summaryrefslogtreecommitdiff
path: root/jni/ruby/sample
diff options
context:
space:
mode:
authorJari Vetoniemi <jari.vetoniemi@indooratlas.com>2020-03-16 18:49:26 +0900
committerJari Vetoniemi <jari.vetoniemi@indooratlas.com>2020-03-30 00:39:06 +0900
commitfcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch)
tree64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/sample
Fresh start
Diffstat (limited to 'jni/ruby/sample')
-rw-r--r--jni/ruby/sample/README45
-rw-r--r--jni/ruby/sample/benchmark.rb19
-rw-r--r--jni/ruby/sample/biorhythm.rb124
-rw-r--r--jni/ruby/sample/cal.rb166
-rw-r--r--jni/ruby/sample/cbreak.rb36
-rw-r--r--jni/ruby/sample/cgi-session-pstore.rb11
-rw-r--r--jni/ruby/sample/clnt.rb21
-rw-r--r--jni/ruby/sample/coverage.rb62
-rw-r--r--jni/ruby/sample/delegate.rb31
-rw-r--r--jni/ruby/sample/dir.rb12
-rw-r--r--jni/ruby/sample/drb/README.ja.rdoc59
-rw-r--r--jni/ruby/sample/drb/README.rdoc56
-rw-r--r--jni/ruby/sample/drb/acl.rb15
-rw-r--r--jni/ruby/sample/drb/darray.rb12
-rw-r--r--jni/ruby/sample/drb/darrayc.rb47
-rw-r--r--jni/ruby/sample/drb/dbiff.rb51
-rw-r--r--jni/ruby/sample/drb/dcdbiff.rb43
-rw-r--r--jni/ruby/sample/drb/dchatc.rb41
-rw-r--r--jni/ruby/sample/drb/dchats.rb70
-rw-r--r--jni/ruby/sample/drb/dhasen.rb42
-rw-r--r--jni/ruby/sample/drb/dhasenc.rb14
-rw-r--r--jni/ruby/sample/drb/dlogc.rb16
-rw-r--r--jni/ruby/sample/drb/dlogd.rb39
-rw-r--r--jni/ruby/sample/drb/dqin.rb13
-rw-r--r--jni/ruby/sample/drb/dqlib.rb14
-rw-r--r--jni/ruby/sample/drb/dqout.rb14
-rw-r--r--jni/ruby/sample/drb/dqueue.rb12
-rw-r--r--jni/ruby/sample/drb/drbc.rb45
-rw-r--r--jni/ruby/sample/drb/drbch.rb48
-rw-r--r--jni/ruby/sample/drb/drbm.rb60
-rw-r--r--jni/ruby/sample/drb/drbmc.rb22
-rw-r--r--jni/ruby/sample/drb/drbs-acl.rb51
-rw-r--r--jni/ruby/sample/drb/drbs.rb64
-rw-r--r--jni/ruby/sample/drb/drbssl_c.rb19
-rw-r--r--jni/ruby/sample/drb/drbssl_s.rb31
-rw-r--r--jni/ruby/sample/drb/extserv_test.rb80
-rw-r--r--jni/ruby/sample/drb/gw_ct.rb29
-rw-r--r--jni/ruby/sample/drb/gw_cu.rb28
-rw-r--r--jni/ruby/sample/drb/gw_s.rb10
-rw-r--r--jni/ruby/sample/drb/holderc.rb22
-rw-r--r--jni/ruby/sample/drb/holders.rb63
-rw-r--r--jni/ruby/sample/drb/http0.rb77
-rw-r--r--jni/ruby/sample/drb/http0serv.rb119
-rw-r--r--jni/ruby/sample/drb/name.rb117
-rw-r--r--jni/ruby/sample/drb/namec.rb36
-rw-r--r--jni/ruby/sample/drb/old_tuplespace.rb214
-rw-r--r--jni/ruby/sample/drb/rinda_ts.rb7
-rw-r--r--jni/ruby/sample/drb/rindac.rb17
-rw-r--r--jni/ruby/sample/drb/rindas.rb18
-rw-r--r--jni/ruby/sample/drb/ring_echo.rb30
-rw-r--r--jni/ruby/sample/drb/ring_inspect.rb30
-rw-r--r--jni/ruby/sample/drb/ring_place.rb25
-rw-r--r--jni/ruby/sample/drb/simpletuple.rb91
-rw-r--r--jni/ruby/sample/drb/speedc.rb21
-rw-r--r--jni/ruby/sample/drb/speeds.rb31
-rw-r--r--jni/ruby/sample/dualstack-fetch.rb48
-rw-r--r--jni/ruby/sample/dualstack-httpd.rb55
-rw-r--r--jni/ruby/sample/eval.rb41
-rw-r--r--jni/ruby/sample/export.rb40
-rw-r--r--jni/ruby/sample/exyacc.rb20
-rw-r--r--jni/ruby/sample/fact.rb9
-rw-r--r--jni/ruby/sample/fib.awk5
-rw-r--r--jni/ruby/sample/fib.pl11
-rw-r--r--jni/ruby/sample/fib.py10
-rw-r--r--jni/ruby/sample/fib.rb10
-rw-r--r--jni/ruby/sample/fib.scm8
-rw-r--r--jni/ruby/sample/freq.rb12
-rw-r--r--jni/ruby/sample/from.rb113
-rw-r--r--jni/ruby/sample/fullpath.rb23
-rw-r--r--jni/ruby/sample/less.rb17
-rw-r--r--jni/ruby/sample/list.rb81
-rw-r--r--jni/ruby/sample/list2.rb16
-rw-r--r--jni/ruby/sample/list3.rb18
-rw-r--r--jni/ruby/sample/logger/app.rb46
-rw-r--r--jni/ruby/sample/logger/log.rb27
-rw-r--r--jni/ruby/sample/logger/shifting.rb26
-rwxr-xr-xjni/ruby/sample/mine.rb176
-rw-r--r--jni/ruby/sample/mkproto.rb27
-rw-r--r--jni/ruby/sample/mpart.rb44
-rw-r--r--jni/ruby/sample/net-imap.rb167
-rw-r--r--jni/ruby/sample/observ.rb32
-rw-r--r--jni/ruby/sample/occur.pl9
-rw-r--r--jni/ruby/sample/occur.rb12
-rw-r--r--jni/ruby/sample/occur2.rb13
-rw-r--r--jni/ruby/sample/open3.rb12
-rw-r--r--jni/ruby/sample/openssl/c_rehash.rb174
-rw-r--r--jni/ruby/sample/openssl/cert2text.rb23
-rw-r--r--jni/ruby/sample/openssl/certstore.rb161
-rw-r--r--jni/ruby/sample/openssl/cipher.rb54
-rw-r--r--jni/ruby/sample/openssl/crlstore.rb122
-rw-r--r--jni/ruby/sample/openssl/echo_cli.rb44
-rw-r--r--jni/ruby/sample/openssl/echo_svr.rb65
-rw-r--r--jni/ruby/sample/openssl/gen_csr.rb51
-rw-r--r--jni/ruby/sample/openssl/smime_read.rb23
-rw-r--r--jni/ruby/sample/openssl/smime_write.rb23
-rw-r--r--jni/ruby/sample/openssl/wget.rb34
-rwxr-xr-xjni/ruby/sample/optparse/opttest.rb125
-rwxr-xr-xjni/ruby/sample/optparse/subcommand.rb19
-rw-r--r--jni/ruby/sample/philos.rb54
-rw-r--r--jni/ruby/sample/pi.rb18
-rw-r--r--jni/ruby/sample/pstore.rb19
-rw-r--r--jni/ruby/sample/pty/expect_sample.rb48
-rw-r--r--jni/ruby/sample/pty/script.rb37
-rw-r--r--jni/ruby/sample/pty/shl.rb92
-rw-r--r--jni/ruby/sample/rcs.awk33
-rw-r--r--jni/ruby/sample/rcs.dat17
-rw-r--r--jni/ruby/sample/rcs.rb39
-rw-r--r--jni/ruby/sample/rdoc/markup/rdoc2latex.rb15
-rw-r--r--jni/ruby/sample/rdoc/markup/sample.rb40
-rw-r--r--jni/ruby/sample/rinda-ring.rb22
-rw-r--r--jni/ruby/sample/ripper/ruby2html.rb112
-rw-r--r--jni/ruby/sample/ripper/strip-comment.rb19
-rwxr-xr-xjni/ruby/sample/rss/blend.rb79
-rwxr-xr-xjni/ruby/sample/rss/convert.rb69
-rwxr-xr-xjni/ruby/sample/rss/list_description.rb91
-rwxr-xr-xjni/ruby/sample/rss/re_read.rb64
-rwxr-xr-xjni/ruby/sample/rss/rss_recent.rb85
-rw-r--r--jni/ruby/sample/sieve.rb14
-rw-r--r--jni/ruby/sample/simple-bench.rb140
-rw-r--r--jni/ruby/sample/svr.rb34
-rw-r--r--jni/ruby/sample/tempfile.rb8
-rwxr-xr-xjni/ruby/sample/test.rb2363
-rw-r--r--jni/ruby/sample/testunit/adder.rb13
-rw-r--r--jni/ruby/sample/testunit/subtracter.rb12
-rw-r--r--jni/ruby/sample/testunit/tc_adder.rb18
-rw-r--r--jni/ruby/sample/testunit/tc_subtracter.rb18
-rw-r--r--jni/ruby/sample/testunit/ts_examples.rb7
-rw-r--r--jni/ruby/sample/time.rb12
-rw-r--r--jni/ruby/sample/timeout.rb42
-rw-r--r--jni/ruby/sample/trick2013/README.md13
-rw-r--r--jni/ruby/sample/trick2013/kinaba/authors.markdown3
-rw-r--r--jni/ruby/sample/trick2013/kinaba/entry.rb1
-rw-r--r--jni/ruby/sample/trick2013/kinaba/remarks.markdown37
-rw-r--r--jni/ruby/sample/trick2013/mame/authors.markdown3
-rw-r--r--jni/ruby/sample/trick2013/mame/entry.rb97
-rw-r--r--jni/ruby/sample/trick2013/mame/music-box.mp4bin0 -> 580724 bytes
-rw-r--r--jni/ruby/sample/trick2013/mame/remarks.markdown47
-rw-r--r--jni/ruby/sample/trick2013/shinh/authors.markdown2
-rw-r--r--jni/ruby/sample/trick2013/shinh/entry.rb10
-rw-r--r--jni/ruby/sample/trick2013/shinh/remarks.markdown4
-rw-r--r--jni/ruby/sample/trick2013/yhara/authors.markdown3
-rw-r--r--jni/ruby/sample/trick2013/yhara/entry.rb28
-rw-r--r--jni/ruby/sample/trick2013/yhara/remarks.en.markdown23
-rw-r--r--jni/ruby/sample/trick2013/yhara/remarks.markdown24
-rw-r--r--jni/ruby/sample/trojan.rb15
-rw-r--r--jni/ruby/sample/tsvr.rb20
-rw-r--r--jni/ruby/sample/uumerge.rb43
-rw-r--r--jni/ruby/sample/weakref.rb9
-rw-r--r--jni/ruby/sample/webrick/demo-app.rb66
-rw-r--r--jni/ruby/sample/webrick/demo-multipart.cgi12
-rw-r--r--jni/ruby/sample/webrick/demo-servlet.rb6
-rw-r--r--jni/ruby/sample/webrick/demo-urlencoded.cgi12
-rw-r--r--jni/ruby/sample/webrick/hello.cgi11
-rw-r--r--jni/ruby/sample/webrick/hello.rb8
-rw-r--r--jni/ruby/sample/webrick/httpd.rb23
-rw-r--r--jni/ruby/sample/webrick/httpproxy.rb25
-rw-r--r--jni/ruby/sample/webrick/httpsd.rb33
157 files changed, 8748 insertions, 0 deletions
diff --git a/jni/ruby/sample/README b/jni/ruby/sample/README
new file mode 100644
index 0000000..796aba1
--- /dev/null
+++ b/jni/ruby/sample/README
@@ -0,0 +1,45 @@
+README this file
+biorhythm.rb biorhythm calculator
+cal.rb cal(1) clone
+cbreak.rb no echo done by ioctl
+clnt.rb socket client
+coverage.rb simple test code coverage tool
+dir.rb directory access
+dualstack-fetch.rb IPv6 demo
+dualstack-httpd.rb IPv6 demo
+eval.rb simple evaluator
+export.rb method access example
+exyacc.rb extrace BNF from yacc file
+fact.rb factorial calculator
+fib.awk Fibonacci number (AWK)
+fib.pl Fibonacci number (Perl)
+fib.py Fibonacci number (Python)
+fib.rb Fibonacci number (Ruby)
+fib.scm Fibonacci number (Scheme)
+freq.rb count word occurrence
+from.rb scan mail spool
+fullpath.rb convert ls -lR to fullpath format
+less.rb front end for less
+list.rb stupid object sample
+list2.rb stupid object sample
+list3.rb stupid object sample
+mine.rb simple mine sweeper
+mkproto.rb extract prototype from C
+mpart.rb split file int multi part
+observ.rb observer design pattern sample
+occur.pl count word occurrence (Perl)
+occur.rb count word occurrence (Ruby)
+occur2.rb count word occurrence - another style
+philos.rb famous dining philosophers
+pi.rb calculate PI
+rcs.awk random character stereogram (AWK)
+rcs.rb random character stereogram (Ruby)
+rcs.dat data for random character stereogram
+sieve.rb sieve of Eratosthenes
+svr.rb socket server
+test.rb test suite used by `make test'
+time.rb /usr/bin/time clone
+timeout.rb timeout test
+trojan.rb simple tool to find file that may be trojan horse.
+tsvr.rb socket server using thread
+uumerge.rb merge files and uudecode them
diff --git a/jni/ruby/sample/benchmark.rb b/jni/ruby/sample/benchmark.rb
new file mode 100644
index 0000000..de5d66f
--- /dev/null
+++ b/jni/ruby/sample/benchmark.rb
@@ -0,0 +1,19 @@
+require 'benchmark'
+
+include Benchmark
+
+n = ARGV[0].to_i.nonzero? || 50000
+puts %Q([#{n} times iterations of `a = "1"'])
+benchmark(CAPTION, 7, FORMAT) do |x|
+ x.report("for:") {for _ in 1..n; _ = "1"; end} # Benchmark.measure
+ x.report("times:") {n.times do ; _ = "1"; end}
+ x.report("upto:") {1.upto(n) do ; _ = "1"; end}
+end
+
+benchmark do
+ [
+ measure{for _ in 1..n; _ = "1"; end}, # Benchmark.measure
+ measure{n.times do ; _ = "1"; end},
+ measure{1.upto(n) do ; _ = "1"; end}
+ ]
+end
diff --git a/jni/ruby/sample/biorhythm.rb b/jni/ruby/sample/biorhythm.rb
new file mode 100644
index 0000000..8d5bf63
--- /dev/null
+++ b/jni/ruby/sample/biorhythm.rb
@@ -0,0 +1,124 @@
+#!/usr/local/bin/ruby
+#
+# biorhythm.rb -
+# $Release Version: $
+# $Revision: 31573 $
+# by Yasuo OHBA(STAFS Development Room)
+#
+# --
+#
+#
+#
+
+# probably based on:
+#
+# Newsgroups: comp.sources.misc,de.comp.sources.os9
+# From: fkk@stasys.sta.sub.org (Frank Kaefer)
+# Subject: v41i126: br - Biorhythm v3.0, Part01/01
+# Message-ID: <1994Feb1.070616.15982@sparky.sterling.com>
+# Sender: kent@sparky.sterling.com (Kent Landfield)
+# Organization: Sterling Software
+# Date: Tue, 1 Feb 1994 07:06:16 GMT
+#
+# Posting-number: Volume 41, Issue 126
+# Archive-name: br/part01
+# Environment: basic, dos, os9
+
+include Math
+require "date.rb"
+require "optparse"
+require "optparse/date"
+
+def print_header(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 get_position(z)
+ pi = Math::PI
+ z = Integer(z)
+ 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
+
+def prompt(msg)
+ $stderr.print msg
+ return gets.chomp
+end
+
+#
+# main program
+#
+options = {
+ :graph => true,
+ :date => Date.today,
+ :days => 9,
+}
+ARGV.options do |opts|
+ opts.on("-b", "--birthday=DATE", Date, "specify your birthday"){|v|
+ options[:birthday] = v
+ }
+ opts.on("--date=DATE", Date, "specify date to show"){|v|
+ options[:date] = v
+ }
+ opts.on("-g", "--show-graph", TrueClass, "show graph (default)"){|v|
+ options[:graph] = v
+ }
+ opts.on("-v", "--show-values", TrueClass, "show values"){|v|
+ options[:graph] = !v
+ }
+ opts.on("--days=DAYS", Integer, "graph range (only in effect for graph)"){|v|
+ options[:days] = v - 1
+ }
+ opts.on_tail("-h", "--help", "show this message"){puts opts; exit}
+ begin
+ opts.parse!
+ rescue => ex
+ puts "Error: #{ex.message}"
+ puts opts
+ exit
+ end
+end
+
+bd = options[:birthday] || Date.parse(prompt("Your birthday (YYYYMMDD): "))
+dd = options[:date] || Date.today
+ausgabeart = options[:graph] ? "g" : "v"
+display_period = options[:days]
+
+if ausgabeart == "v"
+ print_header(bd.year, bd.month, bd.day, dd - bd, bd.strftime("%a"))
+ print "\n"
+
+ phys, emot, geist = get_position(dd - bd)
+ 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
+ print_header(bd.year, bd.month, bd.day, dd - bd, bd.strftime("%a"))
+ print " P=physical, E=emotional, M=mental\n"
+ print " -------------------------+-------------------------\n"
+ print " Bad Condition | Good Condition\n"
+ print " -------------------------+-------------------------\n"
+
+ (dd - bd).step(dd - bd + display_period) do |z|
+ phys, emot, geist = get_position(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/jni/ruby/sample/cal.rb b/jni/ruby/sample/cal.rb
new file mode 100644
index 0000000..97f75bc
--- /dev/null
+++ b/jni/ruby/sample/cal.rb
@@ -0,0 +1,166 @@
+#! /usr/bin/env ruby
+
+# cal.rb: Written by Tadayoshi Funaba 1998-2004,2006,2008
+# $Id: cal.rb,v 2.11 2008-01-06 08:42:17+09 tadf Exp $
+
+require 'date'
+
+class Cal
+
+ START =
+ {
+ 'cn' => Date::GREGORIAN, # China
+ 'de' => 2342032, # Germany (protestant states)
+ 'dk' => 2342032, # Denmark
+ 'es' => 2299161, # Spain
+ 'fi' => 2361390, # Finland
+ 'fr' => 2299227, # France
+ 'gb' => 2361222, # United Kingdom
+ 'gr' => 2423868, # Greece
+ 'hu' => 2301004, # Hungary
+ 'it' => 2299161, # Italy
+ 'jp' => Date::GREGORIAN, # Japan
+ 'no' => 2342032, # Norway
+ 'pl' => 2299161, # Poland
+ 'pt' => 2299161, # Portugal
+ 'ru' => 2421639, # Russia
+ 'se' => 2361390, # Sweden
+ 'us' => 2361222, # United States
+ 'os' => Date::JULIAN, # (old style)
+ 'ns' => Date::GREGORIAN # (new style)
+ }
+
+ DEFAULT_START = 'gb'
+
+ def initialize
+ opt_j; opt_m; opt_t; opt_y; opt_c
+ end
+
+ def opt_j(flag=false) @opt_j = flag end
+ def opt_m(flag=false) @opt_m = flag end
+ def opt_t(flag=false) @opt_t = flag end
+ def opt_y(flag=false) @opt_y = flag end
+
+ def opt_c(arg=DEFAULT_START) @start = START[arg] end
+
+ def set_params
+ @dw = if @opt_j then 3 else 2 end
+ @mw = (@dw + 1) * 7 - 1
+ @mn = if @opt_j then 2 else 3 end
+ @tw = (@mw + 2) * @mn - 2
+ @k = if @opt_m then 1 else 0 end
+ @da = if @opt_j then :yday else :mday end
+ end
+
+ def pict(y, m)
+ d = (1..31).detect{|x| Date.valid_date?(y, m, x, @start)}
+ fi = Date.new(y, m, d, @start)
+ fi -= (fi.jd - @k + 1) % 7
+
+ ve = (fi..fi + 6).collect{|cu|
+ %w(S M Tu W Th F S)[cu.wday]
+ }
+ ve += (fi..fi + 41).collect{|cu|
+ if cu.mon == m then cu.send(@da) end.to_s
+ }
+
+ ve = ve.collect{|e| e.rjust(@dw)}
+
+ gr = group(ve, 7)
+ gr = trans(gr) if @opt_t
+ ta = gr.collect{|xs| xs.join(' ')}
+
+ ca = %w(January February March April May June July
+ August September October November December)[m - 1]
+ ca = ca + ' ' + y.to_s if !@opt_y
+ ca = ca.center(@mw)
+
+ ta.unshift(ca)
+ end
+
+ def group(xs, n)
+ (0..xs.size / n - 1).collect{|i| xs[i * n, n]}
+ end
+
+ def trans(xs)
+ (0..xs[0].size - 1).collect{|i| xs.collect{|x| x[i]}}
+ end
+
+ def stack(xs)
+ if xs.empty? then [] else xs[0] + stack(xs[1..-1]) end
+ end
+
+ def block(xs, n)
+ stack(group(xs, n).collect{|ys| trans(ys).collect{|zs| zs.join(' ')}})
+ end
+
+ def unlines(xs)
+ xs.collect{|x| x + "\n"}.join
+ end
+
+ def monthly(y, m)
+ unlines(pict(y, m))
+ end
+
+ def addmon(y, m, n)
+ y, m = (y * 12 + (m - 1) + n).divmod(12)
+ return y, m + 1
+ end
+
+ def yearly(y)
+ y.to_s.center(@tw) + "\n\n" +
+ unlines(block((0..11).collect{|n| pict(*addmon(y, 1, n))}, @mn)) + "\n"
+ end
+
+ def print(y, m)
+ set_params
+ if @opt_y then yearly(y) else monthly(y, m) end
+ end
+
+end
+
+if __FILE__ == $0
+
+ require 'getoptlong'
+
+ def usage
+ warn 'usage: cal [-c iso3166] [-jmty] [[month] year]'
+ exit 1
+ end
+
+ cal = Cal.new
+
+ begin
+ GetoptLong.new(['-c', GetoptLong::REQUIRED_ARGUMENT],
+ ['-j', GetoptLong::NO_ARGUMENT],
+ ['-m', GetoptLong::NO_ARGUMENT],
+ ['-t', GetoptLong::NO_ARGUMENT],
+ ['-y', GetoptLong::NO_ARGUMENT]).
+ each do |opt, arg|
+ case opt
+ when '-c'; cal.opt_c(arg) || raise
+ when '-j'; cal.opt_j(true)
+ when '-m'; cal.opt_m(true)
+ when '-t'; cal.opt_t(true)
+ when '-y'; cal.opt_y(true)
+ end
+ end
+ rescue
+ usage
+ end
+
+ y, m = ARGV.values_at(1, 0).compact.collect{|x| x.to_i}
+ cal.opt_y(true) if y && !m
+
+ to = Date.today
+ y ||= to.year
+ m ||= to.mon
+
+ usage unless m >= 1 && m <= 12
+ usage unless y >= -4712
+
+ print cal.print(y, m)
+
+end
+
+# See Bird & Wadler's Introduction to functional programming 4.5.
diff --git a/jni/ruby/sample/cbreak.rb b/jni/ruby/sample/cbreak.rb
new file mode 100644
index 0000000..76b534a
--- /dev/null
+++ b/jni/ruby/sample/cbreak.rb
@@ -0,0 +1,36 @@
+# ioctl example works on Sun
+
+CBREAK = 0x00000002
+ECHO = 0x00000008
+TIOCGETP = 0x40067408
+TIOCSETP = 0x80067409
+
+def cbreak ()
+ set_cbreak(true)
+end
+
+def cooked ()
+ set_cbreak(false)
+end
+
+def set_cbreak (on)
+ tty = "\0" * 256
+ STDIN.ioctl(TIOCGETP, tty)
+ ttys = tty.unpack("C4 S")
+ if on
+ ttys[4] |= CBREAK
+ ttys[4] &= ~ECHO
+ else
+ ttys[4] &= ~CBREAK
+ ttys[4] |= ECHO
+ end
+ tty = ttys.pack("C4 S")
+ STDIN.ioctl(TIOCSETP, tty)
+end
+cbreak();
+
+print("this is no-echo line: ");
+readline().print
+cooked();
+print("this is echo line: ");
+readline()
diff --git a/jni/ruby/sample/cgi-session-pstore.rb b/jni/ruby/sample/cgi-session-pstore.rb
new file mode 100644
index 0000000..ec8b498
--- /dev/null
+++ b/jni/ruby/sample/cgi-session-pstore.rb
@@ -0,0 +1,11 @@
+require 'cgi'
+require 'cgi/session/pstore'
+
+STDIN.reopen(IO::NULL)
+cgi = CGI.new
+session = CGI::Session.new(cgi, 'database_manager' => CGI::Session::PStore)
+session['key'] = {'k' => 'v'}
+puts session['key'].class
+fail unless Hash === session['key']
+puts session['key'].inspect
+fail unless session['key'].inspect == '{"k"=>"v"}'
diff --git a/jni/ruby/sample/clnt.rb b/jni/ruby/sample/clnt.rb
new file mode 100644
index 0000000..0f3d17b
--- /dev/null
+++ b/jni/ruby/sample/clnt.rb
@@ -0,0 +1,21 @@
+# socket example - client side
+# usage: ruby clnt.rb [host] port
+
+require "socket"
+
+if ARGV.length >= 2
+ host = ARGV.shift
+else
+ host = "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 line = gets()
+ s.write(line)
+ print(s.readline)
+end
+s.close
diff --git a/jni/ruby/sample/coverage.rb b/jni/ruby/sample/coverage.rb
new file mode 100644
index 0000000..8e8d616
--- /dev/null
+++ b/jni/ruby/sample/coverage.rb
@@ -0,0 +1,62 @@
+require "coverage.so"
+
+Coverage.start
+
+ext = ENV["COVERUBY_EXT"] || ".cov"
+accum = ENV["COVERUBY_ACCUM"]
+accum = !accum || accum == "" || !(%w(f n 0).include?(accum[0]))
+pwd = Dir.pwd
+
+at_exit do
+ exit_exc = $!
+ Dir.chdir(pwd) do
+ Coverage.result.each do |sfile, covs|
+ cfile = sfile + ext
+
+ writable = proc do |f|
+ File.writable?(f) || File.writable?(File.dirname(f))
+ end
+ unless writable[cfile]
+ cfile = cfile.gsub(File::PATH_SEPARATOR, "#")
+ next unless writable[cfile]
+ end
+
+ readlines = proc do |f|
+ File.read(f).force_encoding("ASCII-8BIT").lines.to_a
+ end
+
+ sources = (readlines[sfile] rescue [])
+
+ pcovs = []
+ if accum
+ pcovs = (readlines[cfile] rescue []).map.with_index do |line, idx|
+ if line[/^\s*(?:(#####)|(\d+)|-):\s*\d+:(.*)$/n]
+ cov, line = $1 ? 0 : ($2 ? $2.to_i : nil), $3
+ if !sources[idx] || sources[idx].chomp != line.chomp
+ warn("source file changed, ignoring: `#{ cfile }'")
+ break []
+ end
+ cov
+ else
+ p line
+ warn("coverage file corrupted, ignoring: #{ cfile }")
+ break []
+ end
+ end
+ unless pcovs.empty? || pcovs.size == covs.size
+ warn("coverage file changed, ignoring: `#{ cfile }'")
+ pcovs = []
+ end
+ end
+
+ open(cfile, "w") do |out|
+ covs.zip(sources, pcovs).each_with_index do |(cov, line, pcov), idx|
+ cov += pcov || 0 if cov
+ cov = (cov ? (cov == 0 ? "#####" : cov.to_s) : "-").rjust(9)
+ out.puts("%s:% 5d:%s" % [cov, idx + 1, line])
+ end
+ end
+ end
+ end
+ raise exit_exc if exit_exc
+end
diff --git a/jni/ruby/sample/delegate.rb b/jni/ruby/sample/delegate.rb
new file mode 100644
index 0000000..918dc08
--- /dev/null
+++ b/jni/ruby/sample/delegate.rb
@@ -0,0 +1,31 @@
+require 'delegate'
+
+class ExtArray<DelegateClass(Array)
+ def initialize()
+ super([])
+ end
+end
+
+ary = ExtArray.new
+p ary.class
+ary.push 25
+p ary
+ary.push 42
+ary.each {|x| p x}
+
+foo = Object.new
+def foo.test
+ 25
+end
+def foo.iter
+ yield self
+end
+def foo.error
+ raise 'this is OK'
+end
+foo2 = SimpleDelegator.new(foo)
+p foo2
+foo2.instance_eval{print "foo\n"}
+p foo.test == foo2.test # => true
+p foo2.iter{[55,true]} # => true
+foo2.error # raise error!
diff --git a/jni/ruby/sample/dir.rb b/jni/ruby/sample/dir.rb
new file mode 100644
index 0000000..b627383
--- /dev/null
+++ b/jni/ruby/sample/dir.rb
@@ -0,0 +1,12 @@
+# directory access
+# list all files but .*/*~/*.o
+dirp = Dir.open(".")
+for f in dirp
+ case f
+ when /^\./, /~$/, /\.o/
+ # do not print
+ else
+ print f, "\n"
+ end
+end
+dirp.close
diff --git a/jni/ruby/sample/drb/README.ja.rdoc b/jni/ruby/sample/drb/README.ja.rdoc
new file mode 100644
index 0000000..3ab70f3
--- /dev/null
+++ b/jni/ruby/sample/drb/README.ja.rdoc
@@ -0,0 +1,59 @@
+= サンプルスクリプト
+
+* Arrayをリモートã‹ã‚‰åˆ©ç”¨ã—ã¦ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ã‚’試ã™ã€‚
+ * darray.rb --- server
+ * darrayc.rb --- client
+
+* 簡易ãƒãƒ£ãƒƒãƒˆ
+ * dchats.rb --- server
+ * dchatc.rb --- client
+
+* 分散chasen
+ * dhasen.rb --- server
+ * dhasenc.rb --- client
+
+* 簡易ログサーãƒ
+ * dlogd.rb --- server
+ * dlogc.rb --- client
+
+* Queueサーãƒã€‚
+ クライアントdqin.rbã¯Queueサーãƒã®çŸ¥ã‚‰ãªã„オブジェクト(DQEntry)ã‚’
+ pushã™ã‚‹ãŒDRbUnknownã«ã‚ˆã‚Šã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆdqout.rbãŒpopã§ãる。
+ * dqueue.rb --- server
+ * dqin.rb --- client。DQEntryオブジェクトをpushã™ã‚‹
+ * dqout.rb --- client。DQEntryオブジェクトをpopã™ã‚‹
+ * dqlib.rb --- DQEntryを定義ã—ãŸãƒ©ã‚¤ãƒ–ラリ
+
+* åå‰ã«ã‚ˆã‚‹å‚ç…§
+ IdConvをカスタマイズã—ã¦idã§ãªãåå‰ã§å‚ç…§ã™ã‚‹ä¾‹
+ * name.rb --- server
+ * namec.rb --- client
+
+* extservã®ã‚µãƒ³ãƒ—ル
+ * extserv_test.rb
+
+* TimerIdConvã®ä½¿ç”¨ä¾‹
+ * holders.rb --- server。ruby -d hodlers.rbã¨ã™ã‚‹ã¨TimerIdConvを使用ã™ã‚‹ã€‚
+ * holderc.rb --- client
+
+* rinda.rbã®ä½¿ç”¨ä¾‹
+ * rinda_ts.rb --- TupleSpaceサーãƒã€‚
+ * rindac.rb --- TupleSpaceã®clientã§ã‚¢ãƒ—リケーションã®client
+ * rindas.rb --- TupleSpaceã®clientã§ã‚¢ãƒ—リケーションã®server
+
+* observerã®ä½¿ç”¨ä¾‹
+ cdbiff - http://namazu.org/~satoru/cdbiff/
+ * dbiff.rb --- dcdbiff server
+ * dcdbiff.rb --- dcdbiff client
+
+* drbsslã®ä½¿ç”¨ä¾‹
+ * drbssl_s.rb
+ * drbssl_c.rb
+
+* DRbProtoclã®è¿½åŠ ä¾‹
+ * http0.rb
+ * http0serv.rb
+
+* ringã®ä½¿ç”¨ä¾‹
+ * ring_place.rb
+ * ring_echo.rb
diff --git a/jni/ruby/sample/drb/README.rdoc b/jni/ruby/sample/drb/README.rdoc
new file mode 100644
index 0000000..80ae910
--- /dev/null
+++ b/jni/ruby/sample/drb/README.rdoc
@@ -0,0 +1,56 @@
+= Sample scripts
+
+* array and iteretor
+ * darray.rb --- server
+ * darrayc.rb --- client
+
+* simple chat
+ * dchats.rb --- server
+ * dchatc.rb --- client
+
+* distributed chasen (for Japanese)
+ * dhasen.rb --- server
+ * dhasenc.rb --- client
+
+* simple log server
+ * dlogd.rb --- server
+ * dlogc.rb --- client
+
+* Queue server, and DRbUnknown demo
+ * dqueue.rb --- server
+ * dqin.rb --- client. push DQEntry objects.
+ * dqout.rb --- client. pop DQEntry objects.
+ * dqlib.rb --- define DQEntry
+
+* IdConv customize demo: reference by name
+ * name.rb --- server
+ * namec.rb --- client
+
+* extserv
+ * extserv_test.rb
+
+* IdConv customize demo 2: using TimerIdConv
+ * holders.rb --- server
+ * holderc.rb --- client
+
+* rinda, remote tuplespace
+ * rinda_ts.rb --- TupleSpace server.
+ * rindas.rb --- provide simple service via TupleSpace.
+ * rindac.rb --- service user
+
+* observer
+ cdbiff - http://namazu.org/~satoru/cdbiff/
+ * dbiff.rb --- dcdbiff server
+ * dcdbiff.rb --- dcdbiff client
+
+* drbssl
+ * drbssl_s.rb
+ * drbssl_c.rb
+
+* add DRbProtocl
+ * http0.rb
+ * http0serv.rb
+
+* Rinda::Ring
+ * ring_place.rb
+ * ring_echo.rb
diff --git a/jni/ruby/sample/drb/acl.rb b/jni/ruby/sample/drb/acl.rb
new file mode 100644
index 0000000..d93eb9c
--- /dev/null
+++ b/jni/ruby/sample/drb/acl.rb
@@ -0,0 +1,15 @@
+require 'drb/acl'
+
+list = %w(deny all
+ allow 192.168.1.1
+ allow ::ffff:192.168.1.2
+ allow 192.168.1.3
+)
+
+addr = ["AF_INET", 10, "lc630", "192.168.1.3"]
+
+acl = ACL.new
+p acl.allow_addr?(addr)
+
+acl = ACL.new(list, ACL::DENY_ALLOW)
+p acl.allow_addr?(addr)
diff --git a/jni/ruby/sample/drb/darray.rb b/jni/ruby/sample/drb/darray.rb
new file mode 100644
index 0000000..d2ac395
--- /dev/null
+++ b/jni/ruby/sample/drb/darray.rb
@@ -0,0 +1,12 @@
+=begin
+ distributed Ruby --- Array
+ Copyright (c) 1999-2001 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+
+here = ARGV.shift
+DRb.start_service(here, [1, 2, "III", 4, "five", 6])
+puts DRb.uri
+DRb.thread.join
+
diff --git a/jni/ruby/sample/drb/darrayc.rb b/jni/ruby/sample/drb/darrayc.rb
new file mode 100644
index 0000000..579e115
--- /dev/null
+++ b/jni/ruby/sample/drb/darrayc.rb
@@ -0,0 +1,47 @@
+=begin
+ distributed Ruby --- Array client
+ Copyright (c) 1999-2001 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+
+there = ARGV.shift || raise("usage: #{$0} <server_uri>")
+
+DRb.start_service(nil, nil)
+ro = DRbObject.new(nil, there)
+p ro.size
+
+puts "# collect"
+a = ro.collect { |x|
+ x + x
+}
+p a
+
+puts "# find"
+p ro.find { |x| x.kind_of? String }
+
+puts "# each, break"
+ro.each do |x|
+ next if x == "five"
+ puts x
+end
+
+puts "# each, break"
+ro.each do |x|
+ break if x == "five"
+ puts x
+end
+
+puts "# each, next"
+ro.each do |x|
+ next if x == "five"
+ puts x
+end
+
+puts "# each, redo"
+count = 0
+ro.each do |x|
+ count += 1
+ puts count
+ redo if count == 3
+end
diff --git a/jni/ruby/sample/drb/dbiff.rb b/jni/ruby/sample/drb/dbiff.rb
new file mode 100644
index 0000000..290eb1d
--- /dev/null
+++ b/jni/ruby/sample/drb/dbiff.rb
@@ -0,0 +1,51 @@
+#
+# dbiff.rb - distributed cdbiff (server)
+# * original: cdbiff by Satoru Takabayashi <http://namazu.org/~satoru/cdbiff>
+
+require 'drb/drb'
+require 'drb/eq'
+require 'drb/observer'
+
+class Biff
+ include DRb::DRbObservable
+
+ def initialize(filename, interval)
+ super()
+ @filename = filename
+ @interval = interval
+ end
+
+ def run
+ last = Time.now
+ while true
+ begin
+ sleep(@interval)
+ current = File::mtime(@filename)
+ if current > last
+ changed
+ begin
+ notify_observers(@filename, current)
+ rescue Error
+ end
+ last = current
+ end
+ rescue
+ next
+ end
+ end
+ end
+end
+
+def main
+ filename = "/var/mail/#{ENV['USER']}"
+ interval = 15
+ uri = 'druby://:19903'
+
+ biff = Biff.new(filename, interval)
+
+ DRb.start_service(uri, biff)
+ biff.run
+end
+
+main
+
diff --git a/jni/ruby/sample/drb/dcdbiff.rb b/jni/ruby/sample/drb/dcdbiff.rb
new file mode 100644
index 0000000..6a24680
--- /dev/null
+++ b/jni/ruby/sample/drb/dcdbiff.rb
@@ -0,0 +1,43 @@
+#
+# dcdbiff.rb - distributed cdbiff (client)
+# * original: cdbiff by Satoru Takabayashi <http://namazu.org/~satoru/cdbiff>
+
+require 'drb/drb'
+require 'drb/eq'
+
+class Notify
+ include DRbUndumped
+
+ def initialize(biff, command)
+ @biff = biff
+ @command = command
+
+ @biff.add_observer(self)
+ end
+
+ def update(filename, time)
+ p [filename, time] if $DEBUG
+ system(@command)
+ end
+
+ def done
+ begin
+ @biff.delete_observer(self)
+ rescue
+ end
+ end
+end
+
+def main
+ command = 'eject'
+ uri = 'druby://localhost:19903'
+
+ DRb.start_service
+ biff = DRbObject.new(nil, uri)
+ notify = Notify.new(biff, command)
+
+ trap("INT"){ notify.done }
+ DRb.thread.join
+end
+
+main
diff --git a/jni/ruby/sample/drb/dchatc.rb b/jni/ruby/sample/drb/dchatc.rb
new file mode 100644
index 0000000..2b8ddbf
--- /dev/null
+++ b/jni/ruby/sample/drb/dchatc.rb
@@ -0,0 +1,41 @@
+=begin
+ distributed Ruby --- chat client
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+
+class ChatClient
+ include DRbUndumped
+
+ def initialize(name)
+ @name = name
+ @key = nil
+ end
+ attr_reader(:name)
+ attr_accessor(:key)
+
+ def message(there, str)
+ raise 'invalid key' unless @key == there
+ puts str
+ end
+end
+
+if __FILE__ == $0
+ begin
+ there = ARGV.shift
+ name = ARGV.shift
+ raise "usage" unless (there and name)
+ rescue
+ $stderr.puts("usage: #{$0} <server_uri> <your_name>")
+ exit 1
+ end
+ DRb.start_service
+ ro = DRbObject.new(nil, there)
+
+ chat = ChatClient.new(name)
+ entry = ro.add_member(chat)
+ while gets
+ entry.say($_)
+ end
+end
diff --git a/jni/ruby/sample/drb/dchats.rb b/jni/ruby/sample/drb/dchats.rb
new file mode 100644
index 0000000..c07f748
--- /dev/null
+++ b/jni/ruby/sample/drb/dchats.rb
@@ -0,0 +1,70 @@
+=begin
+ distributed Ruby --- chat server
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+require 'thread'
+require 'drb/drb'
+
+class ChatEntry
+ include DRbUndumped
+
+ def initialize(server, there)
+ @server = server
+ @there = there
+ @name = there.name
+ @key = there.key = Time.now
+ end
+ attr :name, true
+ attr :there
+
+ def say(str)
+ @server.distribute(@there, str)
+ end
+
+ def listen(str)
+ @there.message(@key, str)
+ end
+end
+
+
+class ChatServer
+ def initialize
+ @mutex = Mutex.new
+ @members = {}
+ end
+
+ def add_member(there)
+ client = ChatEntry.new(self, there)
+ @mutex.synchronize do
+ @members[there] = client
+ end
+ client
+ end
+
+ def distribute(there, str)
+ name = @members[there].name
+ msg = "<#{name}> #{str}"
+ msg2 = ">#{name}< #{str}"
+ @mutex.synchronize do
+ for m in @members.keys
+ begin
+ if m == there
+ @members[m].listen(msg2)
+ else
+ @members[m].listen(msg)
+ end
+ rescue
+ p $!
+ @members.delete(m)
+ end
+ end
+ end
+ end
+end
+
+if __FILE__ == $0
+ here = ARGV.shift
+ DRb.start_service(here, ChatServer.new)
+ puts DRb.uri
+ DRb.thread.join
+end
diff --git a/jni/ruby/sample/drb/dhasen.rb b/jni/ruby/sample/drb/dhasen.rb
new file mode 100644
index 0000000..651b9c6
--- /dev/null
+++ b/jni/ruby/sample/drb/dhasen.rb
@@ -0,0 +1,42 @@
+=begin
+ distributed Ruby --- dRuby Sample Server --- chasen server
+ Copyright (c) 1999-2001 Masatoshi SEKI
+=end
+
+=begin
+ How to play.
+
+ Terminal 1
+ | % ruby dhasen.rb
+ | druby://yourhost:7640
+
+ Terminal 2
+ | % ruby dhasenc.rb druby://yourhost:7640
+
+=end
+
+require 'drb/drb'
+require 'chasen'
+require 'thread'
+
+class Dhasen
+ include DRbUndumped
+
+ def initialize
+ @mutex = Mutex.new
+ end
+
+ def sparse(str, *arg)
+ @mutex.synchronize do
+ Chasen.getopt(*arg)
+ Chasen.sparse(str)
+ end
+ end
+end
+
+if __FILE__ == $0
+ DRb.start_service(nil, Dhasen.new)
+ puts DRb.uri
+ DRb.thread.join
+end
+
diff --git a/jni/ruby/sample/drb/dhasenc.rb b/jni/ruby/sample/drb/dhasenc.rb
new file mode 100644
index 0000000..dddac98
--- /dev/null
+++ b/jni/ruby/sample/drb/dhasenc.rb
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+=begin
+ distributed Ruby --- dRuby Sample Client -- chasen client
+ Copyright (c) 1999-2001 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+
+there = ARGV.shift || raise("usage: #{$0} <server_uri>")
+DRb.start_service
+dhasen = DRbObject.new(nil, there)
+
+print dhasen.sparse("本日ã¯ã€æ™´å¤©ãªã‚Šã€‚", "-F", '(%BB %m %M)\n', "-j")
+print dhasen.sparse("本日ã¯ã€æ™´å¤©ãªã‚Šã€‚", "-F", '(%m %M)\n')
diff --git a/jni/ruby/sample/drb/dlogc.rb b/jni/ruby/sample/drb/dlogc.rb
new file mode 100644
index 0000000..3939a71
--- /dev/null
+++ b/jni/ruby/sample/drb/dlogc.rb
@@ -0,0 +1,16 @@
+=begin
+ distributed Ruby --- Log test
+ Copyright (c) 1999-2001 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+
+there = ARGV.shift || raise("usage: #{$0} <server_uri>")
+
+DRb.start_service
+ro = DRbObject.new(nil, there)
+ro.log(123)
+ro.log("hello")
+sleep 2
+ro.log("wakeup")
+
diff --git a/jni/ruby/sample/drb/dlogd.rb b/jni/ruby/sample/drb/dlogd.rb
new file mode 100644
index 0000000..42f302e
--- /dev/null
+++ b/jni/ruby/sample/drb/dlogd.rb
@@ -0,0 +1,39 @@
+=begin
+ distributed Ruby --- Log server
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+require 'thread'
+
+class Logger
+ def initialize(fname)
+ @fname = fname.to_s
+ @fp = File.open(@fname, "a+")
+ @queue = Queue.new
+ @th = Thread.new { self.flush }
+ end
+
+ def log(str)
+ @queue.push("#{Time.now}\t" + str.to_s)
+ end
+
+ def flush
+ begin
+ while(1)
+ @fp.puts(@queue.pop)
+ @fp.flush
+ end
+ ensure
+ @fp.close
+ end
+ end
+end
+
+if __FILE__ == $0
+ here = ARGV.shift
+ DRb.start_service(here, Logger.new('/usr/tmp/dlogd.log'))
+ puts DRb.uri
+ DRb.thread.join
+end
+
diff --git a/jni/ruby/sample/drb/dqin.rb b/jni/ruby/sample/drb/dqin.rb
new file mode 100644
index 0000000..4751335
--- /dev/null
+++ b/jni/ruby/sample/drb/dqin.rb
@@ -0,0 +1,13 @@
+=begin
+ distributed Ruby --- store
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+require 'dqlib'
+
+there = ARGV.shift || raise("usage: #{$0} <server_uri>")
+
+DRb.start_service
+queue = DRbObject.new(nil, there)
+queue.push(DQEntry.new(DRb.uri))
diff --git a/jni/ruby/sample/drb/dqlib.rb b/jni/ruby/sample/drb/dqlib.rb
new file mode 100644
index 0000000..75f2e61
--- /dev/null
+++ b/jni/ruby/sample/drb/dqlib.rb
@@ -0,0 +1,14 @@
+class DQEntry
+ def initialize(name)
+ @name = name
+ end
+
+ def greeting
+ "Hello, This is #{@name}."
+ end
+ alias to_s greeting
+end
+
+if __FILE__ == $0
+ puts DQEntry.new('DQEntry')
+end
diff --git a/jni/ruby/sample/drb/dqout.rb b/jni/ruby/sample/drb/dqout.rb
new file mode 100644
index 0000000..f2b0b4a
--- /dev/null
+++ b/jni/ruby/sample/drb/dqout.rb
@@ -0,0 +1,14 @@
+=begin
+ distributed Ruby --- fetch
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+require 'dqlib'
+
+there = ARGV.shift || raise("usage: #{$0} <server_uri>")
+
+DRb.start_service
+queue = DRbObject.new(nil, there)
+entry = queue.pop
+puts entry.greeting
diff --git a/jni/ruby/sample/drb/dqueue.rb b/jni/ruby/sample/drb/dqueue.rb
new file mode 100644
index 0000000..1c8878c
--- /dev/null
+++ b/jni/ruby/sample/drb/dqueue.rb
@@ -0,0 +1,12 @@
+=begin
+ distributed Ruby --- Queue
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+
+require 'thread'
+require 'drb/drb'
+
+DRb.start_service(nil, Queue.new)
+puts DRb.uri
+DRb.thread.join
+
diff --git a/jni/ruby/sample/drb/drbc.rb b/jni/ruby/sample/drb/drbc.rb
new file mode 100644
index 0000000..50a86c3
--- /dev/null
+++ b/jni/ruby/sample/drb/drbc.rb
@@ -0,0 +1,45 @@
+=begin
+ distributed Ruby --- dRuby Sample Client
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+
+class DRbEx2
+ include DRbUndumped
+
+ def initialize(n)
+ @n = n
+ end
+
+ def to_i
+ @n.to_i
+ end
+end
+
+if __FILE__ == $0
+ there = ARGV.shift
+ unless there
+ $stderr.puts("usage: #{$0} <server_uri>")
+ exit 1
+ end
+
+ DRb.start_service()
+ ro = DRbObject.new_with_uri(there)
+
+ puts ro
+ p ro.to_a
+ puts ro.hello
+ p ro.hello
+ puts ro.sample(DRbEx2.new(1), 2, 3)
+ puts ro.sample(1, ro.sample(DRbEx2.new(1), 2, 3), DRbEx2.new(3))
+
+ begin
+ ro.err
+ rescue DRb::DRbUnknownError
+ p $!
+ p $!.unknown
+ rescue RuntimeError
+ p $!
+ end
+end
diff --git a/jni/ruby/sample/drb/drbch.rb b/jni/ruby/sample/drb/drbch.rb
new file mode 100644
index 0000000..07fdcd5
--- /dev/null
+++ b/jni/ruby/sample/drb/drbch.rb
@@ -0,0 +1,48 @@
+=begin
+ distributed Ruby --- dRuby Sample Client
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+require 'drb/http'
+
+class DRbEx2
+ include DRbUndumped
+
+ def initialize(n)
+ @n = n
+ end
+
+ def to_i
+ @n.to_i
+ end
+end
+
+if __FILE__ == $0
+ there = ARGV.shift
+ unless there
+ $stderr.puts("usage: #{$0} <server_uri>")
+ exit 1
+ end
+
+ DRb::DRbConn.proxy_map['x68k'] = 'http://x68k/~mas/http_cgi.rb'
+
+ DRb.start_service()
+ ro = DRbObject.new(nil, there)
+
+ puts ro
+ p ro.to_a
+ puts ro.hello
+ p ro.hello
+ puts ro.sample(DRbEx2.new(1), 2, 3)
+ puts ro.sample(1, ro.sample(DRbEx2.new(1), 2, 3), DRbEx2.new(3))
+
+ begin
+ ro.err
+ rescue DRb::DRbUnknownError
+ p $!
+ p $!.unknown
+ rescue RuntimeError
+ p $!
+ end
+end
diff --git a/jni/ruby/sample/drb/drbm.rb b/jni/ruby/sample/drb/drbm.rb
new file mode 100644
index 0000000..3390608
--- /dev/null
+++ b/jni/ruby/sample/drb/drbm.rb
@@ -0,0 +1,60 @@
+=begin
+ multiple DRbServer
+ Copyright (c) 1999-2002 Masatoshi SEKI
+=end
+
+=begin
+ How to play.
+
+ Terminal 1
+ | % ruby drbm.rb
+ | druby://yourhost:7640 druby://yourhost:7641
+
+ Terminal 2
+ | % ruby drbmc.rb druby://yourhost:7640 druby://yourhost:7641
+ | [#<DRb::DRbObject .... @uri="druby://yourhost:7640">, "FOO"]
+ | [#<DRb::DRbObject .... @uri="druby://yourhost:7641">, "FOO"]
+
+=end
+
+require 'drb/drb'
+
+class Hoge
+ include DRbUndumped
+ def initialize(s)
+ @str = s
+ end
+
+ def to_s
+ @str
+ end
+end
+
+class Foo
+ def initialize(s='FOO')
+ @hoge = Hoge.new(s)
+ end
+
+ def hello
+ @hoge
+ end
+end
+
+class Bar < Foo
+ def initialize(foo)
+ @hoge = foo.hello
+ end
+end
+
+
+if __FILE__ == $0
+ foo = Foo.new
+ s1 = DRb::DRbServer.new('druby://:7640', foo)
+ s2 = DRb::DRbServer.new('druby://:7641', Bar.new(foo))
+
+ puts "#{s1.uri} #{s2.uri}"
+
+ s1.thread.join
+ s2.thread.join
+end
+
diff --git a/jni/ruby/sample/drb/drbmc.rb b/jni/ruby/sample/drb/drbmc.rb
new file mode 100644
index 0000000..fd19140
--- /dev/null
+++ b/jni/ruby/sample/drb/drbmc.rb
@@ -0,0 +1,22 @@
+=begin
+ multiple DRbServer client
+ Copyright (c) 1999-2002 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+
+if __FILE__ == $0
+ s1 = ARGV.shift
+ s2 = ARGV.shift
+ unless s1 && s2
+ $stderr.puts("usage: #{$0} <server_uri1> <server_uri2>")
+ exit 1
+ end
+
+ DRb.start_service()
+ r1 = DRbObject.new(nil, s1)
+ r2 = DRbObject.new(nil, s2)
+
+ p [r1.hello, r1.hello.to_s]
+ p [r2.hello, r2.hello.to_s]
+end
diff --git a/jni/ruby/sample/drb/drbs-acl.rb b/jni/ruby/sample/drb/drbs-acl.rb
new file mode 100644
index 0000000..71c4f7b
--- /dev/null
+++ b/jni/ruby/sample/drb/drbs-acl.rb
@@ -0,0 +1,51 @@
+=begin
+ distributed Ruby --- dRuby Sample Server
+ Copyright (c) 1999-2000 Masatoshi SEKI
+=end
+
+=begin
+ How to play.
+
+ Terminal 1
+ | % ruby drbs.rb
+ | druby://yourhost:7640
+
+ Terminal 2
+ | % ruby drbc.rb druby://yourhost:7640
+ | "hello"
+ | 6
+ | 10
+
+=end
+
+require 'drb/drb'
+require 'acl'
+
+class DRbEx
+ def initialize
+ @hello = 'hello'
+ end
+
+ def hello
+ info = Thread.current['DRb']
+ p info['socket'].peeraddr if info
+ @hello
+ end
+
+ def sample(a, b, c)
+ a.to_i + b.to_i + c.to_i
+ end
+end
+
+if __FILE__ == $0
+ acl = ACL.new(%w(deny all
+ allow 192.168.1.*
+ allow localhost))
+
+ DRb.install_acl(acl)
+
+ DRb.start_service(nil, DRbEx.new)
+ puts DRb.uri
+ DRb.thread.join
+end
+
diff --git a/jni/ruby/sample/drb/drbs.rb b/jni/ruby/sample/drb/drbs.rb
new file mode 100644
index 0000000..5a913d9
--- /dev/null
+++ b/jni/ruby/sample/drb/drbs.rb
@@ -0,0 +1,64 @@
+=begin
+ distributed Ruby --- dRuby Sample Server
+ Copyright (c) 1999-2000,2002 Masatoshi SEKI
+=end
+
+=begin
+ How to play.
+
+ Terminal 1
+ | % ruby drbs.rb
+ | druby://yourhost:7640
+
+ Terminal 2
+ | % ruby drbc.rb druby://yourhost:7640
+ | "hello"
+ | ....
+
+=end
+
+require 'drb/drb'
+
+class DRbEx
+ include DRbUndumped
+
+ def initialize
+ @hello = 'hello'
+ end
+
+ def hello
+ cntxt = Thread.current['DRb']
+ if cntxt
+ p cntxt['server'].uri
+ p cntxt['client'].peeraddr
+ end
+ Foo::Unknown.new
+ end
+
+ def err
+ raise FooError
+ end
+
+ def sample(a, b, c)
+ a.to_i + b.to_i + c.to_i
+ end
+end
+
+class Foo
+ class Unknown
+ end
+end
+
+class FooError < RuntimeError
+end
+
+if __FILE__ == $0
+ DRb.start_service(ARGV.shift || 'druby://:7640', DRbEx.new)
+ puts DRb.uri
+ Thread.new do
+ sleep 10
+ DRb.stop_service
+ end
+ DRb.thread.join
+end
+
diff --git a/jni/ruby/sample/drb/drbssl_c.rb b/jni/ruby/sample/drb/drbssl_c.rb
new file mode 100644
index 0000000..65112f6
--- /dev/null
+++ b/jni/ruby/sample/drb/drbssl_c.rb
@@ -0,0 +1,19 @@
+#!/usr/bin/env ruby
+
+require 'drb'
+require 'drb/ssl'
+
+there = ARGV.shift || "drbssl://localhost:3456"
+
+config = Hash.new
+config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
+config[:SSLVerifyCallback] = lambda{|ok,x509_store|
+ p [ok, x509_store.error_string]
+ true
+}
+
+DRb.start_service(nil,nil,config)
+h = DRbObject.new(nil, there)
+while line = gets
+ p h.hello(line.chomp)
+end
diff --git a/jni/ruby/sample/drb/drbssl_s.rb b/jni/ruby/sample/drb/drbssl_s.rb
new file mode 100644
index 0000000..4d96f59
--- /dev/null
+++ b/jni/ruby/sample/drb/drbssl_s.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+
+require 'drb'
+require 'drb/ssl'
+
+here = ARGV.shift || "drbssl://localhost:3456"
+
+class HelloWorld
+ include DRbUndumped
+
+ def hello(name)
+ "Hello, #{name}."
+ end
+end
+
+config = Hash.new
+config[:verbose] = true
+begin
+ data = open("sample.key"){|io| io.read }
+ config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(data)
+ data = open("sample.crt"){|io| io.read }
+ config[:SSLCertificate] = OpenSSL::X509::Certificate.new(data)
+rescue
+ $stderr.puts "Switching to use self-signed certificate"
+ config[:SSLCertName] =
+ [ ["C","JP"], ["O","Foo.DRuby.Org"], ["CN", "Sample"] ]
+end
+
+DRb.start_service(here, HelloWorld.new, config)
+puts DRb.uri
+DRb.thread.join
diff --git a/jni/ruby/sample/drb/extserv_test.rb b/jni/ruby/sample/drb/extserv_test.rb
new file mode 100644
index 0000000..2c4f485
--- /dev/null
+++ b/jni/ruby/sample/drb/extserv_test.rb
@@ -0,0 +1,80 @@
+=begin
+ dRuby sample
+ Copyright (c) 2000 Masatoshi SEKI
+
+= How to play
+
+* Terminal 1
+
+ % ruby -I. extserv_test.rb server
+ druby://yourhost:12345
+
+* Terminal 2
+
+ % ruby -I. extserv_test.rb druby://yourhost:12345
+ ...
+
+=end
+
+require 'drb/drb'
+
+def ARGV.shift
+ it = super()
+ raise "usage:\nserver: #{$0} server [<uri>]\nclient: #{$0} [quit] <uri>" unless it
+ it
+end
+
+class Foo
+ include DRbUndumped
+
+ def initialize(str)
+ @str = str
+ end
+
+ def hello(it)
+ "#{it}: #{self}"
+ end
+
+ def to_s
+ @str
+ end
+end
+
+cmd = ARGV.shift
+case cmd
+when 'itest1', 'itest2'
+ require 'drb/extserv'
+
+ front = Foo.new(cmd)
+ server = DRb::DRbServer.new(nil, front)
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift, server)
+ server.thread.join
+
+when 'server'
+ require 'drb/extservm'
+
+ DRb::ExtServManager.command['itest1'] = "ruby -I. #{$0} itest1"
+ DRb::ExtServManager.command['itest2'] = "ruby -I. #{$0} itest2"
+
+ s = DRb::ExtServManager.new
+ DRb.start_service(ARGV.shift, s)
+ puts DRb.uri
+ DRb.thread.join
+
+
+else
+ uri = (cmd == 'quit') ? ARGV.shift : cmd
+
+ DRb.start_service
+ s = DRbObject.new(nil, uri)
+ t1 = s.service('itest1').front
+ puts t1
+ t2 = s.service('itest2').front
+ puts t2
+ puts t1.hello(t2)
+ if (cmd == 'quit')
+ s.service('itest1').stop_service
+ s.service('itest2').stop_service
+ end
+end
+
diff --git a/jni/ruby/sample/drb/gw_ct.rb b/jni/ruby/sample/drb/gw_ct.rb
new file mode 100644
index 0000000..0622784
--- /dev/null
+++ b/jni/ruby/sample/drb/gw_ct.rb
@@ -0,0 +1,29 @@
+require 'drb/drb'
+
+class Foo
+ include DRbUndumped
+
+ def foo(n)
+ n + n
+ end
+
+ def bar(n)
+ yield(n) + yield(n)
+ end
+end
+
+DRb.start_service(nil)
+puts DRb.uri
+
+ro = DRbObject.new(nil, ARGV.shift)
+ro[:tcp] = Foo.new
+gets
+
+it = ro[:unix]
+p [it, it.foo(1)]
+gets
+
+p it.bar('2') {|n| n * 3}
+gets
+
+
diff --git a/jni/ruby/sample/drb/gw_cu.rb b/jni/ruby/sample/drb/gw_cu.rb
new file mode 100644
index 0000000..8079cbd
--- /dev/null
+++ b/jni/ruby/sample/drb/gw_cu.rb
@@ -0,0 +1,28 @@
+require 'drb/drb'
+require 'drb/unix'
+
+class Foo
+ include DRbUndumped
+
+ def foo(n)
+ n + n
+ end
+
+ def bar(n)
+ yield(n) + yield(n)
+ end
+end
+
+DRb.start_service('drbunix:', nil)
+puts DRb.uri
+
+ro = DRbObject.new(nil, ARGV.shift)
+ro[:unix] = Foo.new
+gets
+
+it = ro[:tcp]
+p [it, it.foo(1)]
+gets
+
+p it.bar('2') {|n| n * 3}
+gets
diff --git a/jni/ruby/sample/drb/gw_s.rb b/jni/ruby/sample/drb/gw_s.rb
new file mode 100644
index 0000000..c2bea0b
--- /dev/null
+++ b/jni/ruby/sample/drb/gw_s.rb
@@ -0,0 +1,10 @@
+require 'drb/drb'
+require 'drb/unix'
+require 'drb/gw'
+
+DRb.install_id_conv(DRb::GWIdConv.new)
+gw = DRb::GW.new
+s1 = DRb::DRbServer.new(ARGV.shift, gw)
+s2 = DRb::DRbServer.new(ARGV.shift, gw)
+s1.thread.join
+s2.thread.join
diff --git a/jni/ruby/sample/drb/holderc.rb b/jni/ruby/sample/drb/holderc.rb
new file mode 100644
index 0000000..e627916
--- /dev/null
+++ b/jni/ruby/sample/drb/holderc.rb
@@ -0,0 +1,22 @@
+require 'drb/drb'
+
+begin
+ there = ARGV.shift || raise
+rescue
+ $stderr.puts("usage: #{$0} <server_uri>")
+ exit 1
+end
+
+DRb.start_service()
+ro = DRbObject.new(nil, there)
+
+ary = []
+10.times do
+ ary.push(ro.gen)
+end
+
+sleep 5 if $DEBUG
+
+ary.each do |e|
+ p e.sample([1])
+end
diff --git a/jni/ruby/sample/drb/holders.rb b/jni/ruby/sample/drb/holders.rb
new file mode 100644
index 0000000..293426f
--- /dev/null
+++ b/jni/ruby/sample/drb/holders.rb
@@ -0,0 +1,63 @@
+=begin
+= How to play.
+
+== with timeridconv:
+ % ruby -d holders.rb
+ druby://yourhost:1234
+
+ % ruby holderc.rb druby://yourhost:1234
+
+
+== without timeridconv:
+ % ruby holders.rb
+ druby://yourhost:1234
+
+ % ruby holderc.rb druby://yourhost:1234
+=end
+
+
+require 'drb/drb'
+
+class DRbEx3
+ include DRbUndumped
+
+ def initialize(n)
+ @v = n
+ end
+
+ def sample(list)
+ sum = 0
+ list.each do |e|
+ sum += e.to_i
+ end
+ @v * sum
+ end
+end
+
+class DRbEx4
+ include DRbUndumped
+
+ def initialize
+ @curr = 1
+ end
+
+ def gen
+ begin
+ @curr += 1
+ DRbEx3.new(@curr)
+ ensure
+ GC.start
+ end
+ end
+end
+
+if __FILE__ == $0
+ if $DEBUG
+ require 'drb/timeridconv'
+ DRb.install_id_conv(DRb::TimerIdConv.new(2))
+ end
+
+ DRb.start_service(nil, DRbEx4.new)
+ puts DRb.uri
+ DRb.thread.join
+end
diff --git a/jni/ruby/sample/drb/http0.rb b/jni/ruby/sample/drb/http0.rb
new file mode 100644
index 0000000..e40d810
--- /dev/null
+++ b/jni/ruby/sample/drb/http0.rb
@@ -0,0 +1,77 @@
+require 'drb/drb'
+require 'net/http'
+require 'uri'
+
+module DRb
+ module HTTP0
+ class StrStream
+ def initialize(str='')
+ @buf = str
+ end
+ attr_reader :buf
+
+ def read(n)
+ begin
+ return @buf[0,n]
+ ensure
+ @buf[0,n] = ''
+ end
+ end
+
+ def write(s)
+ @buf.concat s
+ end
+ end
+
+ def self.uri_option(uri, config)
+ return uri, nil
+ end
+
+ def self.open(uri, config)
+ unless /^http:/ =~ uri
+ raise(DRbBadScheme, uri) unless uri =~ /^http:/
+ raise(DRbBadURI, 'can\'t parse uri:' + uri)
+ end
+ ClientSide.new(uri, config)
+ end
+
+ class ClientSide
+ def initialize(uri, config)
+ @uri = uri
+ @res = nil
+ @config = config
+ @msg = DRbMessage.new(config)
+ @proxy = ENV['HTTP_PROXY']
+ end
+
+ def close; end
+ def alive?; false; end
+
+ def send_request(ref, msg_id, *arg, &b)
+ stream = StrStream.new
+ @msg.send_request(stream, ref, msg_id, *arg, &b)
+ @reply_stream = StrStream.new
+ post(@uri, stream.buf)
+ end
+
+ def recv_reply
+ @msg.recv_reply(@reply_stream)
+ end
+
+ def post(url, data)
+ it = URI.parse(url)
+ path = [(it.path=='' ? '/' : it.path), it.query].compact.join('?')
+ http = Net::HTTP.new(it.host, it.port)
+ sio = StrStream.new
+ http.post(path, data, {'Content-Type'=>'application/octetstream;'}) do |str|
+ sio.write(str)
+ if @config[:load_limit] < sio.buf.size
+ raise TypeError, 'too large packet'
+ end
+ end
+ @reply_stream = sio
+ end
+ end
+ end
+ DRbProtocol.add_protocol(HTTP0)
+end
diff --git a/jni/ruby/sample/drb/http0serv.rb b/jni/ruby/sample/drb/http0serv.rb
new file mode 100644
index 0000000..9503a17
--- /dev/null
+++ b/jni/ruby/sample/drb/http0serv.rb
@@ -0,0 +1,119 @@
+require 'webrick'
+require 'drb/drb'
+require 'drb/http0'
+require 'thread'
+
+module DRb
+ module HTTP0
+
+ def self.open_server(uri, config)
+ unless /^http:/ =~ uri
+ raise(DRbBadScheme, uri) unless uri =~ /^http:/
+ raise(DRbBadURI, 'can\'t parse uri:' + uri)
+ end
+ Server.new(uri, config)
+ end
+
+ class Callback < WEBrick::HTTPServlet::AbstractServlet
+ def initialize(config, drb)
+ @config = config
+ @drb = drb
+ @queue = Queue.new
+ end
+
+ def do_POST(req, res)
+ @req = req
+ @res = res
+ @drb.push(self)
+ @res.body = @queue.pop
+ @res['content-type'] = 'application/octet-stream;'
+ end
+
+ def req_body
+ @req.body
+ end
+
+ def reply(body)
+ @queue.push(body)
+ end
+
+ def close
+ @queue.push('')
+ end
+ end
+
+ class Server
+ def initialize(uri, config)
+ @uri = uri
+ @config = config
+ @queue = Queue.new
+ setup_webrick(uri)
+ end
+ attr_reader :uri
+
+ def close
+ @server.shutdown if @server
+ @server = nil
+ end
+
+ def push(callback)
+ @queue.push(callback)
+ end
+
+ def accept
+ client = @queue.pop
+ ServerSide.new(client, @config)
+ end
+
+ def setup_webrick(uri)
+ logger = WEBrick::Log::new($stderr, WEBrick::Log::FATAL)
+ u = URI.parse(uri)
+ s = WEBrick::HTTPServer.new(:Port => u.port,
+ :AddressFamily => Socket::AF_INET,
+ :BindAddress => u.host,
+ :Logger => logger,
+ :ServerType => Thread)
+ s.mount(u.path, Callback, self)
+ @server = s
+ s.start
+ end
+ end
+
+ class ServerSide
+ def initialize(callback, config)
+ @callback = callback
+ @config = config
+ @msg = DRbMessage.new(@config)
+ @req_stream = StrStream.new(@callback.req_body)
+ end
+
+ def close
+ @callback.close if @callback
+ @callback = nil
+ end
+
+ def alive?; false; end
+
+ def recv_request
+ begin
+ @msg.recv_request(@req_stream)
+ rescue
+ close
+ raise $!
+ end
+ end
+
+ def send_reply(succ, result)
+ begin
+ return unless @callback
+ stream = StrStream.new
+ @msg.send_reply(stream, succ, result)
+ @callback.reply(stream.buf)
+ rescue
+ close
+ raise $!
+ end
+ end
+ end
+ end
+end
diff --git a/jni/ruby/sample/drb/name.rb b/jni/ruby/sample/drb/name.rb
new file mode 100644
index 0000000..9527d47
--- /dev/null
+++ b/jni/ruby/sample/drb/name.rb
@@ -0,0 +1,117 @@
+=begin
+ distributed Ruby --- NamedObject Sample
+ Copyright (c) 2000-2001 Masatoshi SEKI
+=end
+
+=begin
+How to play.
+
+* start server
+ Terminal 1
+ | % ruby name.rb druby://yourhost:7640
+ | druby://yourhost:7640
+ | [return] to exit
+
+* start client
+ Terminal 2
+ | % ruby namec.rb druby://yourhost:7640
+ | #<DRb::DRbObject:0x40164174 @uri="druby://yourhost:7640", @ref="seq">
+ | #<DRb::DRbObject:0x40163c9c @uri="druby://yourhost:7640", @ref="mutex">
+ | 1
+ | 2
+ | [return] to continue
+
+* restart server
+ Terminal 1
+ type [return]
+ | % ruby name.rb druby://yourhost:7640
+ | druby://yourhost:7640
+ | [return] to exit
+
+* continue client
+ Terminal 2
+ type [return]
+ | 1
+ | 2
+=end
+
+require 'thread.rb'
+require 'drb/drb'
+
+module DRbNamedObject
+ DRbNAMEDICT = {}
+ attr_reader(:drb_name)
+
+ def drb_name=(name)
+ @drb_name = name
+ Thread.exclusive do
+ raise(IndexError, name) if DRbNAMEDICT[name]
+ DRbNAMEDICT[name] = self
+ end
+ end
+end
+
+class DRbNamedIdConv < DRb::DRbIdConv
+ def initialize
+ @dict = DRbNamedObject::DRbNAMEDICT
+ end
+
+ def to_obj(ref)
+ @dict.fetch(ref) do super end
+ end
+
+ def to_id(obj)
+ if obj.kind_of? DRbNamedObject
+ return obj.drb_name
+ else
+ return super
+ end
+ end
+end
+
+class Seq
+ include DRbUndumped
+ include DRbNamedObject
+
+ def initialize(v, name)
+ @counter = v
+ @mutex = Mutex.new
+ self.drb_name = name
+ end
+
+ def next_value
+ @mutex.synchronize do
+ @counter += 1
+ return @counter
+ end
+ end
+end
+
+class Front
+ def initialize
+ seq = Seq.new(0, 'seq')
+ mutex = Mutex.new
+ mutex.extend(DRbUndumped)
+ mutex.extend(DRbNamedObject)
+ mutex.drb_name = 'mutex'
+ @name = {}
+ @name['seq'] = seq
+ @name['mutex'] = mutex
+ end
+
+ def [](k)
+ @name[k]
+ end
+end
+
+if __FILE__ == $0
+ uri = ARGV.shift
+
+ name_conv = DRbNamedIdConv.new
+
+ DRb.install_id_conv(name_conv)
+ DRb.start_service(uri, Front.new)
+ puts DRb.uri
+ DRb.thread.join
+end
+
diff --git a/jni/ruby/sample/drb/namec.rb b/jni/ruby/sample/drb/namec.rb
new file mode 100644
index 0000000..98b9d0e
--- /dev/null
+++ b/jni/ruby/sample/drb/namec.rb
@@ -0,0 +1,36 @@
+=begin
+ distributed Ruby --- NamedObject Sample Client
+ Copyright (c) 2000-2001 Masatoshi SEKI
+=end
+
+require 'drb/drb'
+
+begin
+ there = ARGV.shift || raise
+rescue
+ puts "usage: #{$0} <server_uri>"
+ exit 1
+end
+
+DRb.start_service()
+ro = DRbObject.new(nil, there)
+
+seq = ro["seq"]
+mutex = ro["mutex"]
+
+p seq
+p mutex
+
+mutex.synchronize do
+ p seq.next_value
+ p seq.next_value
+end
+
+puts '[return] to continue'
+gets
+
+mutex.synchronize do
+ p seq.next_value
+ p seq.next_value
+end
+
diff --git a/jni/ruby/sample/drb/old_tuplespace.rb b/jni/ruby/sample/drb/old_tuplespace.rb
new file mode 100644
index 0000000..9c10a34
--- /dev/null
+++ b/jni/ruby/sample/drb/old_tuplespace.rb
@@ -0,0 +1,214 @@
+#!/usr/local/bin/ruby
+# TupleSpace
+# Copyright (c) 1999-2000 Masatoshi SEKI
+# You can redistribute it and/or modify it under the same terms as Ruby.
+
+require 'thread'
+
+class TupleSpace
+ class Template
+ def initialize(list)
+ @list = list
+ @check_idx = []
+ @list.each_with_index do |x, i|
+ @check_idx.push i if x
+ end
+ @size = @list.size
+ end
+
+ attr :size
+ alias length size
+
+ def match(tuple)
+ return nil if tuple.size != self.size
+ @check_idx.each do |i|
+ unless @list[i] === tuple[i]
+ return false
+ end
+ end
+ return true
+ end
+ end
+
+ def initialize
+ @que = {}
+ @waiting = {}
+ @que.taint # enable tainted comunication
+ @waiting.taint
+ self.taint
+ end
+
+ def wakeup_waiting(tuple)
+ sz = tuple.length
+ return nil unless @waiting[sz]
+
+ x = nil
+ i = -1
+ found = false
+ @waiting[sz] = @waiting[sz].find_all { |x|
+ if x[0].match(tuple)
+ begin
+ x[1].wakeup
+ rescue ThreadError
+ end
+ false
+ else
+ true
+ end
+ }
+ end
+
+ def put_waiting(template, thread)
+ sz = template.length
+ @waiting[sz] = [] unless @waiting[sz]
+ @waiting[sz].push([Template.new(template), thread])
+ end
+ private :wakeup_waiting
+ private :put_waiting
+
+ def get_que(template)
+ sz = template.length
+ return nil unless @que[sz]
+
+ template = Template.new(template)
+
+ x = nil
+ i = -1
+ found = false
+ @que[sz].each_with_index do |x, i|
+ if template.match(x)
+ found = true
+ break
+ end
+ end
+ return nil unless found
+
+ @que[sz].delete_at(i)
+
+ return x
+ end
+
+ def put_que(tuple)
+ sz = tuple.length
+ @que[sz] = [] unless @que[sz]
+ @que[sz].push tuple
+ end
+ private :get_que
+ private :put_que
+
+ def out(*tuples)
+ tuples.each do |tuple|
+ Thread.critical = true
+ put_que(tuple)
+ wakeup_waiting(tuple)
+ Thread.critical = false
+ end
+ end
+ alias put out
+ alias write out
+
+ def in(template, non_block=false)
+ begin
+ loop do
+ Thread.critical = true
+ tuple = get_que(template)
+ unless tuple
+ if non_block
+ raise ThreadError, "queue empty"
+ end
+ put_waiting(template, Thread.current)
+ Thread.stop
+ else
+ return tuple
+ end
+ end
+ ensure
+ Thread.critical = false
+ end
+ end
+ alias get in
+ alias take in
+
+ def rd(template, non_block=false)
+ tuple = self.in(template, non_block)
+ out(tuple)
+ tuple
+ end
+ alias read rd
+
+ def mv(dest, template, non_block=false)
+ tuple = self.in(template, non_block)
+ begin
+ dest.out(tuple)
+ rescue
+ self.out(tuple)
+ end
+ end
+ alias move mv
+end
+
+if __FILE__ == $0
+ ts = TupleSpace.new
+ clients = []
+ servers = []
+
+ def server(ts, id)
+ Thread.start {
+ loop do
+ req = ts.in(['req', nil, nil])
+ ac = req[1]
+ num = req[2]
+ sleep id
+ ts.out([ac, id, num, num * num])
+ end
+ }
+ end
+
+ def client(ts, n)
+ Thread.start {
+ ac = Object.new
+ tuples = (1..10).collect { |i|
+ ['req', ac, i * 10 + n]
+ }
+ ts.out(*tuples)
+ ts.out(tuples[0])
+ puts "out: #{n}"
+ 11.times do |i|
+ ans = ts.in([ac, nil, nil, nil])
+ puts "client(#{n}) server(#{ans[1]}) #{ans[2]} #{ans[3]}"
+ end
+ }
+ end
+
+ def watcher(ts)
+ Thread.start {
+ loop do
+ begin
+ sleep 1
+ p ts.rd(['req', nil, nil], true)
+ rescue ThreadError
+ puts "'req' not found."
+ end
+ end
+ }
+ end
+
+ (0..3).each do |n|
+ servers.push(server(ts, n))
+ end
+
+ (1..6).each do |n|
+ clients.push(client(ts, n))
+ end
+
+ (1..3).each do
+ watcher(ts)
+ end
+
+ clients.each do |t|
+ t.join
+ end
+end
+
+
+
diff --git a/jni/ruby/sample/drb/rinda_ts.rb b/jni/ruby/sample/drb/rinda_ts.rb
new file mode 100644
index 0000000..6f2fae5
--- /dev/null
+++ b/jni/ruby/sample/drb/rinda_ts.rb
@@ -0,0 +1,7 @@
+require 'drb/drb'
+require 'rinda/tuplespace'
+
+uri = ARGV.shift
+DRb.start_service(uri, Rinda::TupleSpace.new)
+puts DRb.uri
+DRb.thread.join
diff --git a/jni/ruby/sample/drb/rindac.rb b/jni/ruby/sample/drb/rindac.rb
new file mode 100644
index 0000000..72be09d
--- /dev/null
+++ b/jni/ruby/sample/drb/rindac.rb
@@ -0,0 +1,17 @@
+require 'drb/drb'
+require 'rinda/rinda'
+
+uri = ARGV.shift || raise("usage: #{$0} <server_uri>")
+
+DRb.start_service
+ts = Rinda::TupleSpaceProxy.new(DRbObject.new(nil, uri))
+
+(1..10).each do |n|
+ ts.write(['sum', DRb.uri, n])
+end
+
+(1..10).each do |n|
+ ans = ts.take(['ans', DRb.uri, n, nil])
+ p [ans[2], ans[3]]
+end
+
diff --git a/jni/ruby/sample/drb/rindas.rb b/jni/ruby/sample/drb/rindas.rb
new file mode 100644
index 0000000..9fd9ada
--- /dev/null
+++ b/jni/ruby/sample/drb/rindas.rb
@@ -0,0 +1,18 @@
+require 'drb/drb'
+require 'rinda/rinda'
+
+def do_it(v)
+ puts "do_it(#{v})"
+ v + v
+end
+
+uri = ARGV.shift || raise("usage: #{$0} <server_uri>")
+
+DRb.start_service
+ts = Rinda::TupleSpaceProxy.new(DRbObject.new(nil, uri))
+
+while true
+ r = ts.take(['sum', nil, nil])
+ v = do_it(r[2])
+ ts.write(['ans', r[1], r[2], v])
+end
diff --git a/jni/ruby/sample/drb/ring_echo.rb b/jni/ruby/sample/drb/ring_echo.rb
new file mode 100644
index 0000000..3b743ca
--- /dev/null
+++ b/jni/ruby/sample/drb/ring_echo.rb
@@ -0,0 +1,30 @@
+require 'drb/drb'
+require 'drb/eq'
+require 'rinda/ring'
+require 'thread'
+
+class RingEcho
+ include DRbUndumped
+ def initialize(name)
+ @name = name
+ end
+
+ def echo(str)
+ "#{@name}: #{str}"
+ end
+end
+
+DRb.start_service
+
+renewer = Rinda::SimpleRenewer.new
+
+finder = Rinda::RingFinger.new
+ts = finder.lookup_ring_any
+ts.read_all([:name, :RingEcho, nil, nil]).each do |tuple|
+ p tuple[2]
+ puts tuple[2].echo('Hello, World') rescue nil
+end
+ts.write([:name, :RingEcho, RingEcho.new(DRb.uri), ''], renewer)
+
+DRb.thread.join
+
diff --git a/jni/ruby/sample/drb/ring_inspect.rb b/jni/ruby/sample/drb/ring_inspect.rb
new file mode 100644
index 0000000..c096cd7
--- /dev/null
+++ b/jni/ruby/sample/drb/ring_inspect.rb
@@ -0,0 +1,30 @@
+require 'rinda/ring'
+require 'drb/drb'
+
+class Inspector
+ def initialize
+ end
+
+ def primary
+ Rinda::RingFinger.primary
+ end
+
+ def list_place
+ Rinda::RingFinger.to_a
+ end
+
+ def list(idx = -1)
+ if idx < 0
+ ts = primary
+ else
+ ts = list_place[idx]
+ raise "RingNotFound" unless ts
+ end
+ ts.read_all([:name, nil, nil, nil])
+ end
+end
+
+def main
+ DRb.start_service
+ r = Inspector.new
+end
diff --git a/jni/ruby/sample/drb/ring_place.rb b/jni/ruby/sample/drb/ring_place.rb
new file mode 100644
index 0000000..11c6c2f
--- /dev/null
+++ b/jni/ruby/sample/drb/ring_place.rb
@@ -0,0 +1,25 @@
+require 'drb/drb'
+require 'rinda/ring'
+require 'rinda/tuplespace'
+
+unless $DEBUG
+ # Run as a daemon...
+ exit!( 0 ) if fork
+ Process.setsid
+ exit!( 0 ) if fork
+end
+
+DRb.start_service(ARGV.shift)
+
+ts = Rinda::TupleSpace.new
+place = Rinda::RingServer.new(ts)
+
+if $DEBUG
+ puts DRb.uri
+ DRb.thread.join
+else
+ STDIN.reopen(IO::NULL)
+ STDOUT.reopen(IO::NULL, 'w')
+ STDERR.reopen(IO::NULL, 'w')
+ DRb.thread.join
+end
diff --git a/jni/ruby/sample/drb/simpletuple.rb b/jni/ruby/sample/drb/simpletuple.rb
new file mode 100644
index 0000000..bfbd86e
--- /dev/null
+++ b/jni/ruby/sample/drb/simpletuple.rb
@@ -0,0 +1,91 @@
+#!/usr/local/bin/ruby
+# SimpleTupleSpace
+# Copyright (c) 1999-2000 Masatoshi SEKI
+# You can redistribute it and/or modify it under the same terms as Ruby.
+
+require 'thread'
+
+class SimpleTupleSpace
+ def initialize
+ @hash = {}
+ @waiting = {}
+ @hash.taint
+ @waiting.taint
+ self.taint
+ end
+
+ def out(key, obj)
+ Thread.critical = true
+ @hash[key] ||= []
+ @waiting[key] ||= []
+ @hash[key].push obj
+ begin
+ t = @waiting[key].shift
+ @waiting.delete(key) if @waiting[key].length == 0
+ t.wakeup if t
+ rescue ThreadError
+ retry
+ ensure
+ Thread.critical = false
+ end
+ end
+
+ def in(key)
+ Thread.critical = true
+ @hash[key] ||= []
+ @waiting[key] ||= []
+ begin
+ loop do
+ if @hash[key].length == 0
+ @waiting[key].push Thread.current
+ Thread.stop
+ else
+ return @hash[key].shift
+ end
+ end
+ ensure
+ @hash.delete(key) if @hash[key].length == 0
+ Thread.critical = false
+ end
+ end
+end
+
+if __FILE__ == $0
+ ts = SimpleTupleSpace.new
+ clients = []
+ servers = []
+
+ def server(ts)
+ Thread.start {
+ loop do
+ req = ts.in('req')
+ ac = req[0]
+ num = req[1]
+ ts.out(ac, num * num)
+ end
+ }
+ end
+
+ def client(ts, n)
+ Thread.start {
+ ac = Object.new
+ ts.out('req', [ac, n])
+ ans = ts.in(ac)
+ puts "#{n}: #{ans}"
+ }
+ end
+
+ 3.times do
+ servers.push(server(ts))
+ end
+
+ (1..6).each do |n|
+ clients.push(client(ts, n))
+ end
+
+ clients.each do |t|
+ t.join
+ end
+end
+
+
diff --git a/jni/ruby/sample/drb/speedc.rb b/jni/ruby/sample/drb/speedc.rb
new file mode 100644
index 0000000..64b8a65
--- /dev/null
+++ b/jni/ruby/sample/drb/speedc.rb
@@ -0,0 +1,21 @@
+#!/usr/local/bin/ruby
+
+uri = ARGV.shift || raise("usage: #{$0} URI")
+N = (ARGV.shift || 100).to_i
+
+case uri
+when /^tcpromp:/, /^unixromp:/
+ require 'romp'
+
+ client = ROMP::Client.new(uri, false)
+ foo = client.resolve("foo")
+when /^druby:/
+ require 'drb/drb'
+
+ DRb.start_service
+ foo = DRbObject.new(nil, uri)
+end
+
+N.times do |n|
+ foo.foo(n)
+end
diff --git a/jni/ruby/sample/drb/speeds.rb b/jni/ruby/sample/drb/speeds.rb
new file mode 100644
index 0000000..7984059
--- /dev/null
+++ b/jni/ruby/sample/drb/speeds.rb
@@ -0,0 +1,31 @@
+class Foo
+ attr_reader :i
+ def initialize
+ @i = 0
+ end
+
+ def foo(i)
+ @i = i
+ i + i
+ end
+end
+
+# server = ROMP::Server.new('tcpromp://localhost:4242', nil, true)
+
+uri = ARGV.shift || raise("usage: #{$0} URI")
+foo = Foo.new
+
+case uri
+when /^tcpromp:/, /^unixromp:/
+ require 'romp'
+
+ server = ROMP::Server.new(uri, nil, true)
+ server.bind(foo, "foo")
+
+when /^druby:/
+ require 'drb/drb'
+
+ DRb.start_service(uri, Foo.new)
+end
+
+DRb.thread.join
diff --git a/jni/ruby/sample/dualstack-fetch.rb b/jni/ruby/sample/dualstack-fetch.rb
new file mode 100644
index 0000000..18d33cc
--- /dev/null
+++ b/jni/ruby/sample/dualstack-fetch.rb
@@ -0,0 +1,48 @@
+# simple webpage fetcher
+
+# The code demonstrates how a multi-protocol client should be written.
+# TCPSocket is using getaddrinfo() internally, so there should be no problem.
+
+require "socket"
+
+if ARGV.size != 1
+ STDERR.print "requires URL\n"
+ exit
+end
+
+url = ARGV[0]
+if url !~ /^http:\/\/([^\/]+)(\/.*)$/
+ STDERR.print "only http with full hostname is supported\n"
+ exit
+end
+
+# split URL into host, port and path
+hostport = $1
+path = $2
+if (hostport =~ /^(.*):([0-9]+)$/)
+ host = $1
+ port = $2
+else
+ host = hostport
+ port = 80
+end
+if host =~ /^\[(.*)\]$/
+ host = $1
+end
+
+#STDERR.print "url=<#{ARGV[0]}>\n"
+#STDERR.print "host=<#{host}>\n"
+#STDERR.print "port=<#{port}>\n"
+#STDERR.print "path=<#{path}>\n"
+
+STDERR.print "conntecting to #{host} port #{port}\n"
+c = TCPSocket.new(host, port)
+dest = Socket.getnameinfo(c.getpeername,
+ Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)
+STDERR.print "conntected to #{dest[0]} port #{dest[1]}\n"
+c.print "GET #{path} HTTP/1.0\n"
+c.print "Host: #{host}\n"
+c.print "\n"
+while c.gets
+ print
+end
diff --git a/jni/ruby/sample/dualstack-httpd.rb b/jni/ruby/sample/dualstack-httpd.rb
new file mode 100644
index 0000000..a6d4d3a
--- /dev/null
+++ b/jni/ruby/sample/dualstack-httpd.rb
@@ -0,0 +1,55 @@
+# simple httpd
+
+# The code demonstrates how a multi-protocol daemon should be written.
+
+require "socket"
+require "thread"
+
+port = 8888
+res = Socket.getaddrinfo(nil, port, nil, Socket::SOCK_STREAM, nil, Socket::AI_PASSIVE)
+sockpool = []
+names = []
+threads = []
+
+res.each do |i|
+ s = TCPServer.new(i[3], i[1])
+ n = Socket.getnameinfo(s.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV).join(" port ")
+ sockpool.push s
+ names.push n
+end
+
+(0 .. sockpool.size - 1).each do |i|
+ mysock = sockpool[i]
+ myname = names[i]
+ STDERR.print "socket #{mysock} started, address #{myname}\n"
+ threads[i] = Thread.start do # Thread.start cannot be used here!
+ ls = mysock # copy to dynamic variable
+ t = Thread.current
+ STDERR.print "socket #{myname} listener started, pid #{$$} thread #{t}\n"
+ while true
+ as = ls.accept
+ Thread.start do
+ STDERR.print "socket #{myname} accepted, thread ", Thread.current, "\n"
+ s = as # copy to dynamic variable
+ str = ''
+ while line = s.gets
+ break if line == "\r\n" or line == "\n"
+ str << line
+ end
+ STDERR.print "socket #{myname} got string\n"
+ s.write("HTTP/1.0 200 OK\n")
+ s.write("Content-type: text/plain\n\n")
+ s.write("this is test: my name is #{myname}, you sent:\n")
+ s.write("---start\n")
+ s.write(str)
+ s.write("---end\n")
+ s.close
+ STDERR.print "socket #{myname} processed, thread ", Thread.current, " terminating\n"
+ end
+ end
+ end
+end
+
+for t in threads
+ t.join
+end
diff --git a/jni/ruby/sample/eval.rb b/jni/ruby/sample/eval.rb
new file mode 100644
index 0000000..ed4b7c3
--- /dev/null
+++ b/jni/ruby/sample/eval.rb
@@ -0,0 +1,41 @@
+line = ''
+indent = 0
+$stdout.sync = true
+print "ruby> "
+loop do
+ l = gets
+ if l.nil?
+ break if line.empty?
+ else
+ line += l
+ if l =~ /,\s*$/
+ print "ruby| "
+ next
+ end
+ if l =~ /^\s*(class|module|def|if|unless|case|while|until|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 ScriptError, StandardError
+ printf "ERR: %s\n", $! || 'exception raised'
+ end
+ break if l.nil?
+ line = ''
+ print "ruby> "
+end
+print "\n"
diff --git a/jni/ruby/sample/export.rb b/jni/ruby/sample/export.rb
new file mode 100644
index 0000000..949e5b1
--- /dev/null
+++ b/jni/ruby/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/jni/ruby/sample/exyacc.rb b/jni/ruby/sample/exyacc.rb
new file mode 100644
index 0000000..7b37a8b
--- /dev/null
+++ b/jni/ruby/sample/exyacc.rb
@@ -0,0 +1,20 @@
+#! /usr/local/bin/ruby -Kn
+# usage: exyacc.rb [yaccfiles]
+# this is coverted from exyacc.pl in the camel book
+
+ARGF.each(nil) do |source|
+ sbeg = source.index("\n%%") + 1
+ send = source.rindex("\n%%") + 1
+ grammar = source[sbeg, send-sbeg]
+ grammar.sub!(/.*\n/, "")
+ grammar.gsub!(/'\{'/, "'\001'")
+ grammar.gsub!(/'\}'/, "'\002'")
+ grammar.gsub!(%r{\*/}, "\003\003")
+ grammar.gsub!(%r{/\*[^\003]*\003\003}, '')
+ while grammar.gsub!(/\{[^{}]*\}/, ''); end
+ grammar.gsub!(/'\001'/, "'{'")
+ grammar.gsub!(/'\002'/, "'}'")
+ while grammar.gsub!(/^[ \t]*\n(\s)/, '\1'); end
+ grammar.gsub!(/([:|])[ \t\n]+(\w)/, '\1 \2')
+ print grammar
+end
diff --git a/jni/ruby/sample/fact.rb b/jni/ruby/sample/fact.rb
new file mode 100644
index 0000000..d8147a4
--- /dev/null
+++ b/jni/ruby/sample/fact.rb
@@ -0,0 +1,9 @@
+def fact(n)
+ return 1 if n == 0
+ f = 1
+ n.downto(1) do |i|
+ f *= i
+ end
+ return f
+end
+print fact(ARGV[0].to_i), "\n"
diff --git a/jni/ruby/sample/fib.awk b/jni/ruby/sample/fib.awk
new file mode 100644
index 0000000..9589f97
--- /dev/null
+++ b/jni/ruby/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/jni/ruby/sample/fib.pl b/jni/ruby/sample/fib.pl
new file mode 100644
index 0000000..4c35eaa
--- /dev/null
+++ b/jni/ruby/sample/fib.pl
@@ -0,0 +1,11 @@
+sub fib {
+ my($n)=@_;
+ if ($n<2) {
+ return $n;
+ }
+ else {
+ return fib($n-2)+fib($n-1);
+ }
+}
+
+print fib(20), "\n";
diff --git a/jni/ruby/sample/fib.py b/jni/ruby/sample/fib.py
new file mode 100644
index 0000000..8318021
--- /dev/null
+++ b/jni/ruby/sample/fib.py
@@ -0,0 +1,10 @@
+# calculate Fibonacci(20)
+# for benchmark
+def fib(n):
+ if n<2:
+ return n
+ else:
+ return fib(n-2)+fib(n-1)
+
+print fib(20)
+
diff --git a/jni/ruby/sample/fib.rb b/jni/ruby/sample/fib.rb
new file mode 100644
index 0000000..cde4fba
--- /dev/null
+++ b/jni/ruby/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/jni/ruby/sample/fib.scm b/jni/ruby/sample/fib.scm
new file mode 100644
index 0000000..d2dc770
--- /dev/null
+++ b/jni/ruby/sample/fib.scm
@@ -0,0 +1,8 @@
+(define (fib n)
+ (if (< n 2)
+ n
+ (+ (fib (- n 2)) (fib (- n 1)))))
+
+(display (fib 20))
+(newline)
+(quit)
diff --git a/jni/ruby/sample/freq.rb b/jni/ruby/sample/freq.rb
new file mode 100644
index 0000000..1b2194c
--- /dev/null
+++ b/jni/ruby/sample/freq.rb
@@ -0,0 +1,12 @@
+# word occurrence listing
+# usage: ruby freq.rb file..
+freq = Hash.new(0)
+while line = gets()
+ line.scan(/\w+/) do |word|
+ freq[word] += 1
+ end
+end
+
+for word in freq.keys.sort!
+ print word, " -- ", freq[word], "\n"
+end
diff --git a/jni/ruby/sample/from.rb b/jni/ruby/sample/from.rb
new file mode 100644
index 0000000..db1299c
--- /dev/null
+++ b/jni/ruby/sample/from.rb
@@ -0,0 +1,113 @@
+#! /usr/local/bin/ruby
+
+require "time"
+require "kconv"
+
+class String
+ def kjust(len)
+ res = ''
+ rlen = 0
+ self.each_char do |char|
+ delta = char.bytesize > 1 ? 2 : 1
+ break if rlen + delta > len
+ rlen += delta
+ res += char
+ end
+ res += ' ' * (len - rlen) if rlen < len
+ res
+ end
+end
+
+def fromout(date, from, subj)
+ return 0 if !date
+ y, m, d = Time.parse(date).to_a.reverse[4, 3] if date
+ y ||= 0; m ||= 0; d ||= 0
+ from ||= "sombody@somewhere"
+ from.delete!("\r\n")
+ from = from.kconv(Encoding.default_external).kjust(28)
+ subj ||= "(nil)"
+ subj.delete!("\r\n")
+ subj = subj.kconv(Encoding.default_external).kjust(40)
+ printf "%02d/%02d/%02d [%s] %s\n", y%100, m, d, from, subj
+ return 1
+end
+
+def get_mailfile(user)
+ file = user
+ unless user
+ file = ENV['MAIL']
+ user = ENV['USER'] || ENV['USERNAME'] || ENV['LOGNAME']
+ end
+
+ if file == nil or !File.exist?(file)
+ [ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m|
+ path = "#{m}/mail/#{user}"
+ if File.exist?(path)
+ file = path
+ break
+ end
+ end
+ end
+ file
+end
+
+def from_main
+ if ARGV[0] == '-w'
+ wait = true
+ ARGV.shift
+ end
+ file = get_mailfile(ARGV[0])
+
+ outcount = 0
+ if File.exist?(file)
+ atime = File.atime(file)
+ mtime = File.mtime(file)
+ open(file, "r") do |f|
+ until f.eof?
+ header = {}
+ f.each_line do |line|
+ next if /^From / =~ line # skip From-line
+ break if /^$/ =~ line # end of header
+
+ if /^(?<attr>\S+?):\s*(?<value>.*)/ =~ line
+ attr.capitalize!
+ header[attr] = value
+ elsif attr
+ header[attr] += "\n" + line.lstrip
+ end
+ end
+
+ f.each_line do |line|
+ break if /^From / =~ line
+ end
+ outcount += fromout(header['Date'], header['From'], header['Subject'])
+ end
+ end
+ File.utime(atime, mtime, file)
+ end
+
+ if outcount == 0
+ print "You have no mail.\n"
+ sleep 2 if wait
+ elsif wait
+ system "stty cbreak -echo"
+ $stdin.getc
+ system "stty cooked echo"
+ end
+end
+
+if __FILE__ == $0
+ from_main
+end
+
+__END__
+
+=begin
+
+= from.rb
+
+== USAGE
+
+ruby from.rb [-w] [username_or_filename]
+
+=end
diff --git a/jni/ruby/sample/fullpath.rb b/jni/ruby/sample/fullpath.rb
new file mode 100644
index 0000000..112ca58
--- /dev/null
+++ b/jni/ruby/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 !~ %r|/$|
+ path += "/"
+end
+
+while line = gets()
+ case line
+ when /:$/
+ path = line.chop.chop + "/"
+ when /^total/, /^d/
+ when /^(.*\d )(.+)$/
+ print($1, path, $2, "\n")
+ end
+end
diff --git a/jni/ruby/sample/less.rb b/jni/ruby/sample/less.rb
new file mode 100644
index 0000000..8be3591
--- /dev/null
+++ b/jni/ruby/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/jni/ruby/sample/list.rb b/jni/ruby/sample/list.rb
new file mode 100644
index 0000000..85899ce
--- /dev/null
+++ b/jni/ruby/sample/list.rb
@@ -0,0 +1,81 @@
+# Linked list example
+class MyElem
+ # object initializer called from Class#new
+ def initialize(item)
+ # @variables are instance variable, no declaration needed
+ @data = item
+ @succ = nil
+ @head = nil
+ end
+
+ def data
+ @data
+ end
+
+ def succ
+ @succ
+ end
+
+ # the method invoked by ``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
+
+ # the method to convert object into string.
+ # redefining this will affect print.
+ def to_s
+ str = "<MyList:\n";
+ for elt in self
+ # short form of ``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
+
+# global variable name starts with `$'.
+$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)
+
+# parenthesises around method arguments can be ommitted unless ambiguous.
+print "list1:\n", $list1, "\n"
+print "list2:\n", $list2, "\n"
diff --git a/jni/ruby/sample/list2.rb b/jni/ruby/sample/list2.rb
new file mode 100644
index 0000000..1d71aff
--- /dev/null
+++ b/jni/ruby/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/jni/ruby/sample/list3.rb b/jni/ruby/sample/list3.rb
new file mode 100644
index 0000000..1d9f04b
--- /dev/null
+++ b/jni/ruby/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/jni/ruby/sample/logger/app.rb b/jni/ruby/sample/logger/app.rb
new file mode 100644
index 0000000..97b62bc
--- /dev/null
+++ b/jni/ruby/sample/logger/app.rb
@@ -0,0 +1,46 @@
+#!/usr/bin/env ruby
+
+require 'logger'
+
+class MyApp < Logger::Application
+ def initialize(a, b, c)
+ super('MyApp')
+
+ # Set logDevice here.
+ logfile = 'app.log'
+ self.log = logfile
+ self.level = INFO
+
+ # Initialize your application...
+ @a = a
+ @b = b
+ @c = c
+ end
+
+ def run
+ @log.info { 'Started.' }
+
+ @log.info { "This block isn't evaled because 'debug' is not severe here." }
+ @log.debug { "Result = " << foo(0) }
+ @log.info { "So nothing is dumped." }
+
+ @log.info { "This block is evaled because 'info' is enough severe here." }
+ @log.info { "Result = " << foo(0) }
+ @log.info { "Above causes exception, so not reached here." }
+
+ @log.info { 'Finished.' }
+ end
+
+private
+
+ def foo(var)
+ 1 / var
+ end
+end
+
+status = MyApp.new(1, 2, 3).start
+
+if status != 0
+ puts 'Some error(s) occurred.'
+ puts 'See "app.log".'
+end
diff --git a/jni/ruby/sample/logger/log.rb b/jni/ruby/sample/logger/log.rb
new file mode 100644
index 0000000..aab80e4
--- /dev/null
+++ b/jni/ruby/sample/logger/log.rb
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+
+require 'logger'
+
+log = Logger.new(STDERR)
+
+def do_log(log)
+ log.debug('do_log1') { "debug" }
+ log.info('do_log2') { "info" }
+ log.warn('do_log3') { "warn" }
+ log.error('do_log4') { "error" }
+ log.fatal('do_log6') { "fatal" }
+ log.unknown('do_log7') { "unknown" }
+end
+
+log.level = Logger::DEBUG # Default.
+do_log(log)
+
+puts "Set severity threshold 'WARN'."
+
+log.level = Logger::WARN
+do_log(log)
+
+puts "Change datetime format. Thanks to Daniel Berger."
+
+log.datetime_format = "%d-%b-%Y@%H:%M:%S"
+do_log(log)
diff --git a/jni/ruby/sample/logger/shifting.rb b/jni/ruby/sample/logger/shifting.rb
new file mode 100644
index 0000000..bd8852a
--- /dev/null
+++ b/jni/ruby/sample/logger/shifting.rb
@@ -0,0 +1,26 @@
+#!/usr/bin/env ruby
+
+require 'logger'
+
+logfile = 'shifting.log'
+# Max 3 age ... logShifting.log, logShifting.log.0, and logShifting.log.1
+shift_age = 3
+# Shift log file about for each 1024 bytes.
+shift_size = 1024
+
+log = Logger.new(logfile, shift_age, shift_size)
+
+def do_log(log)
+ log.debug('do_log1') { 'd' * rand(100) }
+ log.info('do_log2') { 'i' * rand(100) }
+ log.warn('do_log3') { 'w' * rand(100) }
+ log.error('do_log4') { 'e' * rand(100) }
+ log.fatal('do_log5') { 'f' * rand(100) }
+ log.unknown('do_log6') { 'u' * rand(100) }
+end
+
+(1..10).each do
+ do_log(log)
+end
+
+puts 'See shifting.log and shifting.log.[01].'
diff --git a/jni/ruby/sample/mine.rb b/jni/ruby/sample/mine.rb
new file mode 100755
index 0000000..a841d1a
--- /dev/null
+++ b/jni/ruby/sample/mine.rb
@@ -0,0 +1,176 @@
+#! /usr/bin/ruby -Ku
+# -*- coding: utf-8 -*-
+
+class Board
+ def clr
+ print "\e[2J"
+ end
+ def pos(x,y)
+ printf "\e[%d;%dH", y+1, x*2+1
+ end
+ def colorstr(id,s)
+ printf "\e[%dm%s\e[0m", id, s
+ end
+ def put(x, y, col, str)
+ pos(x,y); colorstr(43,str)
+ pos(0,@hi); print "残り:",@mc,"/",@total," "
+ pos(x,y)
+ end
+ private :clr, :pos, :colorstr, :put
+ CHR=["・","1","ï¼’","3","ï¼”","5","ï¼–","ï¼—","8","★","â—","@@"]
+ COL=[46,43,45] # default,opened,over
+ def initialize(h,w,m)
+ # ゲーム盤ã®ç”Ÿæˆ(h:縦,w:横,m:爆弾ã®æ•°)
+ @hi=h; @wi=w; @m=m
+ reset
+ end
+ def reset
+ # ゲーム盤を(å†)åˆæœŸåŒ–ã™ã‚‹
+ srand()
+ @cx=0; @cy=0; @mc=@m
+ @over=false
+ @data=Array.new(@hi*@wi)
+ @state=Array.new(@hi*@wi)
+ @total=@hi*@wi
+ @total.times {|i| @data[i]=0}
+ @m.times do
+ loop do
+ j=rand(@total-1)
+ if @data[j] == 0 then
+ @data[j]=1
+ break
+ end
+ end
+ end
+ clr; pos(0,0)
+ @hi.times{|y| pos(0,y); colorstr(COL[0],CHR[0]*@wi)}
+ pos(@cx,@cy)
+ end
+ def mark
+ # ç¾åœ¨ã®ã‚«ãƒ¼ã‚½ãƒ«ä½ç½®ã«ãƒžãƒ¼ã‚¯ã‚’ã¤ã‘ã‚‹
+ if @state[@wi*@cy+@cx] != nil then return end
+ @state[@wi*@cy+@cx] = "MARK"
+ @mc=@mc-1;
+ @total=@total-1;
+ put(@cx, @cy, COL[1], CHR[9])
+ end
+ def open(x=@cx,y=@cy)
+ # ç¾åœ¨ã®ã‚«ãƒ¼ã‚½ãƒ«ä½ç½®ã‚’オープンã«ã™ã‚‹
+ # 爆弾ãŒã‚ã‚Œã°ã‚²ãƒ¼ãƒ ã‚ªãƒ¼ãƒãƒ¼
+ if @state[@wi*y+x] =="OPEN" then return 0 end
+ if @state[@wi*y+x] == nil then @total=@total-1 end
+ if @state[@wi*y+x] =="MARK" then @mc=@mc+1 end
+ @state[@wi*y+x]="OPEN"
+ if fetch(x,y) == 1 then @over = 1; return end
+ c = count(x,y)
+ put(x, y, COL[1], CHR[c])
+ return 0 if c != 0
+ if x > 0 && y > 0 then open(x-1,y-1) end
+ if y > 0 then open(x, y-1) end
+ if x < @wi-1 && y > 0 then open(x+1,y-1) end
+ if x > 0 then open(x-1,y) end
+ if x < @wi-1 then open(x+1,y) end
+ if x > 0 && y < @hi-1 then open(x-1,y+1) end
+ if y < @hi -1 then open(x,y+1) end
+ if x < @wi-1 && y < @hi-1 then open(x+1,y+1) end
+ pos(@cx,@cy)
+ end
+ def fetch(x,y)
+ # (x,y)ã®ä½ç½®ã®çˆ†å¼¾ã®æ•°(0 or 1)ã‚’è¿”ã™
+ if x < 0 then 0
+ elsif x >= @wi then 0
+ elsif y < 0 then 0
+ elsif y >= @hi then 0
+ else
+ @data[y*@wi+x]
+ end
+ end
+ def count(x,y)
+ # (x,y)ã«éš£æŽ¥ã™ã‚‹çˆ†å¼¾ã®æ•°ã‚’è¿”ã™
+ fetch(x-1,y-1)+fetch(x,y-1)+fetch(x+1,y-1)+
+ fetch(x-1,y) + fetch(x+1,y)+
+ fetch(x-1,y+1)+fetch(x,y+1)+fetch(x+1,y+1)
+ end
+ def over(win)
+ # ゲームã®çµ‚了
+ quit
+ unless win
+ pos(@cx,@cy); print CHR[11]
+ end
+ pos(0,@hi)
+ if win then print "*** YOU WIN !! ***"
+ else print "*** GAME OVER ***"
+ end
+ end
+ def over?
+ # ゲームã®çµ‚了ãƒã‚§ãƒƒã‚¯
+ # 終了処ç†ã‚‚呼ã³å‡ºã™
+ remain = (@mc+@total == 0)
+ if @over || remain
+ over(remain)
+ true
+ else
+ false
+ end
+ end
+ def quit
+ # ゲームã®ä¸­æ–­(ã¾ãŸã¯çµ‚了)
+ # 盤é¢ã‚’å…¨ã¦è¦‹ã›ã‚‹
+ @hi.times do|y|
+ pos(0,y)
+ @wi.times do|x|
+ colorstr(if @state[y*@wi+x] == "MARK" then COL[1] else COL[2] end,
+ if fetch(x,y)==1 then CHR[10] else CHR[count(x,y)] end)
+ end
+ end
+ end
+ def down
+ # カーソルを下ã«
+ if @cy < @hi-1 then @cy=@cy+1; pos(@cx, @cy) end
+ end
+ def up
+ # カーソルを上ã«
+ if @cy > 0 then @cy=@cy-1; pos(@cx, @cy) end
+ end
+ def left
+ # カーソルを左ã«
+ if @cx > 0 then @cx=@cx-1; pos(@cx, @cy) end
+ end
+ def right
+ # カーソルをå³ã«
+ if @cx < @wi-1 then @cx=@cx+1; pos(@cx, @cy) end
+ end
+end
+
+bd=Board.new(10,10,10)
+system("stty raw -echo")
+begin
+ loop do
+ case STDIN.getc
+ when ?n # new game
+ bd.reset
+ when ?m # mark
+ bd.mark
+ when ?j
+ bd.down
+ when ?k
+ bd.up
+ when ?h
+ bd.left
+ when ?l
+ bd.right
+ when ?\s
+ bd.open
+ when ?q,?\C-c # quit game
+ bd.quit
+ break
+ end
+ if bd.over?
+ if STDIN.getc == ?q then break end
+ bd.reset
+ end
+ end
+ensure
+ system("stty -raw echo")
+end
+print "\n"
diff --git a/jni/ruby/sample/mkproto.rb b/jni/ruby/sample/mkproto.rb
new file mode 100644
index 0000000..e650fe8
--- /dev/null
+++ b/jni/ruby/sample/mkproto.rb
@@ -0,0 +1,27 @@
+$/ = nil
+while line = gets()
+ if /^((void|VALUE|int|char *\*|ID|struct \w+ *\*|st_table *\*) *)?\n(\w+)\(.*\)\n\s*((.+;\n)*)\{/ =~ line
+ line = $'
+ printf "%s %s(", $2, $3
+ args = []
+ for arg in $4.split(/;\n\s*/)
+ arg.gsub!(/ +/, ' ')
+ if arg =~ /,/
+ if arg =~ /(([^*]+) *\** *\w+),/
+ type = $2.strip
+ args.push $1.strip
+ arg = $'
+ else
+ type = ""
+ end
+ while arg.sub!(/(\** *\w+)(,|$)/, "") && $~
+ args.push type + " " + $1.strip
+ end
+ else
+ args.push arg.strip
+ end
+ end
+ printf "%s);\n", args.join(', ')
+ redo
+ end
+end
diff --git a/jni/ruby/sample/mpart.rb b/jni/ruby/sample/mpart.rb
new file mode 100644
index 0000000..a88eba0
--- /dev/null
+++ b/jni/ruby/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 and !ifp.eof?
+ 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/jni/ruby/sample/net-imap.rb b/jni/ruby/sample/net-imap.rb
new file mode 100644
index 0000000..b93ecb7
--- /dev/null
+++ b/jni/ruby/sample/net-imap.rb
@@ -0,0 +1,167 @@
+require 'net/imap'
+require "getoptlong"
+
+$stdout.sync = true
+$port = nil
+$user = ENV["USER"] || ENV["LOGNAME"]
+$auth = "login"
+$ssl = false
+$starttls = false
+
+def usage
+ <<EOF
+usage: #{$0} [options] <host>
+
+ --help print this message
+ --port=PORT specifies port
+ --user=USER specifies user
+ --auth=AUTH specifies auth type
+ --starttls use starttls
+ --ssl use ssl
+EOF
+end
+
+begin
+ require 'io/console'
+rescue LoadError
+ def _noecho(&block)
+ system("stty", "-echo")
+ begin
+ yield STDIN
+ ensure
+ system("stty", "echo")
+ end
+ end
+else
+ def _noecho(&block)
+ STDIN.noecho(&block)
+ end
+end
+
+def get_password
+ print "password: "
+ begin
+ return _noecho(&:gets).chomp
+ ensure
+ puts
+ end
+end
+
+def get_command
+ printf("%s@%s> ", $user, $host)
+ if line = gets
+ return line.strip.split(/\s+/)
+ else
+ return nil
+ end
+end
+
+parser = GetoptLong.new
+parser.set_options(['--debug', GetoptLong::NO_ARGUMENT],
+ ['--help', GetoptLong::NO_ARGUMENT],
+ ['--port', GetoptLong::REQUIRED_ARGUMENT],
+ ['--user', GetoptLong::REQUIRED_ARGUMENT],
+ ['--auth', GetoptLong::REQUIRED_ARGUMENT],
+ ['--starttls', GetoptLong::NO_ARGUMENT],
+ ['--ssl', GetoptLong::NO_ARGUMENT])
+begin
+ parser.each_option do |name, arg|
+ case name
+ when "--port"
+ $port = arg
+ when "--user"
+ $user = arg
+ when "--auth"
+ $auth = arg
+ when "--ssl"
+ $ssl = true
+ when "--starttls"
+ $starttls = true
+ when "--debug"
+ Net::IMAP.debug = true
+ when "--help"
+ usage
+ exit
+ end
+ end
+rescue
+ abort usage
+end
+
+$host = ARGV.shift
+unless $host
+ abort usage
+end
+
+imap = Net::IMAP.new($host, :port => $port, :ssl => $ssl)
+begin
+ imap.starttls if $starttls
+ class << password = method(:get_password)
+ alias to_str call
+ end
+ imap.authenticate($auth, $user, password)
+ while true
+ cmd, *args = get_command
+ break unless cmd
+ begin
+ case cmd
+ when "list"
+ for mbox in imap.list("", args[0] || "*")
+ if mbox.attr.include?(Net::IMAP::NOSELECT)
+ prefix = "!"
+ elsif mbox.attr.include?(Net::IMAP::MARKED)
+ prefix = "*"
+ else
+ prefix = " "
+ end
+ print prefix, mbox.name, "\n"
+ end
+ when "select"
+ imap.select(args[0] || "inbox")
+ print "ok\n"
+ when "close"
+ imap.close
+ print "ok\n"
+ when "summary"
+ unless messages = imap.responses["EXISTS"][-1]
+ puts "not selected"
+ next
+ end
+ if messages > 0
+ for data in imap.fetch(1..-1, ["ENVELOPE"])
+ print data.seqno, ": ", data.attr["ENVELOPE"].subject, "\n"
+ end
+ else
+ puts "no message"
+ end
+ when "fetch"
+ if args[0]
+ data = imap.fetch(args[0].to_i, ["RFC822.HEADER", "RFC822.TEXT"])[0]
+ puts data.attr["RFC822.HEADER"]
+ puts data.attr["RFC822.TEXT"]
+ else
+ puts "missing argument"
+ end
+ when "logout", "exit", "quit"
+ break
+ when "help", "?"
+ print <<EOF
+list [pattern] list mailboxes
+select [mailbox] select mailbox
+close close mailbox
+summary display summary
+fetch [msgno] display message
+logout logout
+help, ? display help message
+EOF
+ else
+ print "unknown command: ", cmd, "\n"
+ end
+ rescue Net::IMAP::Error
+ puts $!
+ end
+ end
+ensure
+ imap.logout
+ imap.disconnect
+end
diff --git a/jni/ruby/sample/observ.rb b/jni/ruby/sample/observ.rb
new file mode 100644
index 0000000..061e3c6
--- /dev/null
+++ b/jni/ruby/sample/observ.rb
@@ -0,0 +1,32 @@
+#! /usr/local/bin/ruby
+
+require "thread"
+require "observer"
+
+class Tick
+ include Observable
+ def initialize
+ Thread.start do
+ loop do
+ sleep 0.999
+ now = Time.now
+ changed
+ notify_observers(now.hour, now.min, now.sec)
+ end
+ end
+ end
+end
+
+class Clock
+ def initialize(tick)
+ @tick = tick
+ @tick.add_observer(self)
+ end
+ def update(h, m, s)
+ printf "\e[8D%02d:%02d:%02d", h, m, s
+ STDOUT.flush
+ end
+end
+
+clock = Clock.new(Tick.new)
+sleep
diff --git a/jni/ruby/sample/occur.pl b/jni/ruby/sample/occur.pl
new file mode 100644
index 0000000..331ce50
--- /dev/null
+++ b/jni/ruby/sample/occur.pl
@@ -0,0 +1,9 @@
+while (<>) {
+ for (split(/\W+/)) {
+ $freq{$_}++;
+ }
+}
+
+for (sort keys %freq) {
+ print "$_ -- $freq{$_}\n";
+}
diff --git a/jni/ruby/sample/occur.rb b/jni/ruby/sample/occur.rb
new file mode 100644
index 0000000..42151d8
--- /dev/null
+++ b/jni/ruby/sample/occur.rb
@@ -0,0 +1,12 @@
+# word occurrence listing
+# usage: ruby occur.rb file..
+freq = Hash.new(0)
+while line = gets()
+ for word in line.split(/\W+/)
+ freq[word] += 1
+ end
+end
+
+for word in freq.keys.sort!
+ print word, " -- ", freq[word], "\n"
+end
diff --git a/jni/ruby/sample/occur2.rb b/jni/ruby/sample/occur2.rb
new file mode 100644
index 0000000..ef8ad2c
--- /dev/null
+++ b/jni/ruby/sample/occur2.rb
@@ -0,0 +1,13 @@
+# word occurrence listing
+# usage: ruby occur2.rb file..
+freq = {}
+ARGF.each_line do |line|
+ for word in line.split(/\W+/)
+ freq[word] ||= 0
+ freq[word] += 1
+ end
+end
+
+for word in freq.keys.sort
+ printf("%s -- %d\n", word, freq[word])
+end
diff --git a/jni/ruby/sample/open3.rb b/jni/ruby/sample/open3.rb
new file mode 100644
index 0000000..bc6cdfe
--- /dev/null
+++ b/jni/ruby/sample/open3.rb
@@ -0,0 +1,12 @@
+require 'open3'
+
+a = Open3.popen3("nroff -man")
+Thread.start do
+ while line = gets
+ a[0].print line
+ end
+ a[0].close
+end
+while line = a[1].gets
+ print ":", line
+end
diff --git a/jni/ruby/sample/openssl/c_rehash.rb b/jni/ruby/sample/openssl/c_rehash.rb
new file mode 100644
index 0000000..cd6c9d5
--- /dev/null
+++ b/jni/ruby/sample/openssl/c_rehash.rb
@@ -0,0 +1,174 @@
+#!/usr/bin/env ruby
+
+require 'openssl'
+require 'digest/md5'
+
+class CHashDir
+ include Enumerable
+
+ def initialize(dirpath)
+ @dirpath = dirpath
+ @fingerprint_cache = @cert_cache = @crl_cache = nil
+ end
+
+ def hash_dir(silent = false)
+ # ToDo: Should lock the directory...
+ @silent = silent
+ @fingerprint_cache = Hash.new
+ @cert_cache = Hash.new
+ @crl_cache = Hash.new
+ do_hash_dir
+ end
+
+ def get_certs(name = nil)
+ if name
+ @cert_cache[hash_name(name)]
+ else
+ @cert_cache.values.flatten
+ end
+ end
+
+ def get_crls(name = nil)
+ if name
+ @crl_cache[hash_name(name)]
+ else
+ @crl_cache.values.flatten
+ end
+ end
+
+ def delete_crl(crl)
+ File.unlink(crl_filename(crl))
+ hash_dir(true)
+ end
+
+ def add_crl(crl)
+ File.open(crl_filename(crl), "w") do |f|
+ f << crl.to_pem
+ end
+ hash_dir(true)
+ end
+
+ def load_pem_file(filepath)
+ str = File.read(filepath)
+ begin
+ OpenSSL::X509::Certificate.new(str)
+ rescue
+ begin
+ OpenSSL::X509::CRL.new(str)
+ rescue
+ begin
+ OpenSSL::X509::Request.new(str)
+ rescue
+ nil
+ end
+ end
+ end
+ end
+
+private
+
+ def crl_filename(crl)
+ path(hash_name(crl.issuer)) + '.pem'
+ end
+
+ def do_hash_dir
+ Dir.chdir(@dirpath) do
+ delete_symlink
+ Dir.glob('*.pem') do |pemfile|
+ cert = load_pem_file(pemfile)
+ case cert
+ when OpenSSL::X509::Certificate
+ link_hash_cert(pemfile, cert)
+ when OpenSSL::X509::CRL
+ link_hash_crl(pemfile, cert)
+ else
+ STDERR.puts("WARNING: #{pemfile} does not contain a certificate or CRL: skipping") unless @silent
+ end
+ end
+ end
+ end
+
+ def delete_symlink
+ Dir.entries(".").each do |entry|
+ next unless /^[\da-f]+\.r{0,1}\d+$/ =~ entry
+ File.unlink(entry) if FileTest.symlink?(entry)
+ end
+ end
+
+ def link_hash_cert(org_filename, cert)
+ name_hash = hash_name(cert.subject)
+ fingerprint = fingerprint(cert.to_der)
+ filepath = link_hash(org_filename, name_hash, fingerprint) { |idx|
+ "#{name_hash}.#{idx}"
+ }
+ unless filepath
+ unless @silent
+ STDERR.puts("WARNING: Skipping duplicate certificate #{org_filename}")
+ end
+ else
+ (@cert_cache[name_hash] ||= []) << path(filepath)
+ end
+ end
+
+ def link_hash_crl(org_filename, crl)
+ name_hash = hash_name(crl.issuer)
+ fingerprint = fingerprint(crl.to_der)
+ filepath = link_hash(org_filename, name_hash, fingerprint) { |idx|
+ "#{name_hash}.r#{idx}"
+ }
+ unless filepath
+ unless @silent
+ STDERR.puts("WARNING: Skipping duplicate CRL #{org_filename}")
+ end
+ else
+ (@crl_cache[name_hash] ||= []) << path(filepath)
+ end
+ end
+
+ def link_hash(org_filename, name, fingerprint)
+ idx = 0
+ filepath = nil
+ while true
+ filepath = yield(idx)
+ break unless FileTest.symlink?(filepath) or FileTest.exist?(filepath)
+ if @fingerprint_cache[filepath] == fingerprint
+ return false
+ end
+ idx += 1
+ end
+ STDOUT.puts("#{org_filename} => #{filepath}") unless @silent
+ symlink(org_filename, filepath)
+ @fingerprint_cache[filepath] = fingerprint
+ filepath
+ end
+
+ def symlink(from, to)
+ begin
+ File.symlink(from, to)
+ rescue
+ File.open(to, "w") do |f|
+ f << File.read(from)
+ end
+ end
+ end
+
+ def path(filename)
+ File.join(@dirpath, filename)
+ end
+
+ def hash_name(name)
+ sprintf("%x", name.hash)
+ end
+
+ def fingerprint(der)
+ Digest::MD5.hexdigest(der).upcase
+ end
+end
+
+if $0 == __FILE__
+ dirlist = ARGV
+ dirlist << '/usr/ssl/certs' if dirlist.empty?
+ dirlist.each do |dir|
+ CHashDir.new(dir).hash_dir
+ end
+end
diff --git a/jni/ruby/sample/openssl/cert2text.rb b/jni/ruby/sample/openssl/cert2text.rb
new file mode 100644
index 0000000..50da224
--- /dev/null
+++ b/jni/ruby/sample/openssl/cert2text.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+
+require 'openssl'
+include OpenSSL::X509
+
+def cert2text(cert_str)
+ [Certificate, CRL, Request].each do |klass|
+ begin
+ puts klass.new(cert_str).to_text
+ return
+ rescue
+ end
+ end
+ raise ArgumentError.new('Unknown format.')
+end
+
+if ARGV.empty?
+ cert2text(STDIN.read)
+else
+ ARGV.each do |file|
+ cert2text(File.read(file))
+ end
+end
diff --git a/jni/ruby/sample/openssl/certstore.rb b/jni/ruby/sample/openssl/certstore.rb
new file mode 100644
index 0000000..c6e8f81
--- /dev/null
+++ b/jni/ruby/sample/openssl/certstore.rb
@@ -0,0 +1,161 @@
+require 'c_rehash'
+require 'crlstore'
+
+
+class CertStore
+ include OpenSSL
+ include X509
+
+ attr_reader :self_signed_ca
+ attr_reader :other_ca
+ attr_reader :ee
+ attr_reader :crl
+ attr_reader :request
+
+ def initialize(certs_dir)
+ @certs_dir = certs_dir
+ @c_store = CHashDir.new(@certs_dir)
+ @c_store.hash_dir(true)
+ @crl_store = CrlStore.new(@c_store)
+ @x509store = Store.new
+ @self_signed_ca = @other_ca = @ee = @crl = nil
+
+ # Uncomment this line to let OpenSSL to check CRL for each certs.
+ # @x509store.flags = V_FLAG_CRL_CHECK | V_FLAG_CRL_CHECK_ALL
+
+ add_path
+ scan_certs
+ end
+
+ def generate_cert(filename)
+ @c_store.load_pem_file(filename)
+ end
+
+ def verify(cert)
+ error, crl_map = do_verify(cert)
+ if error
+ [[false, cert, crl_map[cert.subject], error]]
+ else
+ @x509store.chain.collect { |c| [true, c, crl_map[c.subject], nil] }
+ end
+ end
+
+ def match_cert(cert1, cert2)
+ (cert1.issuer.cmp(cert2.issuer) == 0) and cert1.serial == cert2.serial
+ end
+
+ def is_ca?(cert)
+ case guess_cert_type(cert)
+ when CERT_TYPE_SELF_SIGNED
+ true
+ when CERT_TYPE_OTHER
+ true
+ else
+ false
+ end
+ end
+
+ def scan_certs
+ @self_signed_ca = []
+ @other_ca = []
+ @ee = []
+ @crl = []
+ @request = []
+ load_certs
+ end
+
+private
+
+ def add_path
+ @x509store.add_path(@certs_dir)
+ end
+
+ def do_verify(cert)
+ error_map = {}
+ crl_map = {}
+ result = @x509store.verify(cert) do |ok, ctx|
+ cert = ctx.current_cert
+ if ctx.current_crl
+ crl_map[cert.subject] = true
+ end
+ if ok
+ if !ctx.current_crl
+ if crl = @crl_store.find_crl(cert)
+ crl_map[cert.subject] = true
+ if crl.revoked.find { |revoked| revoked.serial == cert.serial }
+ ok = false
+ error_string = 'certification revoked'
+ end
+ end
+ end
+ end
+ error_map[cert.subject] = error_string if error_string
+ ok
+ end
+ error = if result
+ nil
+ else
+ error_map[cert.subject] || @x509store.error_string
+ end
+ return error, crl_map
+ end
+
+ def load_certs
+ @c_store.get_certs.each do |certfile|
+ cert = generate_cert(certfile)
+ case guess_cert_type(cert)
+ when CERT_TYPE_SELF_SIGNED
+ @self_signed_ca << cert
+ when CERT_TYPE_OTHER
+ @other_ca << cert
+ when CERT_TYPE_EE
+ @ee << cert
+ else
+ raise "Unknown cert type."
+ end
+ end
+ @c_store.get_crls.each do |crlfile|
+ @crl << generate_cert(crlfile)
+ end
+ end
+
+ CERT_TYPE_SELF_SIGNED = 0
+ CERT_TYPE_OTHER = 1
+ CERT_TYPE_EE = 2
+ def guess_cert_type(cert)
+ ca = self_signed = is_cert_self_signed(cert)
+ cert.extensions.each do |ext|
+ # Ignores criticality of extensions. It's 'guess'ing.
+ case ext.oid
+ when 'basicConstraints'
+ /CA:(TRUE|FALSE), pathlen:(\d+)/ =~ ext.value
+ ca = ($1 == 'TRUE') unless ca
+ when 'keyUsage'
+ usage = ext.value.split(/\s*,\s*/)
+ ca = usage.include?('Certificate Sign') unless ca
+ when 'nsCertType'
+ usage = ext.value.split(/\s*,\s*/)
+ ca = usage.include?('SSL CA') unless ca
+ end
+ end
+ if ca
+ if self_signed
+ CERT_TYPE_SELF_SIGNED
+ else
+ CERT_TYPE_OTHER
+ end
+ else
+ CERT_TYPE_EE
+ end
+ end
+
+ def is_cert_self_signed(cert)
+ # cert.subject.cmp(cert.issuer) == 0
+ cert.subject.to_s == cert.issuer.to_s
+ end
+end
+
+
+if $0 == __FILE__
+ c = CertStore.new("trust_certs")
+end
diff --git a/jni/ruby/sample/openssl/cipher.rb b/jni/ruby/sample/openssl/cipher.rb
new file mode 100644
index 0000000..58b10d6
--- /dev/null
+++ b/jni/ruby/sample/openssl/cipher.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+require 'openssl'
+
+def crypt_by_password(alg, pass, salt, text)
+ puts "--Setup--"
+ puts %(cipher alg: "#{alg}")
+ puts %(plain text: "#{text}")
+ puts %(password: "#{pass}")
+ puts %(salt: "#{salt}")
+ puts
+
+ puts "--Encrypting--"
+ enc = OpenSSL::Cipher::Cipher.new(alg)
+ enc.encrypt
+ enc.pkcs5_keyivgen(pass, salt)
+ cipher = enc.update(text)
+ cipher << enc.final
+ puts %(encrypted text: #{cipher.inspect})
+ puts
+
+ puts "--Decrypting--"
+ dec = OpenSSL::Cipher::Cipher.new(alg)
+ dec.decrypt
+ dec.pkcs5_keyivgen(pass, salt)
+ plain = dec.update(cipher)
+ plain << dec.final
+ puts %(decrypted text: "#{plain}")
+ puts
+end
+
+def ciphers
+ ciphers = OpenSSL::Cipher.ciphers.sort
+ ciphers.each{|i|
+ if i.upcase != i && ciphers.include?(i.upcase)
+ ciphers.delete(i)
+ end
+ }
+ return ciphers
+end
+
+puts "Supported ciphers in #{OpenSSL::OPENSSL_VERSION}:"
+ciphers.each_with_index{|name, i|
+ printf("%-15s", name)
+ puts if (i + 1) % 5 == 0
+}
+puts
+puts
+
+alg = ARGV.shift || ciphers.first
+pass = "secret password"
+salt = "8 octets" # or nil
+text = "abcdefghijklmnopqrstuvwxyz"
+
+crypt_by_password(alg, pass, salt, text)
diff --git a/jni/ruby/sample/openssl/crlstore.rb b/jni/ruby/sample/openssl/crlstore.rb
new file mode 100644
index 0000000..e3a5925
--- /dev/null
+++ b/jni/ruby/sample/openssl/crlstore.rb
@@ -0,0 +1,122 @@
+begin
+ require 'http-access2'
+rescue LoadError
+ STDERR.puts("Cannot load http-access2. CRL might not be fetched.")
+end
+require 'c_rehash'
+
+
+class CrlStore
+ def initialize(c_store)
+ @c_store = c_store
+ @c_store.hash_dir(true)
+ end
+
+ def find_crl(cert)
+ do_find_crl(cert)
+ end
+
+private
+
+ def do_find_crl(cert)
+ unless ca = find_ca(cert)
+ return nil
+ end
+ unless crlfiles = @c_store.get_crls(ca.subject)
+ if crl = renew_crl(cert, ca)
+ @c_store.add_crl(crl)
+ return crl
+ end
+ return nil
+ end
+ crlfiles.each do |crlfile|
+ next unless crl = load_crl(crlfile)
+ if crl.next_update < Time.now
+ if new_crl = renew_crl(cert, ca)
+ @c_store.delete_crl(crl)
+ @c_store.add_crl(new_crl)
+ crl = new_crl
+ end
+ end
+ if check_valid(crl, ca)
+ return crl
+ end
+ end
+ nil
+ end
+
+ def find_ca(cert)
+ @c_store.get_certs(cert.issuer).each do |cafile|
+ ca = load_cert(cafile)
+ if cert.verify(ca.public_key)
+ return ca
+ end
+ end
+ nil
+ end
+
+ def fetch(location)
+ if /\AURI:(.*)\z/ =~ location
+ begin
+ c = HTTPAccess2::Client.new(ENV['http_proxy'] || ENV['HTTP_PROXY'])
+ c.get_content($1)
+ rescue NameError, StandardError
+ nil
+ end
+ else
+ nil
+ end
+ end
+
+ def load_cert(certfile)
+ load_cert_str(File.read(certfile))
+ end
+
+ def load_crl(crlfile)
+ load_crl_str(File.read(crlfile))
+ end
+
+ def load_cert_str(cert_str)
+ OpenSSL::X509::Certificate.new(cert_str)
+ end
+
+ def load_crl_str(crl_str)
+ OpenSSL::X509::CRL.new(crl_str)
+ end
+
+ def check_valid(crl, ca)
+ unless crl.verify(ca.public_key)
+ return false
+ end
+ crl.last_update <= Time.now
+ end
+
+ RE_CDP = /\AcrlDistributionPoints\z/
+ def get_cdp(cert)
+ if cdp_ext = cert.extensions.find { |ext| RE_CDP =~ ext.oid }
+ cdp_ext.value.chomp
+ else
+ false
+ end
+ end
+
+ def renew_crl(cert, ca)
+ if cdp = get_cdp(cert)
+ if new_crl_str = fetch(cdp)
+ new_crl = load_crl_str(new_crl_str)
+ if check_valid(new_crl, ca)
+ return new_crl
+ end
+ end
+ end
+ false
+ end
+end
+
+if $0 == __FILE__
+ dir = "trust_certs"
+ c_store = CHashDir.new(dir)
+ s = CrlStore.new(c_store)
+ c = OpenSSL::X509::Certificate.new(File.read("cert_store/google_codesign.pem"))
+ p s.find_crl(c)
+end
diff --git a/jni/ruby/sample/openssl/echo_cli.rb b/jni/ruby/sample/openssl/echo_cli.rb
new file mode 100644
index 0000000..069a21e
--- /dev/null
+++ b/jni/ruby/sample/openssl/echo_cli.rb
@@ -0,0 +1,44 @@
+#!/usr/bin/env ruby
+
+require 'socket'
+require 'openssl'
+require 'optparse'
+
+options = ARGV.getopts("p:c:k:C:")
+
+host = ARGV[0] || "localhost"
+port = options["p"] || "2000"
+cert_file = options["c"]
+key_file = options["k"]
+ca_path = options["C"]
+
+ctx = OpenSSL::SSL::SSLContext.new()
+if cert_file && key_file
+ ctx.cert = OpenSSL::X509::Certificate.new(File::read(cert_file))
+ ctx.key = OpenSSL::PKey::RSA.new(File::read(key_file))
+end
+if ca_path
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ ctx.ca_path = ca_path
+else
+ $stderr.puts "!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!"
+end
+
+s = TCPSocket.new(host, port)
+ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
+ssl.connect # start SSL session
+p ssl.peer_cert
+errors = Hash.new
+OpenSSL::X509.constants.grep(/^V_(ERR_|OK)/).each do |name|
+ errors[OpenSSL::X509.const_get(name)] = name
+end
+p errors[ssl.verify_result]
+
+ssl.sync_close = true # if true the underlying socket will be
+ # closed in SSLSocket#close. (default: false)
+while line = $stdin.gets
+ ssl.write line
+ puts ssl.gets.inspect
+end
+
+ssl.close
diff --git a/jni/ruby/sample/openssl/echo_svr.rb b/jni/ruby/sample/openssl/echo_svr.rb
new file mode 100644
index 0000000..719de6b
--- /dev/null
+++ b/jni/ruby/sample/openssl/echo_svr.rb
@@ -0,0 +1,65 @@
+#!/usr/bin/env ruby
+
+require 'socket'
+require 'openssl'
+require 'optparse'
+
+options = ARGV.getopts("p:c:k:C:")
+
+port = options["p"] || "2000"
+cert_file = options["c"]
+key_file = options["k"]
+ca_path = options["C"]
+
+if cert_file && key_file
+ cert = OpenSSL::X509::Certificate.new(File::read(cert_file))
+ key = OpenSSL::PKey::RSA.new(File::read(key_file))
+else
+ key = OpenSSL::PKey::RSA.new(512){ print "." }
+ puts
+ cert = OpenSSL::X509::Certificate.new
+ cert.version = 2
+ cert.serial = 0
+ name = OpenSSL::X509::Name.new([["C","JP"],["O","TEST"],["CN","localhost"]])
+ cert.subject = name
+ cert.issuer = name
+ cert.not_before = Time.now
+ cert.not_after = Time.now + 3600
+ cert.public_key = key.public_key
+ ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
+ cert.extensions = [
+ ef.create_extension("basicConstraints","CA:FALSE"),
+ ef.create_extension("subjectKeyIdentifier","hash"),
+ ef.create_extension("extendedKeyUsage","serverAuth"),
+ ef.create_extension("keyUsage",
+ "keyEncipherment,dataEncipherment,digitalSignature")
+ ]
+ ef.issuer_certificate = cert
+ cert.add_extension ef.create_extension("authorityKeyIdentifier",
+ "keyid:always,issuer:always")
+ cert.sign(key, OpenSSL::Digest::SHA1.new)
+end
+
+ctx = OpenSSL::SSL::SSLContext.new()
+ctx.key = key
+ctx.cert = cert
+if ca_path
+ ctx.verify_mode =
+ OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
+ ctx.ca_path = ca_path
+else
+ $stderr.puts "!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!"
+end
+
+tcps = TCPServer.new(port)
+ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
+loop do
+ ns = ssls.accept
+ puts "connected from #{ns.peeraddr}"
+ while line = ns.gets
+ puts line.inspect
+ ns.write line
+ end
+ puts "connection closed"
+ ns.close
+end
diff --git a/jni/ruby/sample/openssl/gen_csr.rb b/jni/ruby/sample/openssl/gen_csr.rb
new file mode 100644
index 0000000..4228707
--- /dev/null
+++ b/jni/ruby/sample/openssl/gen_csr.rb
@@ -0,0 +1,51 @@
+#!/usr/bin/env ruby
+
+require 'optparse'
+require 'openssl'
+
+include OpenSSL
+
+def usage
+ myname = File::basename($0)
+ $stderr.puts <<EOS
+Usage: #{myname} [--key keypair_file] name
+ name ... ex. /C=JP/O=RRR/OU=CA/CN=NaHi/emailAddress=nahi@example.org
+EOS
+ exit
+end
+
+options = ARGV.getopts(nil, "key:", "csrout:", "keyout:")
+keypair_file = options["key"]
+csrout = options["csrout"] || "csr.pem"
+keyout = options["keyout"] || "keypair.pem"
+
+$stdout.sync = true
+name_str = ARGV.shift or usage()
+name = X509::Name.parse(name_str)
+
+keypair = nil
+if keypair_file
+ keypair = PKey::RSA.new(File.open(keypair_file).read)
+else
+ keypair = PKey::RSA.new(1024) { putc "." }
+ puts
+ puts "Writing #{keyout}..."
+ File.open(keyout, "w", 0400) do |f|
+ f << keypair.to_pem
+ end
+end
+
+puts "Generating CSR for #{name_str}"
+
+req = X509::Request.new
+req.version = 0
+req.subject = name
+req.public_key = keypair.public_key
+req.sign(keypair, Digest::MD5.new)
+
+puts "Writing #{csrout}..."
+File.open(csrout, "w") do |f|
+ f << req.to_pem
+end
+puts req.to_text
+puts req.to_pem
diff --git a/jni/ruby/sample/openssl/smime_read.rb b/jni/ruby/sample/openssl/smime_read.rb
new file mode 100644
index 0000000..17394f9
--- /dev/null
+++ b/jni/ruby/sample/openssl/smime_read.rb
@@ -0,0 +1,23 @@
+require 'optparse'
+require 'openssl'
+include OpenSSL
+
+options = ARGV.getopts("c:k:C:")
+
+cert_file = options["c"]
+key_file = options["k"]
+ca_path = options["C"]
+
+data = $stdin.read
+
+cert = X509::Certificate.new(File::read(cert_file))
+key = PKey::RSA.new(File::read(key_file))
+p7enc = PKCS7::read_smime(data)
+data = p7enc.decrypt(key, cert)
+
+store = X509::Store.new
+store.add_path(ca_path)
+p7sig = PKCS7::read_smime(data)
+if p7sig.verify([], store)
+ puts p7sig.data
+end
diff --git a/jni/ruby/sample/openssl/smime_write.rb b/jni/ruby/sample/openssl/smime_write.rb
new file mode 100644
index 0000000..5a5236c
--- /dev/null
+++ b/jni/ruby/sample/openssl/smime_write.rb
@@ -0,0 +1,23 @@
+require 'openssl'
+require 'optparse'
+include OpenSSL
+
+options = ARGV.getopts("c:k:r:")
+
+cert_file = options["c"]
+key_file = options["k"]
+rcpt_file = options["r"]
+
+cert = X509::Certificate.new(File::read(cert_file))
+key = PKey::RSA.new(File::read(key_file))
+
+data = "Content-Type: text/plain\r\n"
+data << "\r\n"
+data << "This is a clear-signed message.\r\n"
+
+p7sig = PKCS7::sign(cert, key, data, [], PKCS7::DETACHED)
+smime0 = PKCS7::write_smime(p7sig)
+
+rcpt = X509::Certificate.new(File::read(rcpt_file))
+p7enc = PKCS7::encrypt([rcpt], smime0)
+print PKCS7::write_smime(p7enc)
diff --git a/jni/ruby/sample/openssl/wget.rb b/jni/ruby/sample/openssl/wget.rb
new file mode 100644
index 0000000..ee63720
--- /dev/null
+++ b/jni/ruby/sample/openssl/wget.rb
@@ -0,0 +1,34 @@
+#!/usr/bin/env ruby
+
+require 'net/https'
+require 'optparse'
+
+options = ARGV.getopts('C:')
+
+cert_store = options["C"]
+
+uri = URI.parse(ARGV[0])
+if proxy = ENV['HTTP_PROXY']
+ prx_uri = URI.parse(proxy)
+ prx_host = prx_uri.host
+ prx_port = prx_uri.port
+end
+
+h = Net::HTTP.new(uri.host, uri.port, prx_host, prx_port)
+h.set_debug_output($stderr) if $DEBUG
+if uri.scheme == "https"
+ h.use_ssl = true
+ if cert_store
+ if File.directory?(cert_store)
+ h.ca_path = cert_store
+ else
+ h.ca_file = cert_store
+ end
+ end
+end
+
+path = uri.path.empty? ? "/" : uri.path
+h.get2(path){|resp|
+ STDERR.puts h.peer_cert.inspect if h.peer_cert
+ print resp.body
+}
diff --git a/jni/ruby/sample/optparse/opttest.rb b/jni/ruby/sample/optparse/opttest.rb
new file mode 100755
index 0000000..b2013c5
--- /dev/null
+++ b/jni/ruby/sample/optparse/opttest.rb
@@ -0,0 +1,125 @@
+#!/usr/bin/ruby -I.
+
+require 'optparse'
+require 'optparse/time'
+require 'pp'
+
+# keywords
+CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
+CODE_ALIASES = {"jis" => "iso-2022-jp", "sjis" => "shift_jis"}
+POSSIBLE_CODES = "(#{(CODES+CODE_ALIASES.keys).join(',')})"
+
+ARGV.options do
+ |opts|
+ opts.banner << " argv..."
+
+ # separator
+ opts.on_tail
+ opts.on_tail("common options:")
+
+ # no argument, shows at tail
+ opts.on_tail("--help", "show this message") do
+ puts opts
+ exit
+ end
+
+ # mandatory argument
+ opts.on("-r", "--require=LIBRARY", String,
+ "require the LIBRARY, before",
+ "executing your script") do
+ |lib|
+ @library = lib
+ end
+
+ # optional argument
+ opts.on("-i", "--inplace=[EXTENSION]",
+ "edit ARGV files in place", # multiline description
+ "(make backup if EXTENSION supplied)") do
+ |inplace|
+ @inplace = inplace || ''
+ end
+
+ opts.on("-N=[NUM]", Integer) do
+ |num|
+ @number = num
+ end
+
+ # additional class
+ opts.on("-t", "--[no-]time[=TIME]", Time, "it's the time") do
+ |time|
+ @time = time
+ end
+
+ # limit argument syntax
+ opts.on("-[0-7]", "-F", "--irs=[OCTAL]", OptionParser::OctalInteger,
+ "specify record separator", "(\\0, if no argument)") do
+ |irs|
+ @irs = irs
+ end
+
+ # boolean switch(default true)
+ @exec = true
+ opts.on("-n", "--no-exec[=FLAG]", TrueClass, "not really execute") do
+ |exec|
+ @exec = exec
+ end
+
+ # array
+ opts.on("-a", "--list[=LIST,LIST]", Array, "list") do
+ |list|
+ @list = list
+ end
+
+ # fixed size array
+ opts.on("--pair[=car,cdr]", Array, "pair") do
+ |x, y|
+ @x = x
+ @y = y
+ end
+
+ # keyword completion
+ opts.on("--code=CODE", CODES, CODE_ALIASES, "select coding system",
+ "("+CODES.join(",")+",", " "+CODE_ALIASES.keys.join(",")+")") do
+ |c|
+ @code = c
+ end
+
+ # optional argument with keyword completion
+ opts.on("--type[=TYPE]", [:text, :binary], "select type(text, binary)") do
+ |t|
+ @type = t
+ end
+
+ # boolean switch with optional argument(default false)
+ opts.on("-v", "--[no-]verbose=[FLAG]", "run verbosely") do
+ |v|
+ @verbose = v
+ end
+
+ # easy way, set local variable
+ opts.on("-q", "--quit", "quit when ARGV is empty") do
+ |q|
+ @quit = q
+ end
+
+ # adding on the fly
+ opts.on("--add=SWITCH=[ARG]", "add option on the fly", /\A(\w+)(?:=.+)?\Z/) do
+ |opt, var|
+ opts.on("--#{opt}", "added in runtime", &eval("proc {|x|@#{var}=x}"))
+ end
+
+ opts.on_head("specific options:")
+
+ # no argument
+ opts.on_tail("--version", "show version") do
+ puts OptionParser::Version.join('.')
+ exit
+ end
+ opts.parse!
+end
+
+pp self
+begin print ARGV.options; exit end if @quit
+ARGV.options = nil # no more parse
+puts "ARGV = #{ARGV.join(' ')}" if !ARGV.empty?
+#opts.variable.each {|sym| puts "#{sym} = #{opts.send(sym).inspect}"}
diff --git a/jni/ruby/sample/optparse/subcommand.rb b/jni/ruby/sample/optparse/subcommand.rb
new file mode 100755
index 0000000..21c42dd
--- /dev/null
+++ b/jni/ruby/sample/optparse/subcommand.rb
@@ -0,0 +1,19 @@
+#! /usr/bin/ruby
+# contributed by Minero Aoki.
+
+require 'optparse'
+
+parser = OptionParser.new
+parser.on('-i') { puts "-i" }
+parser.on('-o') { puts '-o' }
+
+subparsers = Hash.new {|h,k|
+ $stderr.puts "no such subcommand: #{k}"
+ exit 1
+}
+subparsers['add'] = OptionParser.new.on('-i') { puts "add -i" }
+subparsers['del'] = OptionParser.new.on('-i') { puts "del -i" }
+subparsers['list'] = OptionParser.new.on('-i') { puts "list -i" }
+
+parser.order!(ARGV)
+subparsers[ARGV.shift].parse!(ARGV) unless ARGV.empty?
diff --git a/jni/ruby/sample/philos.rb b/jni/ruby/sample/philos.rb
new file mode 100644
index 0000000..5c8f43c
--- /dev/null
+++ b/jni/ruby/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 n in 0..N-1
+ Thread.start(n){|i| philosopher(i)}
+ sleep 0.1
+end
+
+sleep
diff --git a/jni/ruby/sample/pi.rb b/jni/ruby/sample/pi.rb
new file mode 100644
index 0000000..63be974
--- /dev/null
+++ b/jni/ruby/sample/pi.rb
@@ -0,0 +1,18 @@
+#!/usr/local/bin/ruby
+
+k, a, b, a1, b1 = 2, 4, 1, 12, 4
+
+loop do
+ # 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/jni/ruby/sample/pstore.rb b/jni/ruby/sample/pstore.rb
new file mode 100644
index 0000000..38c2305
--- /dev/null
+++ b/jni/ruby/sample/pstore.rb
@@ -0,0 +1,19 @@
+require 'pstore'
+
+db = PStore.new("/tmp/foo")
+db.transaction do
+ p db.roots
+ ary = db["root"] = [1,2,3,4]
+ ary[1] = [1,1.5]
+end
+
+1000.times do
+ db.transaction do
+ db["root"][0] += 1
+ p db["root"][0]
+ end
+end
+
+db.transaction(true) do
+ p db["root"]
+end
diff --git a/jni/ruby/sample/pty/expect_sample.rb b/jni/ruby/sample/pty/expect_sample.rb
new file mode 100644
index 0000000..2f87f21
--- /dev/null
+++ b/jni/ruby/sample/pty/expect_sample.rb
@@ -0,0 +1,48 @@
+#
+# sample program of expect.rb
+#
+# by A. Ito
+#
+# This program reports the latest version of Ruby interpreter
+# by connecting to ftp server at ruby-lang.org.
+#
+require 'pty'
+require 'expect'
+
+fnames = []
+PTY.spawn("ftp ftp.ruby-lang.org") do |r_f,w_f,pid|
+ w_f.sync = true
+
+ $expect_verbose = false
+
+ if !ENV['USER'].nil?
+ username = ENV['USER']
+ elsif !ENV['LOGNAME'].nil?
+ username = ENV['LOGNAME']
+ else
+ username = 'guest'
+ end
+
+ r_f.expect(/^(Name).*: |(word):|> /) do
+ w_f.puts($1 ? "ftp" : $2 ? "#{username}@" : "cd pub/ruby")
+ end
+ r_f.expect("> ") do
+ w_f.print "dir\n"
+ end
+
+ r_f.expect(/[^\-]> /) do |output|
+ for x in output[0].split("\n")
+ if x =~ /(ruby.*?\.tar\.gz)/ then
+ fnames.push $1
+ end
+ end
+ end
+ begin
+ w_f.print "quit\n"
+ rescue
+ end
+end
+
+print "The latest ruby interpreter is "
+print fnames.sort.pop
+print "\n"
diff --git a/jni/ruby/sample/pty/script.rb b/jni/ruby/sample/pty/script.rb
new file mode 100644
index 0000000..903a6f7
--- /dev/null
+++ b/jni/ruby/sample/pty/script.rb
@@ -0,0 +1,37 @@
+require 'pty'
+
+if ARGV.size == 0 then
+ ofile = "typescript"
+else
+ ofile = ARGV[0]
+end
+
+logfile = File.open(ofile,"a")
+
+system "stty -echo raw lnext ^_"
+
+PTY.spawn("/bin/csh") do |r_pty,w_pty,pid|
+
+ Thread.new do
+ while true
+ w_pty.print STDIN.getc.chr
+ w_pty.flush
+ end
+ end
+
+ begin
+ while true
+ c = r_pty.sysread(512)
+ break if c.nil?
+ print c
+ STDOUT.flush
+ logfile.print c
+ end
+ rescue
+ # print $@,':',$!,"\n"
+ logfile.close
+ end
+end
+
+system "stty echo -raw lnext ^v"
+
diff --git a/jni/ruby/sample/pty/shl.rb b/jni/ruby/sample/pty/shl.rb
new file mode 100644
index 0000000..cdaf8d7
--- /dev/null
+++ b/jni/ruby/sample/pty/shl.rb
@@ -0,0 +1,92 @@
+#
+# old-fashioned 'shl' like program
+# by A. Ito
+#
+# commands:
+# c creates new shell
+# C-z suspends shell
+# p lists all shell
+# 0,1,... choose shell
+# q quit
+
+require 'pty'
+
+$shells = []
+$n_shells = 0
+
+$r_pty = nil
+$w_pty = nil
+
+def writer
+ system "stty -echo raw"
+ begin
+ while true
+ c = STDIN.getc
+ if c == 26 then # C-z
+ $reader.raise(nil)
+ return 'Suspend'
+ end
+ $w_pty.print c.chr
+ $w_pty.flush
+ end
+ rescue
+ $reader.raise(nil)
+ return 'Exit'
+ ensure
+ system "stty echo -raw"
+ end
+end
+
+$reader = Thread.new {
+ while true
+ begin
+ next if $r_pty.nil?
+ c = $r_pty.getc
+ if c.nil? then
+ Thread.stop
+ end
+ print c.chr
+ STDOUT.flush
+ rescue
+ Thread.stop
+ end
+ end
+}
+
+# $reader.raise(nil)
+
+
+while true
+ print ">> "
+ STDOUT.flush
+ case gets
+ when /^c/i
+ $shells[$n_shells] = PTY.spawn("/bin/csh")
+ $r_pty,$w_pty = $shells[$n_shells]
+ $n_shells += 1
+ $reader.run
+ if writer == 'Exit'
+ $n_shells -= 1
+ $shells[$n_shells] = nil
+ end
+ when /^p/i
+ for i in 0..$n_shells
+ unless $shells[i].nil?
+ print i,"\n"
+ end
+ end
+ when /^([0-9]+)/
+ n = $1.to_i
+ if $shells[n].nil?
+ print "\##{i} doesn't exist\n"
+ else
+ $r_pty,$w_pty = $shells[n]
+ $reader.run
+ if writer == 'Exit' then
+ $shells[n] = nil
+ end
+ end
+ when /^q/i
+ exit
+ end
+end
diff --git a/jni/ruby/sample/rcs.awk b/jni/ruby/sample/rcs.awk
new file mode 100644
index 0000000..e64af5b
--- /dev/null
+++ b/jni/ruby/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/jni/ruby/sample/rcs.dat b/jni/ruby/sample/rcs.dat
new file mode 100644
index 0000000..61c88bf
--- /dev/null
+++ b/jni/ruby/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/jni/ruby/sample/rcs.rb b/jni/ruby/sample/rcs.rb
new file mode 100644
index 0000000..0bdf81c
--- /dev/null
+++ b/jni/ruby/sample/rcs.rb
@@ -0,0 +1,39 @@
+# random dot steraogram
+# usage: rcs.rb rcs.dat
+
+sw = 40.0 # width of original pattern
+dw = 78.0 # width of generating Random Character Streogram
+hdw = dw / 2.0
+w = 20.0 # distance between eyes
+h =1.0 # distance from screen and base plane
+d = 0.2 # z value unit
+ss="abcdefghijklmnopqrstuvwxyz0123456789#!$%^&*()-=\\[];'`,./"
+rnd = srand() # You don't actually need this in ruby - srand() is called
+ # on the first call of rand().
+
+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/jni/ruby/sample/rdoc/markup/rdoc2latex.rb b/jni/ruby/sample/rdoc/markup/rdoc2latex.rb
new file mode 100644
index 0000000..aa8079e
--- /dev/null
+++ b/jni/ruby/sample/rdoc/markup/rdoc2latex.rb
@@ -0,0 +1,15 @@
+#!/usr/local/bin/ruby
+# Illustration of a script to convert an RDoc-style file to a LaTeX document
+
+require 'rdoc/markup'
+require 'rdoc/markup/to_latex'
+
+p = RDoc::Markup.new
+h = RDoc::Markup::ToLaTeX.new
+
+#puts "\\documentclass{report}"
+#puts "\\usepackage{tabularx}"
+#puts "\\usepackage{parskip}"
+#puts "\\begin{document}"
+puts p.convert(ARGF.read, h)
+#puts "\\end{document}"
diff --git a/jni/ruby/sample/rdoc/markup/sample.rb b/jni/ruby/sample/rdoc/markup/sample.rb
new file mode 100644
index 0000000..db5d88d
--- /dev/null
+++ b/jni/ruby/sample/rdoc/markup/sample.rb
@@ -0,0 +1,40 @@
+# This program illustrates the basic use of the SimpleMarkup
+# class. It extracts the first comment block from the
+# simple_markup.rb file and converts it into HTML on
+# standard output. Run it using
+#
+# % ruby sample.rb
+#
+# You should be in the sample/rdoc/markup/ directory when you do this,
+# as it hardwires the path to the files it needs to require.
+# This isn't necessary in the code you write once you've
+# installed the package.
+#
+# For a better way of formatting code comment blocks (and more)
+# see the rdoc package.
+#
+
+require 'rdoc/markup/simple_markup'
+require 'rdoc/markup/simple_markup/to_html'
+
+# Extract the comment block from the source file
+
+input_string = ""
+
+File.foreach("../../../lib/rdoc/markup/simple_markup.rb") do |line|
+ break unless line.gsub!(/^\# ?/, '')
+ input_string << line
+end
+
+# Create a markup object
+markup = SM::SimpleMarkup.new
+
+# Attach it to an HTML formatter
+h = SM::ToHtml.new
+
+# And convert out comment block to html. Wrap it a body
+# tag pair to let browsers view it
+
+puts "<html><body>"
+puts markup.convert(input_string, h)
+puts "</body></html>"
diff --git a/jni/ruby/sample/rinda-ring.rb b/jni/ruby/sample/rinda-ring.rb
new file mode 100644
index 0000000..f9bd934
--- /dev/null
+++ b/jni/ruby/sample/rinda-ring.rb
@@ -0,0 +1,22 @@
+require 'rinda/ring'
+
+DRb.start_service
+case ARGV.shift
+when 's'
+ require 'rinda/tuplespace'
+ ts = Rinda::TupleSpace.new
+ Rinda::RingServer.new(ts)
+ $stdin.gets
+when 'w'
+ finger = Rinda::RingFinger.new(nil)
+ finger.lookup_ring do |ts2|
+ p ts2
+ ts2.write([:hello, :world])
+ end
+when 'r'
+ finger = Rinda::RingFinger.new(nil)
+ finger.lookup_ring do |ts2|
+ p ts2
+ p ts2.take([nil, nil])
+ end
+end
diff --git a/jni/ruby/sample/ripper/ruby2html.rb b/jni/ruby/sample/ripper/ruby2html.rb
new file mode 100644
index 0000000..8f64f5a
--- /dev/null
+++ b/jni/ruby/sample/ripper/ruby2html.rb
@@ -0,0 +1,112 @@
+#!/usr/bin/env ruby
+# $originalId: ruby2html.rb,v 1.2 2005/09/23 22:53:47 aamine Exp $
+
+TEMPLATE_LINE = __LINE__ + 2
+TEMPLATE = <<-EndTemplate
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=<%= encoding %>">
+<% if css %>
+ <link rel="stylesheet" type="text/css" href="<%= css %>">
+<% end %>
+ <title><%= File.basename(f.path) %></title>
+</head>
+<body>
+<pre>
+<%
+ if print_line_number
+ Ruby2HTML.compile(f).each_with_index do |line, idx|
+%><%= sprintf('%4d %s', idx+1, line) %><%
+ end
+ else
+%><%= Ruby2HTML.compile(f) %><%
+ end
+%>
+</pre>
+</body>
+</html>
+EndTemplate
+
+require 'ripper'
+require 'stringio'
+require 'cgi'
+require 'erb'
+require 'optparse'
+
+def main
+ encoding = 'us-ascii'
+ css = nil
+ print_line_number = false
+ parser = OptionParser.new
+ parser.banner = "Usage: #{File.basename($0)} [-l] [<file>...]"
+ parser.on('--encoding=NAME', 'Character encoding [us-ascii].') {|name|
+ encoding = name
+ }
+ parser.on('--css=URL', 'Set a link to CSS.') {|url|
+ css = url
+ }
+ parser.on('-l', '--line-number', 'Show line number.') {
+ print_line_number = true
+ }
+ parser.on('--help', 'Prints this message and quit.') {
+ puts parser.help
+ exit 0
+ }
+ begin
+ parser.parse!
+ rescue OptionParser::ParseError => err
+ $stderr.puts err
+ $stderr.puts parser.help
+ exit 1
+ end
+ puts ruby2html(ARGF, encoding, css, print_line_number)
+end
+
+class ERB
+ attr_accessor :lineno
+
+ remove_method :result
+ def result(b)
+ eval(@src, b, (@filename || '(erb)'), (@lineno || 1))
+ end
+end
+
+def ruby2html(f, encoding, css, print_line_number)
+ erb = ERB.new(TEMPLATE, nil, '>')
+ erb.filename = __FILE__
+ erb.lineno = TEMPLATE_LINE
+ erb.result(binding())
+end
+
+class Ruby2HTML < Ripper::Filter
+ def Ruby2HTML.compile(f)
+ buf = StringIO.new
+ Ruby2HTML.new(f).parse(buf)
+ buf.string
+ end
+
+ def on_default(event, tok, f)
+ f << CGI.escapeHTML(tok)
+ end
+
+ def on_kw(tok, f)
+ f << %Q[<span class="resword">#{CGI.escapeHTML(tok)}</span>]
+ end
+
+ def on_comment(tok, f)
+ f << %Q[<span class="comment">#{CGI.escapeHTML(tok.rstrip)}</span>\n]
+ end
+
+ def on_tstring_beg(tok, f)
+ f << %Q[<span class="string">#{CGI.escapeHTML(tok)}]
+ end
+
+ def on_tstring_end(tok, f)
+ f << %Q[#{CGI.escapeHTML(tok)}</span>]
+ end
+end
+
+if $0 == __FILE__
+ main
+end
diff --git a/jni/ruby/sample/ripper/strip-comment.rb b/jni/ruby/sample/ripper/strip-comment.rb
new file mode 100644
index 0000000..1023875
--- /dev/null
+++ b/jni/ruby/sample/ripper/strip-comment.rb
@@ -0,0 +1,19 @@
+# $Id: strip-comment.rb 25189 2009-10-02 12:04:37Z akr $
+
+require 'ripper/filter'
+
+class CommentStripper < Ripper::Filter
+ def CommentStripper.strip(src)
+ new(src).parse(nil)
+ end
+
+ def on_default(event, token, data)
+ print token
+ end
+
+ def on_comment(token, data)
+ puts
+ end
+end
+
+CommentStripper.strip(ARGF)
diff --git a/jni/ruby/sample/rss/blend.rb b/jni/ruby/sample/rss/blend.rb
new file mode 100755
index 0000000..351f6f3
--- /dev/null
+++ b/jni/ruby/sample/rss/blend.rb
@@ -0,0 +1,79 @@
+#!/usr/bin/env ruby
+
+require "rss"
+
+feeds = []
+verbose = false
+encoding = "UTF-8"
+
+def error(exception)
+ mark = "=" * 20
+ mark = "#{mark} error #{mark}"
+ STDERR.puts mark
+ STDERR.puts exception.class
+ STDERR.puts exception.message
+ STDERR.puts exception.backtrace
+ STDERR.puts mark
+end
+
+before_time = Time.now
+ARGV.each do |fname|
+ if fname == '-v'
+ verbose = true
+ next
+ end
+ rss = nil
+ f = File.new(fname).read
+ begin
+ ## do validate parse
+ rss = RSS::Parser.parse(f)
+ rescue RSS::InvalidRSSError
+ error($!) if verbose
+ ## do non validate parse for invalid RSS 1.0
+ begin
+ rss = RSS::Parser.parse(f, false)
+ rescue RSS::Error
+ ## invalid RSS.
+ error($!) if verbose
+ end
+ rescue RSS::Error
+ error($!) if verbose
+ end
+ if rss.nil?
+ STDERR.puts "#{fname} does not include RSS 1.0 or 0.9x/2.0"
+ else
+ begin
+ rss.output_encoding = encoding
+ rescue RSS::UnknownConversionMethodError
+ error($!) if verbose
+ end
+ feeds << rss
+ end
+end
+processing_time = Time.now - before_time
+
+rss = RSS::Maker.make("1.0") do |maker|
+ maker.encoding = encoding
+ maker.channel.about = "http://example.com/blend.rdf"
+ maker.channel.title = "blended feeds"
+ maker.channel.link = "http://example.com/"
+ maker.channel.description = "blended feeds generated by RSS Parser"
+
+ feeds.each do |feed|
+ feed.items.each do |item|
+ item.setup_maker(maker.items)
+ end
+ end
+
+ maker.items.each do |item|
+ item.title ||= "UNKNOWN"
+ item.link ||= "UNKNOWN"
+ end
+
+ maker.items.do_sort = true
+ maker.items.max_size = 15
+end
+puts rss
+
+STDERR.puts "Used XML parser: #{RSS::Parser.default_parser}"
+STDERR.puts "Processing time: #{processing_time}s"
diff --git a/jni/ruby/sample/rss/convert.rb b/jni/ruby/sample/rss/convert.rb
new file mode 100755
index 0000000..e6bff4c
--- /dev/null
+++ b/jni/ruby/sample/rss/convert.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby
+
+require "rss"
+
+feeds = []
+verbose = false
+encoding = "UTF-8"
+to_version = "1.0"
+
+def error(exception)
+ mark = "=" * 20
+ mark = "#{mark} error #{mark}"
+ STDERR.puts mark
+ STDERR.puts exception.class
+ STDERR.puts exception.message
+ STDERR.puts exception.backtrace
+ STDERR.puts mark
+end
+
+before_time = Time.now
+ARGV.each do |fname|
+ case fname
+ when '-v'
+ verbose = true
+ next
+ when /^-t(0\.91|1\.0|2\.0|atom)$/
+ to_version = $1
+ next
+ end
+ rss = nil
+ f = File.read(fname)
+ begin
+ ## do validate parse
+ rss = RSS::Parser.parse(f)
+ rescue RSS::InvalidRSSError
+ error($!) if verbose
+ ## do non validate parse for invalid RSS 1.0
+ begin
+ rss = RSS::Parser.parse(f, false)
+ rescue RSS::Error
+ ## invalid RSS.
+ error($!) if verbose
+ end
+ rescue RSS::Error
+ error($!) if verbose
+ end
+ if rss.nil?
+ STDERR.puts "#{fname} does not include RSS 1.0 or 0.9x/2.0"
+ else
+ begin
+ rss.output_encoding = encoding
+ rescue RSS::UnknownConversionMethodError
+ error($!) if verbose
+ end
+ feeds << [fname, rss]
+ end
+end
+processing_time = Time.now - before_time
+
+feeds.each do |fname, rss|
+ converted_rss = rss.to_xml(to_version)
+ output_name = fname.sub(/(\.[^\.]+)$/, "-#{to_version}\\1")
+ File.open(output_name, "w") do |output|
+ output.print(converted_rss)
+ end
+end
+
+STDERR.puts "Used XML parser: #{RSS::Parser.default_parser}"
+STDERR.puts "Processing time: #{processing_time}s"
diff --git a/jni/ruby/sample/rss/list_description.rb b/jni/ruby/sample/rss/list_description.rb
new file mode 100755
index 0000000..990974d
--- /dev/null
+++ b/jni/ruby/sample/rss/list_description.rb
@@ -0,0 +1,91 @@
+#!/usr/bin/env ruby
+
+require "nkf"
+class String
+ # From tdiary.rb
+ def shorten( len = 120 )
+ lines = NKF::nkf( "-t -m0 -f#{len}", self.gsub( /\n/, ' ' ) ).split( /\n/ )
+ lines[0].concat( '...' ) if lines[0] and lines[1]
+ lines[0]
+ end
+end
+
+require "rss"
+
+channels = {}
+verbose = false
+
+def error(exception)
+ mark = "=" * 20
+ mark = "#{mark} error #{mark}"
+ puts mark
+ puts exception.class
+ puts exception.message
+ puts exception.backtrace
+ puts mark
+end
+
+before_time = Time.now
+ARGV.each do |fname|
+ if fname == '-v'
+ verbose = true
+ next
+ end
+ rss = nil
+ f = File.new(fname).read
+ begin
+ ## do validate parse
+ rss = RSS::Parser.parse(f)
+ rescue RSS::InvalidRSSError
+ error($!) if verbose
+ ## do non validate parse for invalid RSS 1.0
+ begin
+ rss = RSS::Parser.parse(f, false)
+ rescue RSS::Error
+ ## invalid RSS.
+ error($!) if verbose
+ end
+ rescue RSS::Error
+ error($!) if verbose
+ end
+ if rss.nil?
+ puts "#{fname} does not include RSS 1.0 or 0.9x/2.0"
+ else
+ begin
+ rss.output_encoding = "utf-8"
+ rescue RSS::UnknownConversionMethodError
+ error($!) if verbose
+ end
+
+ rss = rss.to_rss("1.0") do |maker|
+ maker.channel.about ||= maker.channel.link
+ maker.channel.description ||= "No description"
+ maker.items.each do |item|
+ item.title ||= "No title"
+ item.link ||= "UNKNOWN"
+ end
+ end
+ next if rss.nil?
+
+ rss.items.each do |item|
+ channels[rss.channel.title] ||= []
+ channels[rss.channel.title] << item if item.description
+ end
+ end
+end
+processing_time = Time.now - before_time
+
+channels.sort do |x, y|
+ x[0] <=> y[0]
+end[0..20].each do |title, items|
+ puts "Channel: #{title}" unless items.empty?
+ items.sort do |x, y|
+ x.title <=> y.title
+ end[0..10].each do |item|
+ puts " Item: #{item.title.shorten(50)}"
+ puts " Description: #{item.description.shorten(50)}"
+ end
+end
+
+puts "Used XML parser: #{RSS::Parser.default_parser}"
+puts "Processing time: #{processing_time}s"
diff --git a/jni/ruby/sample/rss/re_read.rb b/jni/ruby/sample/rss/re_read.rb
new file mode 100755
index 0000000..c386ab2
--- /dev/null
+++ b/jni/ruby/sample/rss/re_read.rb
@@ -0,0 +1,64 @@
+#!/usr/bin/env ruby
+
+require "rss"
+
+def error(exception)
+ mark = "=" * 20
+ mark = "#{mark} error #{mark}"
+ puts mark
+ puts exception.class
+ puts exception.message
+ puts exception.backtrace
+ puts mark
+end
+
+verbose = false
+before_time = Time.now
+
+ARGV.each do |fname|
+ if fname == '-v'
+ verbose = true
+ next
+ end
+ source = nil
+ File.open(fname) do |f|
+ source = f.read
+ end
+
+ rss = nil
+ read = false
+ begin
+ rss = RSS::Parser.parse(source)
+ puts "Re-read valid feed: #{fname}"
+ RSS::Parser.parse(rss.to_s)
+ read = true
+ rescue RSS::InvalidRSSError
+ error($!) if verbose
+ ## do non validate parse for invalid feed
+ begin
+ rss = RSS::Parser.parse(source, false)
+ rescue RSS::Error
+ ## invalid feed
+ error($!) if verbose
+ end
+ rescue RSS::Error
+ error($!) if verbose
+ end
+
+ if rss.nil?
+ puts "Invalid feed: #{fname}"
+ elsif !read
+ puts "Re-read invalid feed: #{fname}"
+ begin
+ RSS::Parser.parse(rss.to_s)
+ rescue RSS::Error
+ puts " Error occurred: #{fname}"
+ error($!) if verbose
+ end
+ end
+end
+
+processing_time = Time.now - before_time
+
+puts "Used XML parser: #{RSS::Parser.default_parser}"
+puts "Processing time: #{processing_time}s"
diff --git a/jni/ruby/sample/rss/rss_recent.rb b/jni/ruby/sample/rss/rss_recent.rb
new file mode 100755
index 0000000..14c8612
--- /dev/null
+++ b/jni/ruby/sample/rss/rss_recent.rb
@@ -0,0 +1,85 @@
+#!/usr/bin/env ruby
+
+require "nkf"
+class String
+ # From tdiary.rb
+ def shorten( len = 120 )
+ lines = NKF::nkf( "-t -m0 -f#{len}", self.gsub( /\n/, ' ' ) ).split( /\n/ )
+ lines[0].concat( '...' ) if lines[0] and lines[1]
+ lines[0]
+ end
+end
+
+require "rss"
+
+items = []
+verbose = false
+
+def error(exception)
+ mark = "=" * 20
+ mark = "#{mark} error #{mark}"
+ puts mark
+ puts exception.class
+ puts exception.message
+ puts exception.backtrace
+ puts mark
+end
+before_time = Time.now
+ARGV.each do |fname|
+ if fname == '-v'
+ verbose = true
+ next
+ end
+ rss = nil
+ f = File.new(fname).read
+ begin
+ ## do validate parse
+ rss = RSS::Parser.parse(f)
+ rescue RSS::InvalidRSSError
+ error($!) if verbose
+ ## do non validate parse for invalid RSS 1.0
+ begin
+ rss = RSS::Parser.parse(f, false)
+ rescue RSS::Error
+ ## invalid RSS.
+ error($!) if verbose
+ end
+ rescue RSS::Error
+ error($!) if verbose
+ end
+ if rss.nil?
+ puts "#{fname} does not include RSS 1.0 or 0.9x/2.0"
+ else
+ begin
+ rss.output_encoding = "utf-8"
+ rescue RSS::UnknownConversionMethodError
+ error($!) if verbose
+ end
+
+ rss = rss.to_rss("1.0") do |maker|
+ maker.channel.about ||= maker.channel.link
+ maker.channel.description ||= "No description"
+ maker.items.each do |item|
+ item.title ||= "UNKNOWN"
+ item.link ||= "UNKNOWN"
+ end
+ end
+ next if rss.nil?
+
+ rss.items.each do |item|
+ items << [rss.channel, item] if item.dc_date
+ end
+ end
+end
+processing_time = Time.now - before_time
+
+items.sort do |x, y|
+ y[1].dc_date <=> x[1].dc_date
+end[0..20].each do |channel, item|
+ puts "#{item.dc_date.localtime.iso8601}: " <<
+ "#{channel.title}: #{item.title}"
+ puts " Description: #{item.description.shorten(50)}" if item.description
+end
+
+puts "Used XML parser: #{RSS::Parser.default_parser}"
+puts "Processing time: #{processing_time}s"
diff --git a/jni/ruby/sample/sieve.rb b/jni/ruby/sample/sieve.rb
new file mode 100644
index 0000000..e0bb21d
--- /dev/null
+++ b/jni/ruby/sample/sieve.rb
@@ -0,0 +1,14 @@
+# sieve of Eratosthenes
+max = Integer(ARGV.shift || 100)
+sieve = []
+for i in 2 .. max
+ sieve[i] = i
+end
+
+for i in 2 .. Math.sqrt(max)
+ next unless sieve[i]
+ (i*i).step(max, i) do |j|
+ sieve[j] = nil
+ end
+end
+puts sieve.compact.join(", ")
diff --git a/jni/ruby/sample/simple-bench.rb b/jni/ruby/sample/simple-bench.rb
new file mode 100644
index 0000000..607fdbf
--- /dev/null
+++ b/jni/ruby/sample/simple-bench.rb
@@ -0,0 +1,140 @@
+require 'benchmark'
+
+def foo0
+end
+def foo3 a, b, c
+end
+def foo6 a, b, c, d, e, f
+end
+
+def iter0
+ yield
+end
+
+def iter1
+ yield 1
+end
+
+def iter3
+ yield 1, 2, 3
+end
+
+def iter6
+ yield 1, 2, 3, 4, 5, 6
+end
+
+(1..6).each{|i|
+ kws = (1..i).map{|e| "k#{e}: #{e}"}
+ eval %Q{
+ def foo_kw#{i}(#{kws.join(', ')})
+ end
+ }
+
+ kws = (1..i).map{|e| "k#{e}:"}
+ eval %Q{
+ def foo_required_kw#{i}(#{kws.join(', ')})
+ end
+ }
+}
+
+(1..6).each{|i|
+ kws = (1..i).map{|e| "k#{e}: #{e} + 1"}
+ eval %Q{
+ def foo_complex_kw#{i}(#{kws.join(', ')})
+ end
+ }
+}
+
+(1..6).each{|i|
+ kws = (1..i).map{|e| "k#{e}: #{e}"}
+ eval %Q{
+ def iter_kw#{i}
+ yield #{kws.join(', ')}
+ end
+ }
+}
+
+ary1 = [1]
+ary2 = [[1, 2, 3, 4, 5]]
+
+test_methods = %Q{
+ # empty 1
+ # empty 2
+ foo0
+ foo3 1, 2, 3
+ foo6 1, 2, 3, 4, 5, 6
+ foo_kw1
+ foo_kw2
+ foo_kw3
+ foo_kw4
+ foo_kw5
+ foo_kw6
+ foo_kw6 k1: 1
+ foo_kw6 k1: 1, k2: 2
+ foo_kw6 k1: 1, k2: 2, k3: 3
+ foo_kw6 k1: 1, k2: 2, k3: 3, k4: 4
+ foo_kw6 k1: 1, k2: 2, k3: 3, k4: 4, k5: 5
+ foo_kw6 k1: 1, k2: 2, k3: 3, k4: 4, k5: 5, k6: 6
+ foo_required_kw1 k1: 1
+ foo_required_kw2 k1: 1, k2: 2
+ foo_required_kw3 k1: 1, k2: 2, k3: 3
+ foo_required_kw4 k1: 1, k2: 2, k3: 3, k4: 4
+ foo_required_kw5 k1: 1, k2: 2, k3: 3, k4: 4, k5: 5
+ foo_required_kw6 k1: 1, k2: 2, k3: 3, k4: 4, k5: 5, k6: 6
+ foo_complex_kw1
+ foo_complex_kw2
+ foo_complex_kw3
+ foo_complex_kw4
+ foo_complex_kw5
+ foo_complex_kw6
+ foo_complex_kw6 k1: 1
+ foo_complex_kw6 k1: 1, k2: 2
+ foo_complex_kw6 k1: 1, k2: 2, k3: 3
+ foo_complex_kw6 k1: 1, k2: 2, k3: 3, k4: 4
+ foo_complex_kw6 k1: 1, k2: 2, k3: 3, k4: 4, k5: 5
+ foo_complex_kw6 k1: 1, k2: 2, k3: 3, k4: 4, k5: 5, k6: 6
+ iter0{}
+ iter1{}
+ iter1{|a|}
+ iter3{}
+ iter3{|a|}
+ iter3{|a, b, c|}
+ iter6{}
+ iter6{|a|}
+ iter6{|a, b, c, d, e, f, g|}
+ iter0{|k1: nil, k2: nil, k3: nil, k4: nil, k5: nil, k6: nil|}
+ iter_kw1{|k1: nil, k2: nil, k3: nil, k4: nil, k5: nil, k6: nil|}
+ iter_kw2{|k1: nil, k2: nil, k3: nil, k4: nil, k5: nil, k6: nil|}
+ iter_kw3{|k1: nil, k2: nil, k3: nil, k4: nil, k5: nil, k6: nil|}
+ iter_kw4{|k1: nil, k2: nil, k3: nil, k4: nil, k5: nil, k6: nil|}
+ iter_kw5{|k1: nil, k2: nil, k3: nil, k4: nil, k5: nil, k6: nil|}
+ iter_kw6{|k1: nil, k2: nil, k3: nil, k4: nil, k5: nil, k6: nil|}
+ ary1.each{|e|}
+ ary1.each{|e,|}
+ ary1.each{|a, b, c, d, e|}
+ ary2.each{|e|}
+ ary2.each{|e,|}
+ ary2.each{|a, b, c, d, e|}
+}
+
+N = 10_000_000
+
+max_line = test_methods.each_line.max_by{|line| line.strip.size}
+max_size = max_line.strip.size
+
+Benchmark.bm(max_size){|x|
+
+ str = test_methods.each_line.map{|line| line.strip!
+ next if line.empty?
+ %Q{
+ x.report(#{line.dump}){
+ i = 0
+ while i<#{N}
+ #{line}
+ i+=1
+ end
+ }
+ }
+ }.join("\n")
+ eval str
+}
diff --git a/jni/ruby/sample/svr.rb b/jni/ruby/sample/svr.rb
new file mode 100644
index 0000000..eb49ccf
--- /dev/null
+++ b/jni/ruby/sample/svr.rb
@@ -0,0 +1,34 @@
+# socket example - server side
+# usage: ruby svr.rb
+
+# this server might be blocked by an ill-behaved client.
+# see tsvr.rb which is safe from client blocking.
+
+require "socket"
+
+gs = TCPServer.open(0)
+addr = gs.addr
+addr.shift
+printf("server is on %s\n", addr.join(":"))
+socks = [gs]
+
+loop do
+ 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)
+ # single thread gets may block whole service
+ elsif str = s.gets
+ s.write(str)
+ end
+ end
+ end
+end
diff --git a/jni/ruby/sample/tempfile.rb b/jni/ruby/sample/tempfile.rb
new file mode 100644
index 0000000..5a36361
--- /dev/null
+++ b/jni/ruby/sample/tempfile.rb
@@ -0,0 +1,8 @@
+require 'tempfile'
+
+f = Tempfile.new("foo")
+f.print("foo\n")
+f.close
+f.open
+p f.gets # => "foo\n"
+f.close!
diff --git a/jni/ruby/sample/test.rb b/jni/ruby/sample/test.rb
new file mode 100755
index 0000000..d7f80b1
--- /dev/null
+++ b/jni/ruby/sample/test.rb
@@ -0,0 +1,2363 @@
+#! /usr/bin/env ruby
+# -*- coding: us-ascii -*-
+
+$testnum=0
+$ntest=0
+$failed = 0
+class Progress
+ def initialize
+ @color = nil
+ @tty = nil
+ @quiet = nil
+ @verbose = nil
+ ARGV.each do |arg|
+ case arg
+ when /\A--color(?:=(?:always|(auto)|(never)|(.*)))?\z/
+ warn "unknown --color argument: #$3" if $3
+ @color = $1 ? nil : !$2
+ when /\A--tty(=(?:yes|(no)|(.*)))?\z/
+ warn "unknown --tty argument: #$3" if $3
+ @tty = !$1 || !$2
+ true
+ when /\A-(q|-quiet)\z/
+ @quiet = true
+ when /\A-(v|-verbose)\z/
+ @verbose = true
+ end
+ end
+ @tty = STDERR.tty? && !STDOUT.tty? && /dumb/ !~ ENV["TERM"] if @tty.nil?
+ @eol = @tty && !@verbose ? "\r\e[K\r" : "\n"
+ case @color
+ when nil
+ @color = @tty
+ end
+ if @color
+ # dircolors-like style
+ colors = (colors = ENV['TEST_COLORS']) ? Hash[colors.scan(/(\w+)=([^:]*)/)] : {}
+ @passed = "\e[#{colors["pass"] || "32"}m"
+ @failed = "\e[#{colors["fail"] || "31"}m"
+ @reset = "\e[m"
+ else
+ @passed = @failed = @reset = ""
+ end
+ extend(Rotator) if @tty
+ end
+
+ def passed_string
+ "."
+ end
+ def failed_string
+ "#{@failed}F#{@reset}"
+ end
+ def init_string
+ end
+ def finish_string
+ if @quiet
+ @eol
+ else
+ "#{@passed}#{@ok ? 'OK' : ''} #{$testnum}#{@reset}#{@eol}"
+ end
+ end
+ def pass
+ STDERR.print passed_string
+ end
+ def fail
+ @ok = false
+ STDERR.print failed_string
+ end
+ def init
+ @ok = true
+ STDERR.print init_string
+ end
+ def finish
+ STDERR.print finish_string
+ end
+
+ module Rotator
+ ROTATOR = %w[- \\ | /]
+ BS = "\b" * ROTATOR[0].size
+ def passed_string
+ "#{BS}#{ROTATOR[(@count += 1) % ROTATOR.size]}"
+ end
+ def failed_string
+ "#{BS}#{super}#{ROTATOR[@count % ROTATOR.size]}"
+ end
+ def init_string
+ @count = 0
+ " "
+ end
+ def finish_string
+ s = "#{BS}#{' ' * BS.size}#{BS}#{super}"
+ s.gsub!(/\n/, "\r\e[2K\r") if @quiet
+ s
+ end
+ end
+end
+PROGRESS = Progress.new
+
+def test_check(what)
+ unless $ntest.zero?
+ PROGRESS.finish
+ end
+ STDERR.print "sample/test.rb:#{what} "
+ PROGRESS.init
+ $what = what
+ $testnum = 0
+end
+
+def test_ok(cond,n=1)
+ $testnum+=1
+ $ntest+=1
+ where = (st = caller(n)) ? st[0] : "caller error! (n=#{n}, trace=#{caller(0).join(', ')}"
+ if cond
+ PROGRESS.pass
+ printf "ok %d (%s)\n", $testnum, where
+ else
+ PROGRESS.fail
+ printf "not ok %s %d -- %s\n", $what, $testnum, where
+ $failed+=1
+ end
+ STDOUT.flush
+ STDERR.flush
+end
+
+# make sure conditional operators work
+
+test_check "assignment"
+
+a=[]; a[0] ||= "bar";
+test_ok(a[0] == "bar")
+h={}; h["foo"] ||= "bar";
+test_ok(h["foo"] == "bar")
+
+aa = 5
+aa ||= 25
+test_ok(aa == 5)
+bb ||= 25
+test_ok(bb == 25)
+cc &&=33
+test_ok(cc == nil)
+cc = 5
+cc &&=44
+test_ok(cc == 44)
+
+a = nil; test_ok(a == nil)
+a = 1; test_ok(a == 1)
+a = []; test_ok(a == [])
+a = [1]; test_ok(a == [1])
+a = [nil]; test_ok(a == [nil])
+a = [[]]; test_ok(a == [[]])
+a = [1,2]; test_ok(a == [1,2])
+a = [*[]]; test_ok(a == [])
+a = [*[1]]; test_ok(a == [1])
+a = [*[1,2]]; test_ok(a == [1,2])
+
+a = *[]; test_ok(a == [])
+a = *[1]; test_ok(a == [1])
+a = *[nil]; test_ok(a == [nil])
+a = *[[]]; test_ok(a == [[]])
+a = *[1,2]; test_ok(a == [1,2])
+a = *[*[]]; test_ok(a == [])
+a = *[*[1]]; test_ok(a == [1])
+a = *[*[1,2]]; test_ok(a == [1,2])
+
+a, = nil; test_ok(a == nil)
+a, = 1; test_ok(a == 1)
+a, = []; test_ok(a == nil)
+a, = [1]; test_ok(a == 1)
+a, = [nil]; test_ok(a == nil)
+a, = [[]]; test_ok(a == [])
+a, = 1,2; test_ok(a == 1)
+a, = [1,2]; test_ok(a == 1)
+a, = [*[]]; test_ok(a == nil)
+a, = [*[1]]; test_ok(a == 1)
+a, = *[1,2]; test_ok(a == 1)
+a, = [*[1,2]]; test_ok(a == 1)
+
+a, = *[]; test_ok(a == nil)
+a, = *[1]; test_ok(a == 1)
+a, = *[nil]; test_ok(a == nil)
+a, = *[[]]; test_ok(a == [])
+a, = *[1,2]; test_ok(a == 1)
+a, = *[*[]]; test_ok(a == nil)
+a, = *[*[1]]; test_ok(a == 1)
+a, = *[*[1,2]]; test_ok(a == 1)
+
+*a = nil; test_ok(a == [nil])
+*a = 1; test_ok(a == [1])
+*a = []; test_ok(a == [])
+*a = [1]; test_ok(a == [1])
+*a = [nil]; test_ok(a == [nil])
+*a = [[]]; test_ok(a == [[]])
+*a = [1,2]; test_ok(a == [1,2])
+*a = [*[]]; test_ok(a == [])
+*a = [*[1]]; test_ok(a == [1])
+*a = [*[1,2]]; test_ok(a == [1,2])
+
+*a = *[]; test_ok(a == [])
+*a = *[1]; test_ok(a == [1])
+*a = *[nil]; test_ok(a == [nil])
+*a = *[[]]; test_ok(a == [[]])
+*a = *[1,2]; test_ok(a == [1,2])
+*a = *[*[]]; test_ok(a == [])
+*a = *[*[1]]; test_ok(a == [1])
+*a = *[*[1,2]]; test_ok(a == [1,2])
+
+a,b,*c = nil; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = 1; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = []; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = [1]; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = [nil]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = [[]]; test_ok([a,b,c] == [[],nil,[]])
+a,b,*c = [1,2]; test_ok([a,b,c] == [1,2,[]])
+a,b,*c = [*[]]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = [*[1]]; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = [*[1,2]]; test_ok([a,b,c] == [1,2,[]])
+
+a,b,*c = *[]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = *[1]; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = *[nil]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = *[[]]; test_ok([a,b,c] == [[],nil,[]])
+a,b,*c = *[1,2]; test_ok([a,b,c] == [1,2,[]])
+a,b,*c = *[*[]]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = *[*[1]]; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = *[*[1,2]]; test_ok([a,b,c] == [1,2,[]])
+
+def f; yield nil; end; f {|a| test_ok(a == nil)}
+def f; yield 1; end; f {|a| test_ok(a == 1)}
+def f; yield []; end; f {|a| test_ok(a == [])}
+def f; yield [1]; end; f {|a| test_ok(a == [1])}
+def f; yield [nil]; end; f {|a| test_ok(a == [nil])}
+def f; yield [[]]; end; f {|a| test_ok(a == [[]])}
+def f; yield [*[]]; end; f {|a| test_ok(a == [])}
+def f; yield [*[1]]; end; f {|a| test_ok(a == [1])}
+def f; yield [*[1,2]]; end; f {|a| test_ok(a == [1,2])}
+def f; yield *[]; end; f {|a| test_ok(a == nil)}
+def f; yield *[1]; end; f {|a| test_ok(a == 1)}
+def f; yield *[nil]; end; f {|a| test_ok(a == nil)}
+def f; yield *[[]]; end; f {|a| test_ok(a == [])}
+def f; yield *[*[]]; end; f {|a| test_ok(a == nil)}
+def f; yield *[*[1]]; end; f {|a| test_ok(a == 1)}
+def f; yield *[*[1,2]]; end; f {|a| test_ok(a == 1)}
+
+def f; yield; end; f {|a,| test_ok(a == nil)}
+def f; yield nil; end; f {|a,| test_ok(a == nil)}
+def f; yield 1; end; f {|a,| test_ok(a == 1)}
+def f; yield []; end; f {|a,| test_ok(a == nil)}
+def f; yield [1]; end; f {|a,| test_ok(a == 1)}
+def f; yield [nil]; end; f {|a,| test_ok(a == nil)}
+def f; yield [[]]; end; f {|a,| test_ok(a == [])}
+def f; yield [*[]]; end; f {|a,| test_ok(a == nil)}
+def f; yield [*[1]]; end; f {|a,| test_ok(a == 1)}
+def f; yield [*[1,2]]; end; f {|a,| test_ok(a == 1)}
+
+def f; yield *[]; end; f {|a,| test_ok(a == nil)}
+def f; yield *[1]; end; f {|a,| test_ok(a == 1)}
+def f; yield *[nil]; end; f {|a,| test_ok(a == nil)}
+def f; yield *[[]]; end; f {|a,| test_ok(a == nil)}
+def f; yield *[*[]]; end; f {|a,| test_ok(a == nil)}
+def f; yield *[*[1]]; end; f {|a,| test_ok(a == 1)}
+def f; yield *[*[1,2]]; end; f {|a,| test_ok(a == 1)}
+
+def f; yield; end; f {|*a| test_ok(a == [])}
+def f; yield nil; end; f {|*a| test_ok(a == [nil])}
+def f; yield 1; end; f {|*a| test_ok(a == [1])}
+def f; yield []; end; f {|*a| test_ok(a == [[]])}
+def f; yield [1]; end; f {|*a| test_ok(a == [[1]])}
+def f; yield [nil]; end; f {|*a| test_ok(a == [[nil]])}
+def f; yield [[]]; end; f {|*a| test_ok(a == [[[]]])}
+def f; yield [1,2]; end; f {|*a| test_ok(a == [[1,2]])}
+def f; yield [*[]]; end; f {|*a| test_ok(a == [[]])}
+def f; yield [*[1]]; end; f {|*a| test_ok(a == [[1]])}
+def f; yield [*[1,2]]; end; f {|*a| test_ok(a == [[1,2]])}
+
+def f; yield *[]; end; f {|*a| test_ok(a == [])}
+def f; yield *[1]; end; f {|*a| test_ok(a == [1])}
+def f; yield *[nil]; end; f {|*a| test_ok(a == [nil])}
+def f; yield *[[]]; end; f {|*a| test_ok(a == [[]])}
+def f; yield *[*[]]; end; f {|*a| test_ok(a == [])}
+def f; yield *[*[1]]; end; f {|*a| test_ok(a == [1])}
+def f; yield *[*[1,2]]; end; f {|*a| test_ok(a == [1,2])}
+
+def f; yield; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield nil; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield 1; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield []; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield [nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])}
+def f; yield [*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield [*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])}
+
+def f; yield *[]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield *[1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield *[nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield *[[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield *[*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield *[*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield *[*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])}
+
+def r; return; end; a = r(); test_ok(a == nil)
+def r; return nil; end; a = r(); test_ok(a == nil)
+def r; return 1; end; a = r(); test_ok(a == 1)
+def r; return []; end; a = r(); test_ok(a == [])
+def r; return [1]; end; a = r(); test_ok(a == [1])
+def r; return [nil]; end; a = r(); test_ok(a == [nil])
+def r; return [[]]; end; a = r(); test_ok(a == [[]])
+def r; return [*[]]; end; a = r(); test_ok(a == [])
+def r; return [*[1]]; end; a = r(); test_ok(a == [1])
+def r; return [*[1,2]]; end; a = r(); test_ok(a == [1,2])
+
+def r; return *[]; end; a = r(); test_ok(a == [])
+def r; return *[1]; end; a = r(); test_ok(a == [1])
+def r; return *[nil]; end; a = r(); test_ok(a == [nil])
+def r; return *[[]]; end; a = r(); test_ok(a == [[]])
+def r; return *[*[]]; end; a = r(); test_ok(a == [])
+def r; return *[*[1]]; end; a = r(); test_ok(a == [1])
+def r; return *[*[1,2]]; end; a = r(); test_ok(a == [1,2])
+
+def r; return *[[]]; end; a = *r(); test_ok(a == [[]])
+def r; return *[*[1,2]]; end; a = *r(); test_ok(a == [1,2])
+
+def r; return; end; *a = r(); test_ok(a == [nil])
+def r; return nil; end; *a = r(); test_ok(a == [nil])
+def r; return 1; end; *a = r(); test_ok(a == [1])
+def r; return []; end; *a = r(); test_ok(a == [])
+def r; return [1]; end; *a = r(); test_ok(a == [1])
+def r; return [nil]; end; *a = r(); test_ok(a == [nil])
+def r; return [[]]; end; *a = r(); test_ok(a == [[]])
+def r; return [1,2]; end; *a = r(); test_ok(a == [1,2])
+def r; return [*[]]; end; *a = r(); test_ok(a == [])
+def r; return [*[1]]; end; *a = r(); test_ok(a == [1])
+def r; return [*[1,2]]; end; *a = r(); test_ok(a == [1,2])
+
+def r; return *[]; end; *a = r(); test_ok(a == [])
+def r; return *[1]; end; *a = r(); test_ok(a == [1])
+def r; return *[nil]; end; *a = r(); test_ok(a == [nil])
+def r; return *[[]]; end; *a = r(); test_ok(a == [[]])
+def r; return *[1,2]; end; *a = r(); test_ok(a == [1,2])
+def r; return *[*[]]; end; *a = r(); test_ok(a == [])
+def r; return *[*[1]]; end; *a = r(); test_ok(a == [1])
+def r; return *[*[1,2]]; end; *a = r(); test_ok(a == [1,2])
+
+def r; return *[[]]; end; *a = *r(); test_ok(a == [[]])
+def r; return *[1,2]; end; *a = *r(); test_ok(a == [1,2])
+def r; return *[*[1,2]]; end; *a = *r(); test_ok(a == [1,2])
+
+def r; return; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return nil; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return 1; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return []; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return [1]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return [nil]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return [[]]; end; a,b,*c = r(); test_ok([a,b,c] == [[],nil,[]])
+def r; return [1,2]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])
+def r; return [*[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return [*[1]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return [*[1,2]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])
+
+def r; return *[]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return *[1]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return *[nil]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return *[[]]; end; a,b,*c = r(); test_ok([a,b,c] == [[],nil,[]])
+def r; return *[1,2]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])
+def r; return *[*[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return *[*[1]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return *[*[1,2]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])
+
+f = lambda {|r,| test_ok([] == r)}
+f.call([], *[])
+
+f = lambda {|r,*l| test_ok([] == r); test_ok([1] == l)}
+f.call([], *[1])
+
+f = lambda{|x| x}
+test_ok(f.call(42) == 42)
+test_ok(f.call([42]) == [42])
+test_ok(f.call([[42]]) == [[42]])
+test_ok(f.call([42,55]) == [42,55])
+
+f = lambda{|x,| x}
+test_ok(f.call(42) == 42)
+test_ok(f.call([42]) == [42])
+test_ok(f.call([[42]]) == [[42]])
+test_ok(f.call([42,55]) == [42,55])
+
+f = lambda{|*x| x}
+test_ok(f.call(42) == [42])
+test_ok(f.call([42]) == [[42]])
+test_ok(f.call([[42]]) == [[[42]]])
+test_ok(f.call([42,55]) == [[42,55]])
+test_ok(f.call(42,55) == [42,55])
+
+f = lambda { |a, b=42, *c| [a,b,c] }
+test_ok(f.call(1 ) == [1,42,[ ]] )
+test_ok(f.call(1,43 ) == [1,43,[ ]] )
+test_ok(f.call(1,43,44) == [1,43,[44]] )
+
+f = lambda { |a, b=(a|16), *c, &block| [a,b,c,block&&block[]] }
+test_ok(f.call(8 ) == [8,24,[ ],nil] )
+test_ok(f.call(8,43 ) == [8,43,[ ],nil] )
+test_ok(f.call(8,43,44) == [8,43,[44],nil] )
+test_ok(f.call(8 ){45} == [8,24,[ ],45 ] )
+test_ok(f.call(8,43 ){45} == [8,43,[ ],45 ] )
+test_ok(f.call(8,43,44){45} == [8,43,[44],45 ] )
+
+f = lambda { |a, b=42, *c, d| [a,b,c,d] }
+test_ok(f.call(1 ,99) == [1,42,[ ],99] )
+test_ok(f.call(1,43 ,99) == [1,43,[ ],99] )
+test_ok(f.call(1,43,44,99) == [1,43,[44],99] )
+
+f = lambda { |a, b=(a|16), &block| [a,b,block&&block[]] }
+test_ok(f.call(8 ) == [8,24,nil] )
+test_ok(f.call(8,43) == [8,43,nil] )
+test_ok(f.call(8,43) == [8,43,nil] )
+test_ok(f.call(8 ){45} == [8,24,45 ] )
+test_ok(f.call(8,43){45} == [8,43,45 ] )
+test_ok(f.call(8,43){45} == [8,43,45 ] )
+
+f = lambda { |a, b=42, d| [a,b,d] }
+test_ok(f.call(1 ,99) == [1,42,99] )
+test_ok(f.call(1,43,99) == [1,43,99] )
+test_ok(f.call(1,43,99) == [1,43,99] )
+
+f = lambda { |b=42, *c, &block| [b,c,block&&block[]] }
+test_ok(f.call( ) == [42,[ ],nil] )
+test_ok(f.call(43 ) == [43,[ ],nil] )
+test_ok(f.call(43,44) == [43,[44],nil] )
+test_ok(f.call( ){45} == [42,[ ],45 ] )
+test_ok(f.call(43 ){45} == [43,[ ],45 ] )
+test_ok(f.call(43,44){45} == [43,[44],45 ] )
+
+f = lambda { |b=42, *c, d| [b,c,d] }
+test_ok(f.call( 99) == [42,[ ],99] )
+test_ok(f.call(43 ,99) == [43,[ ],99] )
+test_ok(f.call(43,44,99) == [43,[44],99] )
+
+f = lambda { |b=42, &block| [b,block&&block[]] }
+test_ok(f.call( ) == [42,nil] )
+test_ok(f.call(43) == [43,nil] )
+test_ok(f.call(43) == [43,nil] )
+test_ok(f.call( ){45} == [42,45 ] )
+test_ok(f.call(43){45} == [43,45 ] )
+test_ok(f.call(43){45} == [43,45 ] )
+
+f = lambda { |b=42, d| [b,d] }
+test_ok(f.call( 99) == [42,99] )
+test_ok(f.call(43,99) == [43,99] )
+test_ok(f.call(43,99) == [43,99] )
+
+
+a,=*[1]
+test_ok(a == 1)
+a,=*[[1]]
+test_ok(a == [1])
+a,=*[[[1]]]
+test_ok(a == [[1]])
+
+x, (y, z) = 1, 2, 3
+test_ok([1,2,nil] == [x,y,z])
+x, (y, z) = 1, [2,3]
+test_ok([1,2,3] == [x,y,z])
+x, (y, z) = 1, [2]
+test_ok([1,2,nil] == [x,y,z])
+
+a = loop do break; end; test_ok(a == nil)
+a = loop do break nil; end; test_ok(a == nil)
+a = loop do break 1; end; test_ok(a == 1)
+a = loop do break []; end; test_ok(a == [])
+a = loop do break [1]; end; test_ok(a == [1])
+a = loop do break [nil]; end; test_ok(a == [nil])
+a = loop do break [[]]; end; test_ok(a == [[]])
+a = loop do break [*[]]; end; test_ok(a == [])
+a = loop do break [*[1]]; end; test_ok(a == [1])
+a = loop do break [*[1,2]]; end; test_ok(a == [1,2])
+
+a = loop do break *[]; end; test_ok(a == [])
+a = loop do break *[1]; end; test_ok(a == [1])
+a = loop do break *[nil]; end; test_ok(a == [nil])
+a = loop do break *[[]]; end; test_ok(a == [[]])
+a = loop do break *[*[]]; end; test_ok(a == [])
+a = loop do break *[*[1]]; end; test_ok(a == [1])
+a = loop do break *[*[1,2]]; end; test_ok(a == [1,2])
+
+*a = loop do break; end; test_ok(a == [nil])
+*a = loop do break nil; end; test_ok(a == [nil])
+*a = loop do break 1; end; test_ok(a == [1])
+*a = loop do break []; end; test_ok(a == [])
+*a = loop do break [1]; end; test_ok(a == [1])
+*a = loop do break [nil]; end; test_ok(a == [nil])
+*a = loop do break [[]]; end; test_ok(a == [[]])
+*a = loop do break [1,2]; end; test_ok(a == [1,2])
+*a = loop do break [*[]]; end; test_ok(a == [])
+*a = loop do break [*[1]]; end; test_ok(a == [1])
+*a = loop do break [*[1,2]]; end; test_ok(a == [1,2])
+
+*a = loop do break *[]; end; test_ok(a == [])
+*a = loop do break *[1]; end; test_ok(a == [1])
+*a = loop do break *[nil]; end; test_ok(a == [nil])
+*a = loop do break *[[]]; end; test_ok(a == [[]])
+*a = loop do break *[1,2]; end; test_ok(a == [1,2])
+*a = loop do break *[*[]]; end; test_ok(a == [])
+*a = loop do break *[*[1]]; end; test_ok(a == [1])
+*a = loop do break *[*[1,2]]; end; test_ok(a == [1,2])
+
+*a = *loop do break *[[]]; end; test_ok(a == [[]])
+*a = *loop do break *[1,2]; end; test_ok(a == [1,2])
+*a = *loop do break *[*[1,2]]; end; test_ok(a == [1,2])
+
+a,b,*c = loop do break; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break nil; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break 1; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break []; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break [1]; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break [nil]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break [[]]; end; test_ok([a,b,c] == [[],nil,[]])
+a,b,*c = loop do break [1,2]; end; test_ok([a,b,c] == [1,2,[]])
+a,b,*c = loop do break [*[]]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break [*[1]]; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break [*[1,2]]; end; test_ok([a,b,c] == [1,2,[]])
+
+a,b,*c = loop do break *[]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break *[1]; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break *[nil]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break *[[]]; end; test_ok([a,b,c] == [[],nil,[]])
+a,b,*c = loop do break *[1,2]; end; test_ok([a,b,c] == [1,2,[]])
+a,b,*c = loop do break *[*[]]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break *[*[1]]; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break *[*[1,2]]; end; test_ok([a,b,c] == [1,2,[]])
+
+def r(val); a = yield(); test_ok(a == val, 2); end
+r(nil){next}
+r(nil){next nil}
+r(1){next 1}
+r([]){next []}
+r([1]){next [1]}
+r([nil]){next [nil]}
+r([[]]){next [[]]}
+r([]){next [*[]]}
+r([1]){next [*[1]]}
+r([1,2]){next [*[1,2]]}
+
+r([]){next *[]}
+r([1]){next *[1]}
+r([nil]){next *[nil]}
+r([[]]){next *[[]]}
+r([]){next *[*[]]}
+r([1]){next *[*[1]]}
+r([1,2]){next *[*[1,2]]}
+
+def r(val); *a = yield(); test_ok(a == val, 2); end
+r([nil]){next}
+r([nil]){next nil}
+r([1]){next 1}
+r([]){next []}
+r([1]){next [1]}
+r([nil]){next [nil]}
+r([[]]){next [[]]}
+r([1,2]){next [1,2]}
+r([]){next [*[]]}
+r([1]){next [*[1]]}
+r([1,2]){next [*[1,2]]}
+
+def r(val); *a = *yield(); test_ok(a == val, 2); end
+r([[]]){next *[[]]}
+r([1,2]){next *[1,2]}
+r([1,2]){next *[*[1,2]]}
+
+def r(val); a,b,*c = yield(); test_ok([a,b,c] == val, 2); end
+r([nil,nil,[]]){next}
+r([nil,nil,[]]){next nil}
+r([1,nil,[]]){next 1}
+r([nil,nil,[]]){next []}
+r([1,nil,[]]){next [1]}
+r([nil,nil,[]]){next [nil]}
+r([[],nil,[]]){next [[]]}
+r([1,2,[]]){next [1,2]}
+r([nil,nil,[]]){next [*[]]}
+r([1,nil,[]]){next [*[1]]}
+r([1,2,[]]){next [*[1,2]]}
+
+def r(val); a,b,*c = *yield(); test_ok([a,b,c] == val, 2); end
+r([[],nil,[]]){next *[[]]}
+r([1,2,[]]){next *[1,2]}
+r([1,2,[]]){next *[*[1,2]]}
+
+test_check "condition"
+
+$x = '0';
+
+$x == $x && test_ok(true)
+$x != $x && test_ok(false)
+$x == $x || test_ok(false)
+$x != $x || test_ok(true)
+
+# first test to see if we can run the tests.
+
+test_check "if/unless";
+
+$x = 'test';
+test_ok(if $x == $x then true else false end)
+$bad = false
+unless $x == $x
+ $bad = true
+end
+test_ok(!$bad)
+test_ok(unless $x != $x then true else false end)
+
+test_check "case"
+
+case 5
+when 1, 2, 3, 4, 6, 7, 8
+ test_ok(false)
+when 5
+ test_ok(true)
+end
+
+case 5
+when 5
+ test_ok(true)
+when 1..10
+ test_ok(false)
+end
+
+case 5
+when 1..10
+ test_ok(true)
+else
+ test_ok(false)
+end
+
+case 5
+when 5
+ test_ok(true)
+else
+ test_ok(false)
+end
+
+case "foobar"
+when /^f.*r$/
+ test_ok(true)
+else
+ test_ok(false)
+end
+
+test_check "while/until";
+
+while_tmp = "while_tmp.#{$$}"
+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")
+test_ok(tmp.kind_of?(File))
+
+while line = tmp.gets()
+ break if /vt100/ =~ line
+end
+
+test_ok(!tmp.eof? && /vt100/ =~ line)
+tmp.close
+
+# test next
+$bad = false
+tmp = open(while_tmp, "r")
+while line = tmp.gets()
+ next if /vt100/ =~ line
+ $bad = 1 if /vt100/ =~ line
+end
+test_ok(!(!tmp.eof? || /vt100/ =~ line || $bad))
+tmp.close
+
+# test redo
+$bad = false
+tmp = open(while_tmp, "r")
+while line = tmp.gets()
+ lastline = line
+ line = line.gsub(/vt100/, 'VT100')
+ if lastline != line
+ line.gsub!('VT100', 'Vt100')
+ redo
+ end
+ $bad = 1 if /vt100/ =~ line
+ $bad = 1 if /VT100/ =~ line
+end
+test_ok(tmp.eof? && !$bad)
+tmp.close
+
+sum=0
+for i in 1..10
+ sum += i
+ i -= 1
+ if i > 0
+ redo
+ end
+end
+test_ok(sum == 220)
+
+# test interval
+$bad = false
+tmp = open(while_tmp, "r")
+while line = tmp.gets()
+ break if 3
+ case line
+ when /vt100/, /Amiga/, /paper/
+ $bad = true
+ end
+end
+test_ok(!$bad)
+tmp.close
+
+File.unlink while_tmp or `/bin/rm -f "#{while_tmp}"`
+test_ok(!File.exist?(while_tmp))
+
+i = 0
+until i>4
+ i+=1
+end
+test_ok(i>4)
+
+
+# exception handling
+test_check "exception";
+
+begin
+ raise "this must be handled"
+ test_ok(false)
+rescue
+ test_ok(true)
+end
+
+$bad = true
+begin
+ raise "this must be handled no.2"
+rescue
+ if $bad
+ $bad = false
+ retry
+ test_ok(false)
+ end
+end
+test_ok(true)
+
+# exception in rescue clause
+$string = "this must be handled no.3"
+begin
+ begin
+ raise "exception in rescue clause"
+ rescue
+ raise $string
+ end
+ test_ok(false)
+rescue => e
+ test_ok($! == e)
+ test_ok(e.message == $string)
+ test_ok(e != $string)
+end
+
+# exception in ensure clause
+begin
+ begin
+ raise "this must be handled no.4"
+ ensure
+ raise "exception in ensure clause"
+ end
+ test_ok(false)
+rescue
+ test_ok(true)
+end
+
+$bad = true
+begin
+ begin
+ raise "this must be handled no.5"
+ ensure
+ $bad = false
+ end
+rescue
+end
+test_ok(!$bad)
+
+$bad = true
+begin
+ begin
+ raise "this must be handled no.6"
+ ensure
+ $bad = false
+ end
+rescue
+end
+test_ok(!$bad)
+
+$bad = true
+while true
+ begin
+ break
+ ensure
+ $bad = false
+ end
+end
+test_ok(!$bad)
+
+test_ok(catch(:foo) {
+ loop do
+ loop do
+ throw :foo, true
+ break
+ end
+ break
+ test_ok(false) # should not reach here
+ end
+ false
+ })
+
+test_check "array"
+test_ok([1, 2] + [3, 4] == [1, 2, 3, 4])
+test_ok([1, 2] * 2 == [1, 2, 1, 2])
+test_ok([1, 2] * ":" == "1:2")
+
+test_ok([1, 2].hash == [1, 2].hash)
+
+test_ok([1,2,3] & [2,3,4] == [2,3])
+test_ok([1,2,3] | [2,3,4] == [1,2,3,4])
+test_ok([1,2,3] - [2,3] == [1])
+
+$x = [0, 1, 2, 3, 4, 5]
+test_ok($x[2] == 2)
+test_ok($x[1..3] == [1, 2, 3])
+test_ok($x[1,3] == [1, 2, 3])
+
+$x[0, 2] = 10
+test_ok($x[0] == 10 && $x[1] == 2)
+
+$x[0, 0] = -1
+test_ok($x[0] == -1 && $x[1] == 10)
+
+$x[-1, 1] = 20
+test_ok($x[-1] == 20 && $x.pop == 20)
+
+# array and/or
+test_ok(([1,2,3]&[2,4,6]) == [2])
+test_ok(([1,2,3]|[2,4,6]) == [1,2,3,4,6])
+
+# compact
+$x = [nil, 1, nil, nil, 5, nil, nil]
+$x.compact!
+test_ok($x == [1, 5])
+
+# uniq
+$x = [1, 1, 4, 2, 5, 4, 5, 1, 2]
+$x.uniq!
+test_ok($x == [1, 4, 2, 5])
+
+# empty?
+test_ok(!$x.empty?)
+$x = []
+test_ok($x.empty?)
+
+# sort
+$x = ["it", "came", "to", "pass", "that", "..."]
+$x = $x.sort.join(" ")
+test_ok($x == "... came it pass that to")
+$x = [2,5,3,1,7]
+$x.sort!{|a,b| a<=>b} # sort with condition
+test_ok($x == [1,2,3,5,7])
+$x.sort!{|a,b| b-a} # reverse sort
+test_ok($x == [7,5,3,2,1])
+
+# split test
+$x = "The Book of Mormon"
+test_ok($x.split(//).reverse!.join == $x.reverse)
+test_ok($x.reverse == $x.reverse!)
+test_ok("1 byte string".split(//).reverse.join(":") == "g:n:i:r:t:s: :e:t:y:b: :1")
+$x = "a b c d"
+test_ok($x.split == ['a', 'b', 'c', 'd'])
+test_ok($x.split(' ') == ['a', 'b', 'c', 'd'])
+test_ok(defined? "a".chomp)
+test_ok("abc".scan(/./) == ["a", "b", "c"])
+test_ok("1a2b3c".scan(/(\d.)/) == [["1a"], ["2b"], ["3c"]])
+# non-greedy match
+test_ok("a=12;b=22".scan(/(.*?)=(\d*);?/) == [["a", "12"], ["b", "22"]])
+
+$x = [1]
+test_ok(($x * 5).join(":") == '1:1:1:1:1')
+test_ok(($x * 1).join(":") == '1')
+test_ok(($x * 0).join(":") == '')
+
+*$x = *(1..7).to_a
+test_ok($x.size == 7)
+test_ok($x == [1, 2, 3, 4, 5, 6, 7])
+
+$x = [1,2,3]
+$x[1,0] = $x
+test_ok($x == [1,1,2,3,2,3])
+
+$x = [1,2,3]
+$x[-1,0] = $x
+test_ok($x == [1,2,1,2,3,3])
+
+$x = [1,2,3]
+$x.concat($x)
+test_ok($x == [1,2,3,1,2,3])
+
+test_check "hash"
+$x = {1=>2, 2=>4, 3=>6}
+
+test_ok($x[1] == 2)
+
+test_ok(begin
+ for k,v in $x
+ raise if k*2 != v
+ end
+ true
+ rescue
+ false
+ end)
+
+test_ok($x.length == 3)
+test_ok($x.has_key?(1))
+test_ok($x.has_value?(4))
+test_ok($x.values_at(2,3) == [4,6])
+test_ok($x == {1=>2, 2=>4, 3=>6})
+
+$z = $x.keys.sort.join(":")
+test_ok($z == "1:2:3")
+
+$z = $x.values.sort.join(":")
+test_ok($z == "2:4:6")
+test_ok($x == $x)
+
+$x.shift
+test_ok($x.length == 2)
+
+$z = [1,2]
+$x[$z] = 256
+test_ok($x[$z] == 256)
+
+$x = Hash.new(0)
+$x[1] = 1
+test_ok($x[1] == 1)
+test_ok($x[2] == 0)
+
+$x = Hash.new([])
+test_ok($x[22] == [])
+test_ok($x[22].equal?($x[22]))
+
+$x = Hash.new{[]}
+test_ok($x[22] == [])
+test_ok(!$x[22].equal?($x[22]))
+
+$x = Hash.new{|h,k| $z = k; h[k] = k*2}
+$z = 0
+test_ok($x[22] == 44)
+test_ok($z == 22)
+$z = 0
+test_ok($x[22] == 44)
+test_ok($z == 0)
+$x.default = 5
+test_ok($x[23] == 5)
+
+$x = Hash.new
+def $x.default(k)
+ $z = k
+ self[k] = k*2
+end
+$z = 0
+test_ok($x[22] == 44)
+test_ok($z == 22)
+$z = 0
+test_ok($x[22] == 44)
+test_ok($z == 0)
+
+test_check "iterator"
+
+test_ok(!iterator?)
+
+def ttt
+ test_ok(iterator?)
+end
+ttt{}
+
+# yield at top level
+test_ok(!defined?(yield))
+
+$x = [1, 2, 3, 4]
+$y = []
+
+# iterator over array
+for i in $x
+ $y.push i
+end
+test_ok($x == $y)
+
+# nested iterator
+def tt
+ 1.upto(10) {|i|
+ yield i
+ }
+end
+
+i=0
+tt{|i| break if i == 5}
+test_ok(i == 0)
+
+def tt2(dummy)
+ yield 1
+end
+
+def tt3(&block)
+ tt2(raise(ArgumentError,""),&block)
+end
+
+$x = false
+begin
+ tt3{}
+rescue ArgumentError
+ $x = true
+rescue Exception
+end
+test_ok($x)
+
+def tt4 &block
+ tt2(raise(ArgumentError,""),&block)
+end
+$x = false
+begin
+ tt4{}
+rescue ArgumentError
+ $x = true
+rescue Exception
+end
+test_ok($x)
+
+# iterator break/redo/next/retry
+done = true
+loop{
+ break
+ done = false # should not reach here
+}
+test_ok(done)
+
+done = false
+$bad = false
+loop {
+ break if done
+ done = true
+ next
+ $bad = true # should not reach here
+}
+test_ok(!$bad)
+
+done = false
+$bad = false
+loop {
+ break if done
+ done = true
+ redo
+ $bad = true # should not reach here
+}
+test_ok(!$bad)
+
+$x = []
+for i in 1 .. 7
+ $x.push i
+end
+test_ok($x.size == 7)
+test_ok($x == [1, 2, 3, 4, 5, 6, 7])
+
+# append method to built-in class
+class Array
+ def iter_test1
+ collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]}
+ end
+ def iter_test2
+ a = collect{|e| [e, yield(e)]}
+ a.sort{|a,b|a[1]<=>b[1]}
+ end
+end
+$x = [[1,2],[3,4],[5,6]]
+test_ok($x.iter_test1{|x|x} == $x.iter_test2{|x|x})
+
+class IterTest
+ def initialize(e); @body = e; end
+
+ def each0(&block); @body.each(&block); end
+ def each1(&block); @body.each {|*x| block.call(*x) } end
+ def each2(&block); @body.each {|*x| block.call(x) } end
+ def each3(&block); @body.each {|x| block.call(*x) } end
+ def each4(&block); @body.each {|x| block.call(x) } end
+ def each5; @body.each {|*x| yield(*x) } end
+ def each6; @body.each {|*x| yield(x) } end
+ def each7; @body.each {|x| yield(*x) } end
+ def each8; @body.each {|x| yield(x) } end
+
+ def f(a)
+ a
+ end
+end
+test_ok(IterTest.new(nil).method(:f).to_proc.call([1]) == [1])
+m = /\w+/.match("abc")
+test_ok(IterTest.new(nil).method(:f).to_proc.call([m]) == [m])
+
+IterTest.new([0]).each0 {|x| test_ok(x == 0)}
+IterTest.new([1]).each1 {|x| test_ok(x == 1)}
+IterTest.new([2]).each2 {|x| test_ok(x == [2])}
+#IterTest.new([3]).each3 {|x| test_ok(x == 3)}
+IterTest.new([4]).each4 {|x| test_ok(x == 4)}
+IterTest.new([5]).each5 {|x| test_ok(x == 5)}
+IterTest.new([6]).each6 {|x| test_ok(x == [6])}
+#IterTest.new([7]).each7 {|x| test_ok(x == 7)}
+IterTest.new([8]).each8 {|x| test_ok(x == 8)}
+
+IterTest.new([[0]]).each0 {|x| test_ok(x == [0])}
+IterTest.new([[1]]).each1 {|x| test_ok(x == [1])}
+IterTest.new([[2]]).each2 {|x| test_ok(x == [[2]])}
+IterTest.new([[3]]).each3 {|x| test_ok(x == 3)}
+IterTest.new([[4]]).each4 {|x| test_ok(x == [4])}
+IterTest.new([[5]]).each5 {|x| test_ok(x == [5])}
+IterTest.new([[6]]).each6 {|x| test_ok(x == [[6]])}
+IterTest.new([[7]]).each7 {|x| test_ok(x == 7)}
+IterTest.new([[8]]).each8 {|x| test_ok(x == [8])}
+
+IterTest.new([[0,0]]).each0 {|*x| test_ok(x == [[0,0]])}
+IterTest.new([[8,8]]).each8 {|*x| test_ok(x == [[8,8]])}
+
+def m0(v)
+ v
+end
+
+def m1
+ m0(block_given?)
+end
+test_ok(m1{p 'test'})
+test_ok(!m1)
+
+def m
+ m0(block_given?,&Proc.new{})
+end
+test_ok(m1{p 'test'})
+test_ok(!m1)
+
+class C
+ include Enumerable
+ def initialize
+ @a = [1,2,3]
+ end
+ def each(&block)
+ @a.each(&block)
+ end
+end
+
+test_ok(C.new.collect{|n| n} == [1,2,3])
+
+test_ok(Proc == lambda{}.class)
+test_ok(Proc == Proc.new{}.class)
+lambda{|a|test_ok(a==1)}.call(1)
+def block_test(klass, &block)
+ test_ok(klass === block)
+end
+
+block_test(NilClass)
+block_test(Proc){}
+
+def call_argument_test(state, proc, *args)
+ x = state
+ begin
+ proc.call(*args)
+ rescue ArgumentError
+ x = !x
+ end
+ test_ok(x,2)
+end
+
+call_argument_test(true, lambda{||})
+call_argument_test(false, lambda{||}, 1)
+call_argument_test(true, lambda{|a,|}, 1)
+call_argument_test(false, lambda{|a,|})
+call_argument_test(false, lambda{|a,|}, 1,2)
+
+call_argument_test(true, Proc.new{||})
+call_argument_test(true, Proc.new{||}, 1)
+call_argument_test(true, Proc.new{|a,|}, 1)
+call_argument_test(true, Proc.new{|a,|})
+call_argument_test(true, Proc.new{|a,|}, 1,2)
+
+def block_get(&block)
+ block
+end
+
+test_ok(Proc == block_get{}.class)
+call_argument_test(true, block_get{||})
+call_argument_test(true, block_get{||}, 1)
+call_argument_test(true, block_get{|a,|}, 1)
+call_argument_test(true, block_get{|a,|})
+call_argument_test(true, block_get{|a,|}, 1,2)
+
+call_argument_test(true, block_get(&lambda{||}))
+call_argument_test(false, block_get(&lambda{||}),1)
+call_argument_test(true, block_get(&lambda{|a,|}),1)
+call_argument_test(false, block_get(&lambda{|a,|}),1,2)
+
+blk = block_get{11}
+test_ok(blk.class == Proc)
+test_ok(blk.to_proc.class == Proc)
+test_ok(blk.clone.call == 11)
+test_ok(block_get(&blk).class == Proc)
+
+lmd = lambda{44}
+test_ok(lmd.class == Proc)
+test_ok(lmd.to_proc.class == Proc)
+test_ok(lmd.clone.call == 44)
+test_ok(block_get(&lmd).class == Proc)
+
+test_ok(Proc.new{|a,| a}.yield(1,2,3) == 1)
+call_argument_test(true, Proc.new{|a,|}, 1,2)
+
+test_ok(Proc.new{|&b| b.call(10)}.call {|x| x} == 10)
+test_ok(Proc.new{|a,&b| b.call(a)}.call(12) {|x| x} == 12)
+
+def test_return1
+ Proc.new {
+ return 55
+ }.yield + 5
+end
+test_ok(test_return1() == 55)
+def test_return2
+ lambda {
+ return 55
+ }.call + 5
+end
+test_ok(test_return2() == 60)
+
+def proc_call(&b)
+ b.call
+end
+def proc_yield()
+ yield
+end
+def proc_return1
+ lambda{return 42}.call+1
+end
+test_ok(proc_return1() == 43)
+def proc_return2
+ ->{return 42}.call+1
+end
+test_ok(proc_return2() == 43)
+def proc_return3
+ proc_call{return 42}+1
+end
+test_ok(proc_return3() == 42)
+def proc_return4
+ proc_yield{return 42}+1
+end
+test_ok(proc_return4() == 42)
+
+def ljump_test(state, proc, *args)
+ x = state
+ begin
+ proc.call(*args)
+ rescue LocalJumpError
+ x = !x
+ end
+ test_ok(x,2)
+end
+
+ljump_test(false, block_get{break})
+ljump_test(true, lambda{break})
+
+def exit_value_test(&block)
+ block.call
+rescue LocalJumpError
+ $!.exit_value
+end
+
+test_ok(45 == exit_value_test{break 45})
+
+test_ok(55 == begin
+ block_get{break 55}.call
+ rescue LocalJumpError
+ $!.exit_value
+ end)
+
+def block_call(&block)
+ block.call
+end
+
+def test_b1
+ block_call{break 11}
+end
+test_ok(test_b1() == 11)
+
+def ljump_rescue(r)
+ begin
+ yield
+ rescue LocalJumpError => e
+ r if /from proc-closure/ =~ e.message
+ end
+end
+
+def test_b2
+ ljump_rescue(22) do
+ block_get{break 21}.call
+ end
+end
+test_ok(test_b2() == 22)
+
+def test_b3
+ ljump_rescue(33) do
+ Proc.new{break 31}.yield
+ end
+end
+test_ok(test_b3() == 33)
+
+def test_b4
+ lambda{break 44}.call
+end
+test_ok(test_b4() == 44)
+
+def test_b5
+ ljump_rescue(55) do
+ b = block_get{break 54}
+ block_call(&b)
+ end
+end
+test_ok(test_b5() == 55)
+
+def test_b6
+ b = lambda{break 67}
+ block_call(&b)
+ 66
+end
+test_ok(test_b6() == 66)
+
+def util_r7
+ block_get{break 78}
+end
+
+def test_b7
+ b = util_r7()
+ ljump_rescue(77) do
+ block_call(&b)
+ end
+end
+test_ok(test_b7() == 77)
+
+def util_b8(&block)
+ block_call(&block)
+end
+
+def test_b8
+ util_b8{break 88}
+end
+test_ok(test_b8() == 88)
+
+def util_b9(&block)
+ lambda{block.call; 98}.call
+end
+
+def test_b9
+ util_b9{break 99}
+end
+test_ok(test_b9() == 99)
+
+def util_b10
+ util_b9{break 100}
+end
+
+def test_b10
+ util_b10()
+end
+test_ok(test_b10() == 100)
+
+def test_b11
+ ljump_rescue(111) do
+ loop do
+ Proc.new{break 110}.yield
+ break 112
+ end
+ end
+end
+test_ok(test_b11() == 111)
+
+def test_b12
+ loop do
+ break lambda{break 122}.call
+ break 121
+ end
+end
+test_ok(test_b12() == 122)
+
+def test_b13
+ ljump_rescue(133) do
+ while true
+ Proc.new{break 130}.yield
+ break 131
+ end
+ end
+end
+test_ok(test_b13() == 133)
+
+def test_b14
+ while true
+ break lambda{break 144}.call
+ break 143
+ end
+end
+test_ok(test_b14() == 144)
+
+def test_b15
+ [0].each {|c| yield 1 }
+ 156
+end
+test_ok(test_b15{|e| break 155 } == 155)
+
+def marity_test(m)
+ method = method(m)
+ test_ok(method.arity == method.to_proc.arity, 2)
+end
+marity_test(:test_ok)
+marity_test(:marity_test)
+marity_test(:p)
+
+lambda(&method(:test_ok)).call(true)
+lambda(&block_get{|a,n| test_ok(a,n)}).call(true, 2)
+
+class ITER_TEST1
+ def a
+ block_given?
+ end
+end
+
+class ITER_TEST2 < ITER_TEST1
+ def a
+ test_ok(super)
+ super
+ end
+end
+test_ok(ITER_TEST2.new.a {})
+
+class ITER_TEST3
+ def foo x
+ return yield if block_given?
+ x
+ end
+end
+
+class ITER_TEST4 < ITER_TEST3
+ def foo x
+ test_ok(super == yield)
+ test_ok(super(x, &nil) == x)
+ end
+end
+
+ITER_TEST4.new.foo(44){55}
+
+class ITER_TEST5
+ def tt(aa)
+ aa
+ end
+
+ def uu(a)
+ class << self
+ define_method(:tt) do |sym|
+ super(sym)
+ end
+ end
+ end
+
+ def xx(*x)
+ x.size
+ end
+end
+
+a = ITER_TEST5.new
+a.uu(12)
+test_ok(a.tt(1) == 1)
+
+class ITER_TEST6 < ITER_TEST5
+ def xx(*a)
+ a << 12
+ super
+ end
+end
+
+test_ok(ITER_TEST6.new.xx([24]) == 2)
+
+test_check "float"
+test_ok(2.6.floor == 2)
+test_ok((-2.6).floor == -3)
+test_ok(2.6.ceil == 3)
+test_ok((-2.6).ceil == -2)
+test_ok(2.6.truncate == 2)
+test_ok((-2.6).truncate == -2)
+test_ok(2.6.round == 3)
+test_ok((-2.4).truncate == -2)
+test_ok((13.4 % 1 - 0.4).abs < 0.0001)
+nan = 0.0/0
+def nan_test(x,y)
+ test_ok(x != y)
+ test_ok((x < y) == false)
+ test_ok((x > y) == false)
+ test_ok((x <= y) == false)
+ test_ok((x >= y) == false)
+end
+nan_test(nan, nan)
+nan_test(nan, 0)
+nan_test(nan, 1)
+nan_test(nan, -1)
+nan_test(nan, 1000)
+nan_test(nan, -1000)
+nan_test(nan, 1_000_000_000_000)
+nan_test(nan, -1_000_000_000_000)
+nan_test(nan, 100.0);
+nan_test(nan, -100.0);
+nan_test(nan, 0.001);
+nan_test(nan, -0.001);
+nan_test(nan, 1.0/0);
+nan_test(nan, -1.0/0);
+
+#s = "3.7517675036461267e+17"
+#test_ok(s == sprintf("%.16e", s.to_f))
+f = 3.7517675036461267e+17
+test_ok(f == sprintf("%.16e", f).to_f)
+
+
+test_check "bignum"
+def fact(n)
+ return 1 if n == 0
+ f = 1
+ while n>0
+ f *= n
+ n -= 1
+ end
+ return f
+end
+$x = fact(40)
+test_ok($x == $x)
+test_ok($x == fact(40))
+test_ok($x < $x+2)
+test_ok($x > $x-2)
+test_ok($x == 815915283247897734345611269596115894272000000000)
+test_ok($x != 815915283247897734345611269596115894272000000001)
+test_ok($x+1 == 815915283247897734345611269596115894272000000001)
+test_ok($x/fact(20) == 335367096786357081410764800000)
+$x = -$x
+test_ok($x == -815915283247897734345611269596115894272000000000)
+test_ok(2-(2**32) == -(2**32-2))
+test_ok(2**32 - 5 == (2**32-3)-2)
+
+$good = true;
+for i in 1000..1014
+ $good = false if ((1 << i) != (2**i))
+end
+test_ok($good)
+
+$good = true;
+n1= 1 << 1000
+for i in 1000..1014
+ $good = false if ((1 << i) != n1)
+ n1 *= 2
+end
+test_ok($good)
+
+$good = true;
+n2=n1
+for i in 1..10
+ n1 = n1 / 2
+ n2 = n2 >> 1
+ $good = false if (n1 != n2)
+end
+test_ok($good)
+
+$good = true;
+for i in 4000..4096
+ n1 = 1 << i;
+ if (n1**2-1) / (n1+1) != (n1-1)
+ $good = false
+ end
+end
+test_ok($good)
+
+b = 10**80
+a = b * 9 + 7
+test_ok(7 == a.modulo(b))
+test_ok(-b + 7 == a.modulo(-b))
+test_ok(b + -7 == (-a).modulo(b))
+test_ok(-7 == (-a).modulo(-b))
+test_ok(7 == a.remainder(b))
+test_ok(7 == a.remainder(-b))
+test_ok(-7 == (-a).remainder(b))
+test_ok(-7 == (-a).remainder(-b))
+
+test_ok(10**40+10**20 == 10000000000000000000100000000000000000000)
+test_ok(10**40/10**20 == 100000000000000000000)
+
+a = 677330545177305025495135714080
+b = 14269972710765292560
+test_ok(a % b == 0)
+test_ok(-a % b == 0)
+
+def shift_test(a)
+ b = a / (2 ** 32)
+ c = a >> 32
+ test_ok(b == c)
+
+ b = a * (2 ** 32)
+ c = a << 32
+ test_ok(b == c)
+end
+
+shift_test(-4518325415524767873)
+shift_test(-0xfffffffffffffffff)
+
+test_check "string & char"
+
+test_ok("abcd" == "abcd")
+test_ok("abcd" =~ /abcd/)
+test_ok("abcd" === "abcd")
+# compile time string concatenation
+test_ok("ab" "cd" == "abcd")
+test_ok("#{22}aa" "cd#{44}" == "22aacd44")
+test_ok("#{22}aa" "cd#{44}" "55" "#{66}" == "22aacd445566")
+test_ok("abc" !~ /^$/)
+test_ok("abc\n" !~ /^$/)
+test_ok("abc" !~ /^d*$/)
+test_ok(("abc" =~ /d*$/) == 3)
+test_ok("" =~ /^$/)
+test_ok("\n" =~ /^$/)
+test_ok("a\n\n" =~ /^$/)
+test_ok("abcabc" =~ /.*a/ && $& == "abca")
+test_ok("abcabc" =~ /.*c/ && $& == "abcabc")
+test_ok("abcabc" =~ /.*?a/ && $& == "a")
+test_ok("abcabc" =~ /.*?c/ && $& == "abc")
+test_ok(/(.|\n)*?\n(b|\n)/ =~ "a\nb\n\n" && $& == "a\nb")
+
+test_ok(/^(ab+)+b/ =~ "ababb" && $& == "ababb")
+test_ok(/^(?:ab+)+b/ =~ "ababb" && $& == "ababb")
+test_ok(/^(ab+)+/ =~ "ababb" && $& == "ababb")
+test_ok(/^(?:ab+)+/ =~ "ababb" && $& == "ababb")
+
+test_ok(/(\s+\d+){2}/ =~ " 1 2" && $& == " 1 2")
+test_ok(/(?:\s+\d+){2}/ =~ " 1 2" && $& == " 1 2")
+
+$x = <<END;
+ABCD
+ABCD
+END
+$x.gsub!(/((.|\n)*?)B((.|\n)*?)D/, '\1\3')
+test_ok($x == "AC\nAC\n")
+
+test_ok("foobar" =~ /foo(?=(bar)|(baz))/)
+test_ok("foobaz" =~ /foo(?=(bar)|(baz))/)
+
+$foo = "abc"
+test_ok("#$foo = abc" == "abc = abc")
+test_ok("#{$foo} = abc" == "abc = abc")
+
+foo = "abc"
+test_ok("#{foo} = abc" == "abc = abc")
+
+test_ok('-' * 5 == '-----')
+test_ok('-' * 1 == '-')
+test_ok('-' * 0 == '')
+
+foo = '-'
+test_ok(foo * 5 == '-----')
+test_ok(foo * 1 == '-')
+test_ok(foo * 0 == '')
+
+$x = "a.gif"
+test_ok($x.sub(/.*\.([^\.]+)$/, '\1') == "gif")
+test_ok($x.sub(/.*\.([^\.]+)$/, 'b.\1') == "b.gif")
+test_ok($x.sub(/.*\.([^\.]+)$/, '\2') == "")
+test_ok($x.sub(/.*\.([^\.]+)$/, 'a\2b') == "ab")
+test_ok($x.sub(/.*\.([^\.]+)$/, '<\&>') == "<a.gif>")
+
+# character constants(assumes ASCII)
+test_ok("a"[0] == ?a)
+test_ok(?a == ?a)
+test_ok(?\C-a == "\1")
+test_ok(?\M-a == "\341")
+test_ok(?\M-\C-a == "\201")
+test_ok("a".upcase![0] == ?A)
+test_ok("A".downcase![0] == ?a)
+test_ok("abc".tr!("a-z", "A-Z") == "ABC")
+test_ok("aabbcccc".tr_s!("a-z", "A-Z") == "ABC")
+test_ok("abcc".squeeze!("a-z") == "abc")
+test_ok("abcd".delete!("bc") == "ad")
+
+$x = "abcdef"
+$y = [ ?a, ?b, ?c, ?d, ?e, ?f ]
+$bad = false
+$x.each_byte {|i|
+ if i.chr != $y.shift
+ $bad = true
+ break
+ end
+}
+test_ok(!$bad)
+
+s = "a string"
+s[0..s.size]="another string"
+test_ok(s == "another string")
+
+s = <<EOS
+#{
+[1,2,3].join(",")
+}
+EOS
+test_ok(s == "1,2,3\n")
+test_ok("Just".to_i(36) == 926381)
+test_ok("-another".to_i(36) == -23200231779)
+test_ok(1299022.to_s(36) == "ruby")
+test_ok(-1045307475.to_s(36) == "-hacker")
+test_ok("Just_another_Ruby_hacker".to_i(36) == 265419172580680477752431643787347)
+test_ok(-265419172580680477752431643787347.to_s(36) == "-justanotherrubyhacker")
+
+a = []
+(0..255).each {|n|
+ ch = [n].pack("C")
+ a.push ch if /a#{Regexp.quote ch}b/x =~ "ab"
+}
+test_ok(a.size == 0)
+
+test_check "assignment"
+a = nil
+test_ok(defined?(a))
+test_ok(a == nil)
+
+# multiple asignment
+a, b = 1, 2
+test_ok(a == 1 && b == 2)
+
+a, b = b, a
+test_ok(a == 2 && b == 1)
+
+a, = 1,2
+test_ok(a == 1)
+
+a, *b = 1, 2, 3
+test_ok(a == 1 && b == [2, 3])
+
+a, (b, c), d = 1, [2, 3], 4
+test_ok(a == 1 && b == 2 && c == 3 && d == 4)
+
+*a = 1, 2, 3
+test_ok(a == [1, 2, 3])
+
+*a = 4
+test_ok(a == [4])
+
+*a = nil
+test_ok(a == [nil])
+
+test_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
+ test_ok(false)
+rescue
+ test_ok(true)
+end
+
+begin
+ aaa # no arg given (exception raised)
+ test_ok(false)
+rescue
+ test_ok(true)
+end
+
+test_ok(aaa(1) == [1, 100])
+test_ok(aaa(1, 2) == [1, 2])
+test_ok(aaa(1, 2, 3, 4) == [1, 2, 3, 4])
+test_ok(aaa(1, *[2, 3, 4]) == [1, 2, 3, 4])
+
+test_check "proc"
+$proc = Proc.new{|i| i}
+test_ok($proc.call(2) == 2)
+test_ok($proc.call(3) == 3)
+
+$proc = Proc.new{|i| i*2}
+test_ok($proc.call(2) == 4)
+test_ok($proc.call(3) == 6)
+
+Proc.new{
+ iii=5 # nested local variable
+ $proc = Proc.new{|i|
+ iii = i
+ }
+ $proc2 = Proc.new {
+ $x = iii # nested variables shared by procs
+ }
+ # scope of nested variables
+ test_ok(defined?(iii))
+}.call
+test_ok(!defined?(iii)) # out of scope
+
+loop{iii=5; test_ok(eval("defined? iii")); break}
+loop {
+ iii = 10
+ def dyna_var_check
+ loop {
+ test_ok(!defined?(iii))
+ break
+ }
+ end
+ dyna_var_check
+ break
+}
+$x=0
+$proc.call(5)
+$proc2.call
+test_ok($x == 5)
+
+if defined? Process.kill
+ test_check "signal"
+
+ $x = 0
+ trap "SIGINT", Proc.new{|sig| $x = 2}
+ Process.kill "SIGINT", $$
+ 100.times {
+ sleep 0.1
+ break if $x != 0
+ }
+ test_ok($x == 2)
+
+ trap "SIGINT", Proc.new{raise "Interrupt"}
+
+ x = false
+ begin
+ Process.kill "SIGINT", $$
+ sleep 0.1
+ rescue
+ x = $!
+ end
+ test_ok(x && /Interrupt/ =~ x.message)
+end
+
+test_check "eval"
+test_ok(eval("") == nil)
+$bad=false
+eval 'while false; $bad = true; print "foo\n" end'
+test_ok(!$bad)
+
+test_ok(eval('TRUE'))
+test_ok(eval('true'))
+test_ok(!eval('NIL'))
+test_ok(!eval('nil'))
+test_ok(!eval('FALSE'))
+test_ok(!eval('false'))
+
+$foo = 'test_ok(true)'
+begin
+ eval $foo
+rescue
+ test_ok(false)
+end
+
+test_ok(eval("$foo") == 'test_ok(true)')
+test_ok(eval("true") == true)
+i = 5
+test_ok(eval("i == 5"))
+test_ok(eval("i") == 5)
+test_ok(eval("defined? i"))
+
+# eval with binding
+def test_ev
+ local1 = "local1"
+ lambda {
+ local2 = "local2"
+ return binding
+ }.call
+end
+
+$x = test_ev
+test_ok(eval("local1", $x) == "local1") # normal local var
+test_ok(eval("local2", $x) == "local2") # nested local var
+$bad = true
+begin
+ p eval("local1")
+rescue NameError # must raise error
+ $bad = false
+end
+test_ok(!$bad)
+
+module EvTest
+ EVTEST1 = 25
+ evtest2 = 125
+ $x = binding
+end
+test_ok(eval("EVTEST1", $x) == 25) # constant in module
+test_ok(eval("evtest2", $x) == 125) # local var in module
+$bad = true
+begin
+ eval("EVTEST1")
+rescue NameError # must raise error
+ $bad = false
+end
+test_ok(!$bad)
+
+x = binding #! YARV Limitation: Proc.new{}
+eval "i4 = 1", x
+test_ok(eval("i4", x) == 1)
+x = Proc.new{binding}.call #! YARV Limitation: Proc.new{Proc.new{}}.call
+eval "i4 = 22", x
+test_ok(eval("i4", x) == 22)
+$x = []
+x = Proc.new{binding}.call #! YARV Limitation: Proc.new{Proc.new{}}.call
+eval "(0..9).each{|i5| $x[i5] = Proc.new{i5*2}}", x
+test_ok($x[4].call == 8)
+
+x = binding
+eval "i = 1", x
+test_ok(eval("i", x) == 1)
+x = Proc.new{binding}.call
+eval "i = 22", x
+test_ok(eval("i", x) == 22)
+$x = []
+x = Proc.new{binding}.call
+eval "(0..9).each{|i5| $x[i5] = Proc.new{i5*2}}", x
+test_ok($x[4].call == 8)
+x = Proc.new{binding}.call
+eval "for i6 in 1..1; j6=i6; end", x
+test_ok(eval("defined? i6", x))
+test_ok(eval("defined? j6", x))
+
+Proc.new {
+ p = binding
+ eval "foo11 = 1", p
+ foo22 = 5
+ Proc.new{foo11=22}.call
+ Proc.new{foo22=55}.call
+ test_ok(eval("foo11", p) == eval("foo11"))
+ test_ok(eval("foo11") == 1)
+ test_ok(eval("foo22", p) == eval("foo22"))
+ test_ok(eval("foo22") == 55)
+}.call if false #! YARV Limitation
+
+#! YARV Limitation: p1 = Proc.new{i7 = 0; Proc.new{i7}}.call
+p1 = Proc.new{i7 = 0; binding}.call
+#! YARV Limitation: test_ok(p1.call == 0)
+eval "i7=5", p1
+#! YARV Limitation: test_ok(p1.call == 5)
+test_ok(!defined?(i7))
+
+if false #! YARV Limitation
+p1 = Proc.new{i7 = 0; Proc.new{i7}}.call
+i7 = nil
+test_ok(p1.call == 0)
+eval "i7=1", p1
+test_ok(p1.call == 1)
+eval "i7=5", p1
+test_ok(p1.call == 5)
+test_ok(i7 == nil)
+end
+
+test_check "system"
+test_ok(`echo foobar` == "foobar\n")
+test_ok(`./miniruby -e 'print "foobar"'` == 'foobar')
+
+script_tmp = "script_tmp.#{$$}"
+tmp = open(script_tmp, "w")
+tmp.print "print $zzz\n";
+tmp.close
+
+test_ok(`./miniruby -s #{script_tmp} -zzz` == 'true')
+test_ok(`./miniruby -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
+
+test_ok(`./miniruby #{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
+
+test_ok(`./miniruby -x #{script_tmp}` == '')
+test_ok(`./miniruby -x #{script_tmp} -zzz=555` == '555')
+
+tmp = open(script_tmp, "w")
+for i in 1..5
+ tmp.print i, "\n"
+end
+tmp.close
+
+`./miniruby -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
+test_ok(done)
+
+File.unlink script_tmp or `/bin/rm -f "#{script_tmp}"`
+File.unlink "#{script_tmp}.bak" or `/bin/rm -f "#{script_tmp}.bak"`
+
+test_check "const"
+TEST1 = 1
+TEST2 = 2
+
+module Const
+ TEST3 = 3
+ TEST4 = 4
+end
+
+module Const2
+ TEST3 = 6
+ TEST4 = 8
+end
+
+include Const
+
+test_ok([TEST1,TEST2,TEST3,TEST4] == [1,2,3,4])
+
+include Const2
+STDERR.print "intentionally redefines TEST3, TEST4\n" if $VERBOSE
+test_ok([TEST1,TEST2,TEST3,TEST4] == [1,2,6,8])
+
+
+test_ok((String <=> Object) == -1)
+test_ok((Object <=> String) == 1)
+test_ok((Array <=> String) == nil)
+
+test_check "clone"
+foo = Object.new
+def foo.test
+ "test"
+end
+bar = foo.clone
+def bar.test2
+ "test2"
+end
+
+test_ok(bar.test2 == "test2")
+test_ok(bar.test == "test")
+test_ok(foo.test == "test")
+
+begin
+ foo.test2
+ test_ok false
+rescue NoMethodError
+ test_ok true
+end
+
+module M001; end
+module M002; end
+module M003; include M002; end
+module M002; include M001; end
+module M003; include M002; end
+
+test_ok(M003.ancestors == [M003, M002, M001])
+
+test_check "marshal"
+$x = [1,2,3,[4,5,"foo"],{1=>"bar"},2.5,fact(30)]
+$y = Marshal.dump($x)
+test_ok($x == Marshal.load($y))
+
+StrClone=String.clone;
+test_ok(Marshal.load(Marshal.dump(StrClone.new("abc"))).class == StrClone)
+
+[[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z|
+ a = (x.to_f + y.to_f / z.to_f) * Math.exp(w.to_f / (x.to_f + y.to_f / z.to_f))
+ ma = Marshal.dump(a)
+ b = Marshal.load(ma)
+ test_ok(a == b)
+}
+
+test_check "pack"
+
+$format = "c2x5CCxsdils_l_a6";
+# 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,-32767,-123456,"abcdef"]
+$x = ary.pack($format)
+ary2 = $x.unpack($format)
+
+test_ok(ary.length == ary2.length)
+test_ok(ary.join(':') == ary2.join(':'))
+test_ok($x =~ /def/)
+
+$x = [-1073741825]
+test_ok($x.pack("q").unpack("q") == $x)
+
+test_check "math"
+test_ok(Math.sqrt(4) == 2)
+
+include Math
+test_ok(sqrt(4) == 2)
+
+test_check "struct"
+struct_test = Struct.new("Test", :foo, :bar)
+test_ok(struct_test == Struct::Test)
+
+test = struct_test.new(1, 2)
+test_ok(test.foo == 1 && test.bar == 2)
+test_ok(test[0] == 1 && test[1] == 2)
+
+a, b = test.to_a
+test_ok(a == 1 && b == 2)
+
+test[0] = 22
+test_ok(test.foo == 22)
+
+test.bar = 47
+test_ok(test.bar == 47)
+
+test_check "variable"
+test_ok($$.instance_of?(Fixnum))
+
+# read-only variable
+begin
+ $$ = 5
+ test_ok false
+rescue NameError
+ test_ok true
+end
+
+foobar = "foobar"
+$_ = foobar
+test_ok($_ == foobar)
+
+class Gods
+ @@rule = "Uranus" # private to Gods
+ def ruler0
+ @@rule
+ end
+
+ def self.ruler1 # <= per method definition style
+ @@rule
+ end
+ class << self # <= multiple method definition style
+ def ruler2
+ @@rule
+ end
+ end
+end
+
+module Olympians
+ @@rule ="Zeus"
+ def ruler3
+ @@rule
+ end
+end
+
+class Titans < Gods
+ @@rule = "Cronus" # do not affect @@rule in Gods
+ include Olympians
+ def ruler4
+ @@rule
+ end
+end
+
+test_ok(Gods.new.ruler0 == "Cronus")
+test_ok(Gods.ruler1 == "Cronus")
+test_ok(Gods.ruler2 == "Cronus")
+test_ok(Titans.ruler1 == "Cronus")
+test_ok(Titans.ruler2 == "Cronus")
+atlas = Titans.new
+test_ok(atlas.ruler0 == "Cronus")
+test_ok(atlas.ruler3 == "Zeus")
+test_ok(atlas.ruler4 == "Cronus")
+
+test_check "trace"
+$x = 1234
+$y = 0
+trace_var :$x, Proc.new{$y = $x}
+$x = 40414
+test_ok($y == $x)
+
+untrace_var :$x
+$x = 19660208
+test_ok($y != $x)
+
+trace_var :$x, Proc.new{$x *= 2}
+$x = 5
+test_ok($x == 10)
+
+untrace_var :$x
+
+test_check "defined?"
+
+test_ok(defined?($x)) # global variable
+test_ok(defined?($x) == 'global-variable')# returns description
+
+foo=5
+test_ok(defined?(foo)) # local variable
+
+test_ok(defined?(Array)) # constant
+test_ok(defined?(Object.new)) # method
+test_ok(!defined?(Object.print))# private method
+test_ok(defined?(1 == 2)) # operator expression
+
+class Foo
+ def foo
+ p :foo
+ end
+ protected :foo
+ def bar(f)
+ test_ok(defined?(self.foo))
+ test_ok(defined?(f.foo))
+ end
+end
+f = Foo.new
+test_ok(defined?(f.foo) == nil)
+f.bar(f)
+
+def defined_test
+ return !defined?(yield)
+end
+
+test_ok(defined_test) # not iterator
+test_ok(!defined_test{}) # called as iterator
+
+test_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
+test_ok(x.bar == "foo")
+test_ok(x.baz == "foo+foo")
+
+# test_check for cache
+test_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
+test_ok(!x.foo)
+test_ok(x.bar)
+test_ok(!x.quux)
+
+test_check "path"
+test_ok(File.basename("a") == "a")
+test_ok(File.basename("a/b") == "b")
+test_ok(File.basename("a/b/") == "b")
+test_ok(File.basename("/") == "/")
+test_ok(File.basename("//") == "/")
+test_ok(File.basename("///") == "/")
+test_ok(File.basename("a/b////") == "b")
+test_ok(File.basename("a.rb", ".rb") == "a")
+test_ok(File.basename("a.rb///", ".rb") == "a")
+test_ok(File.basename("a.rb///", ".*") == "a")
+test_ok(File.basename("a.rb///", ".c") == "a.rb")
+test_ok(File.dirname("a") == ".")
+test_ok(File.dirname("/") == "/")
+test_ok(File.dirname("/a") == "/")
+test_ok(File.dirname("a/b") == "a")
+test_ok(File.dirname("a/b/c") == "a/b")
+test_ok(File.dirname("/a/b/c") == "/a/b")
+test_ok(File.dirname("/a/b/") == "/a")
+test_ok(File.dirname("/a/b///") == "/a")
+case Dir.pwd
+when %r'\A\w:'
+ test_ok(/\A\w:\/\z/ =~ File.expand_path(".", "/"))
+ test_ok(/\A\w:\/a\z/ =~ File.expand_path("a", "/"))
+ dosish = true
+when %r'\A//'
+ test_ok(%r'\A//[^/]+/[^/]+\z' =~ File.expand_path(".", "/"))
+ test_ok(%r'\A//[^/]+/[^/]+/a\z' =~ File.expand_path(".", "/"))
+ dosish = true
+else
+ test_ok(File.expand_path(".", "/") == "/")
+ test_ok(File.expand_path("sub", "/") == "/sub")
+end
+if dosish
+ test_ok(File.expand_path("/", "//machine/share/sub") == "//machine/share")
+ test_ok(File.expand_path("/dir", "//machine/share/sub") == "//machine/share/dir")
+ test_ok(File.expand_path("/", "z:/sub") == "z:/")
+ test_ok(File.expand_path("/dir", "z:/sub") == "z:/dir")
+end
+test_ok(File.expand_path(".", "//") == "//")
+test_ok(File.expand_path("sub", "//") == "//sub")
+
+# test_check "Proc#binding"
+ObjectSpace.each_object(Proc){|o|
+ begin
+ b = o.binding
+ eval 'self', b
+ rescue ArgumentError
+ end
+}
+
+test_check "gc"
+begin
+ 1.upto(10000) {
+ tmp = [0,1,2,3,4,5,6,7,8,9]
+ }
+ tmp = nil
+ test_ok true
+rescue
+ test_ok false
+end
+class S
+ def initialize(a)
+ @a = a
+ end
+end
+l=nil
+100000.times {
+ l = S.new(l)
+}
+GC.start
+test_ok true # reach here or dumps core
+l = []
+100000.times {
+ l.push([l])
+}
+GC.start
+test_ok true # reach here or dumps core
+
+ObjectSpace.each_object{|o|
+ o.class.name
+}
+
+test_ok true # reach here or dumps core
+
+PROGRESS.finish
+if $failed > 0
+ printf "not ok/test: %d failed %d\n", $ntest, $failed
+else
+ printf "end of test(test: %d)\n", $ntest
+end
diff --git a/jni/ruby/sample/testunit/adder.rb b/jni/ruby/sample/testunit/adder.rb
new file mode 100644
index 0000000..aa5c88c
--- /dev/null
+++ b/jni/ruby/sample/testunit/adder.rb
@@ -0,0 +1,13 @@
+# Author:: Nathaniel Talbott.
+# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
+# License:: Ruby license.
+
+class Adder
+ def initialize(number)
+ @number = number
+ end
+ def add(number)
+ return @number + number
+ end
+end
+
diff --git a/jni/ruby/sample/testunit/subtracter.rb b/jni/ruby/sample/testunit/subtracter.rb
new file mode 100644
index 0000000..2c08247
--- /dev/null
+++ b/jni/ruby/sample/testunit/subtracter.rb
@@ -0,0 +1,12 @@
+# Author:: Nathaniel Talbott.
+# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
+# License:: Ruby license.
+
+class Subtracter
+ def initialize(number)
+ @number = number
+ end
+ def subtract(number)
+ return @number - number
+ end
+end
diff --git a/jni/ruby/sample/testunit/tc_adder.rb b/jni/ruby/sample/testunit/tc_adder.rb
new file mode 100644
index 0000000..8453beb
--- /dev/null
+++ b/jni/ruby/sample/testunit/tc_adder.rb
@@ -0,0 +1,18 @@
+# Author:: Nathaniel Talbott.
+# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
+# License:: Ruby license.
+
+require 'test/unit'
+require 'adder'
+
+class TC_Adder < Test::Unit::TestCase
+ def setup
+ @adder = Adder.new(5)
+ end
+ def test_add
+ assert_equal(7, @adder.add(2), "Should have added correctly")
+ end
+ def teardown
+ @adder = nil
+ end
+end
diff --git a/jni/ruby/sample/testunit/tc_subtracter.rb b/jni/ruby/sample/testunit/tc_subtracter.rb
new file mode 100644
index 0000000..d2c8313
--- /dev/null
+++ b/jni/ruby/sample/testunit/tc_subtracter.rb
@@ -0,0 +1,18 @@
+# Author:: Nathaniel Talbott.
+# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
+# License:: Ruby license.
+
+require 'test/unit'
+require 'subtracter'
+
+class TC_Subtracter < Test::Unit::TestCase
+ def setup
+ @subtracter = Subtracter.new(5)
+ end
+ def test_subtract
+ assert_equal(3, @subtracter.subtract(2), "Should have subtracted correctly")
+ end
+ def teardown
+ @subtracter = nil
+ end
+end
diff --git a/jni/ruby/sample/testunit/ts_examples.rb b/jni/ruby/sample/testunit/ts_examples.rb
new file mode 100644
index 0000000..3d24dd6
--- /dev/null
+++ b/jni/ruby/sample/testunit/ts_examples.rb
@@ -0,0 +1,7 @@
+# Author:: Nathaniel Talbott.
+# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
+# License:: Ruby license.
+
+require 'test/unit'
+require 'tc_adder'
+require 'tc_subtracter'
diff --git a/jni/ruby/sample/time.rb b/jni/ruby/sample/time.rb
new file mode 100644
index 0000000..e169120
--- /dev/null
+++ b/jni/ruby/sample/time.rb
@@ -0,0 +1,12 @@
+#! /usr/bin/env ruby
+
+b = Time.now
+system(*ARGV)
+e = Time.now
+
+tms = Process.times
+real = e - b
+user = tms.cutime
+sys = tms.cstime
+
+STDERR.printf("%11.1f real %11.1f user %11.1f sys\n", real, user, sys)
diff --git a/jni/ruby/sample/timeout.rb b/jni/ruby/sample/timeout.rb
new file mode 100644
index 0000000..8d25d72
--- /dev/null
+++ b/jni/ruby/sample/timeout.rb
@@ -0,0 +1,42 @@
+require 'timeout'
+
+def progress(n = 5)
+ n.times {|i| print i; STDOUT.flush; sleep 1; i+= 1}
+ puts "never reach"
+end
+
+p timeout(5) {
+ 45
+}
+p timeout(5, Timeout::Error) {
+ 45
+}
+p timeout(nil) {
+ 54
+}
+p timeout(0) {
+ 54
+}
+begin
+ timeout(5) {progress}
+rescue => e
+ puts e.message
+end
+begin
+ timeout(3) {
+ begin
+ timeout(5) {progress}
+ rescue => e
+ puts "never reach"
+ end
+ }
+rescue => e
+ puts e.message
+end
+class MyTimeout < StandardError
+end
+begin
+ timeout(2, MyTimeout) {progress}
+rescue MyTimeout => e
+ puts e.message
+end
diff --git a/jni/ruby/sample/trick2013/README.md b/jni/ruby/sample/trick2013/README.md
new file mode 100644
index 0000000..65f1d3b
--- /dev/null
+++ b/jni/ruby/sample/trick2013/README.md
@@ -0,0 +1,13 @@
+This directory contains the award-winning entries of
+the 1st Transcendental Ruby Imbroglio Contest for rubyKaigi (TRICK 2013).
+
+THESE ARE BAD EXAMPLES! You must NOT use them as a sample code.
+
+* kinaba/entry.rb: "Best pangram" - Gold award
+* mame/entry.rb: "Most classic" - Bronze award
+* shinh/entry.rb: "Most Readable" - Silver award
+* yhara/entry.rb: "Worst abuse of constants" - Dishonorable mention
+
+For the contest outline and other winning entries, see:
+
+https://github.com/tric/trick2013
diff --git a/jni/ruby/sample/trick2013/kinaba/authors.markdown b/jni/ruby/sample/trick2013/kinaba/authors.markdown
new file mode 100644
index 0000000..84c011e
--- /dev/null
+++ b/jni/ruby/sample/trick2013/kinaba/authors.markdown
@@ -0,0 +1,3 @@
+* kinaba
+ * kiki@kmonos.net
+ * cctld: jp
diff --git a/jni/ruby/sample/trick2013/kinaba/entry.rb b/jni/ruby/sample/trick2013/kinaba/entry.rb
new file mode 100644
index 0000000..8a3f855
--- /dev/null
+++ b/jni/ruby/sample/trick2013/kinaba/entry.rb
@@ -0,0 +1 @@
+!@THEqQUICKbBROWNfFXjJMPSvVLAZYDGgkyz&[%r{\"}mosx,4>6]|?'while(putc 3_0-~$.+=9/2^5;)<18*7and:`#
diff --git a/jni/ruby/sample/trick2013/kinaba/remarks.markdown b/jni/ruby/sample/trick2013/kinaba/remarks.markdown
new file mode 100644
index 0000000..e35550e
--- /dev/null
+++ b/jni/ruby/sample/trick2013/kinaba/remarks.markdown
@@ -0,0 +1,37 @@
+### Remarks
+
+Just run it with no argument:
+
+ ruby entry.rb
+
+I confirmed the following implementations/platforms:
+
+* ruby 2.0.0p0 (2013-02-24) [i386-mswin32\_100]
+
+### Description
+
+The program prints each ASCII character from 0x20 ' ' to 0x7e '~' exactly once.
+
+The program contains each ASCII character from 0x20 ' ' to 0x7e '~' exactly once.
+
+### Internals
+
+The algorthim is the obvious loop "32.upto(126){|x| putc x}".
+
+It is not so hard to transform it to use each character *at most once*. Only the slight difficulty comes from the constraint that we cannot "declare and then use" variables, because then the code will contain the variable name twice. This restriction is worked around by the $. global variable, the best friend of Ruby golfers.
+
+The relatively interesting part is to use all the charcters *at least once*. Of course, this is easily accomplished by putting everything into a comment (i.e., #unsed...) or to a string literal (%(unused...), note that normal string literals are forbidden since they use quotation marks twice). Hey, but that's not fun at all! I tried to minimize the escapeway.
+
+* "@THEqQUICKbBROWNfFXjJMPSvVLAZYDGgkyz". Trash box of unused alphabet. I with I could have used "gkyz" somewhere else.
+
+* "%r{\"}mosx". Regex literal, with %-syntax. I don't even know what each m,o,s,x means...
+
+* "?'" Symbol literal. The quote characters (' " \`) are the first obstacle to this trial because they have to be used in pair usually. These are escaped as \" and ?' and :\`.
+
+* "4>6" "3\_0-~$.+=9/2^5" "18\*7". I had to consume many arithmetic operators +-\*/^~<>, but I only have ten literals 0 to 9 and $. as operands. Besides I have to express the print loop. This is an interesting puzzle.
+
+* "(putc ...;)<18*7". Trail semicolon doesn't change the value of the expression.
+
+### Limitation
+
+n/a.
diff --git a/jni/ruby/sample/trick2013/mame/authors.markdown b/jni/ruby/sample/trick2013/mame/authors.markdown
new file mode 100644
index 0000000..e99cd71
--- /dev/null
+++ b/jni/ruby/sample/trick2013/mame/authors.markdown
@@ -0,0 +1,3 @@
+* Yusuke Endoh
+ * mame@tsg.ne.jp
+ * cctld: jp
diff --git a/jni/ruby/sample/trick2013/mame/entry.rb b/jni/ruby/sample/trick2013/mame/entry.rb
new file mode 100644
index 0000000..8abfc2b
--- /dev/null
+++ b/jni/ruby/sample/trick2013/mame/entry.rb
@@ -0,0 +1,97 @@
+ eval$C=%q(at_exit{
+ open("/dev/dsp","wb"){|g|h=[0]*80
+ $><<"\s"*18+"eval$C=%q(#$C);S=%:"
+ (S<<m=58).lines{|l|s=[128]*n=20E2
+ t=0; h.map!{|v|d=?!==l[
+ t]?1 :(l[
+ t]== ?#)?
+ 0*v= 6:03
+ (v<1 ?[]:
+ 0..n -1).
+ each {|z|
+ s[z] +=2*
+ M.sin(($*[0] ||1)
+ .to_f*M.sin(y= 40*(z+m)*2**
+ (t/12E0)/463)+ y)*(v-z*d/n)};
+ t+=1;v-d};m+= n;g.flush<<(s.
+ pack"C*"); puts(l)}}};M=
+ Math);S=%:
+
+ Jesu, Joy of Man's Desiring
+ Johann Sebastian Bach
+
+ #
+ | #
+ | #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | #
+ # # # #
+ | | | #
+ | #| #
+ # # | #
+ | | | #
+ | | # #
+ # # # #
+ | | # |
+ | | # #
+ # # # #
+ | | | #
+ | | #
+ # # # #
+ | | # |
+ | # # |
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | | # #
+ # # # #
+ | | | #
+ | # #
+ # # #
+ | | | #
+ | # | #
+ # # # #
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | :
diff --git a/jni/ruby/sample/trick2013/mame/music-box.mp4 b/jni/ruby/sample/trick2013/mame/music-box.mp4
new file mode 100644
index 0000000..6d1e87c
--- /dev/null
+++ b/jni/ruby/sample/trick2013/mame/music-box.mp4
Binary files differ
diff --git a/jni/ruby/sample/trick2013/mame/remarks.markdown b/jni/ruby/sample/trick2013/mame/remarks.markdown
new file mode 100644
index 0000000..8c1988c
--- /dev/null
+++ b/jni/ruby/sample/trick2013/mame/remarks.markdown
@@ -0,0 +1,47 @@
+### Remarks
+
+Run the program under a platform that `/dev/dsp` is available.
+For example, if you are using pulseaudio, use `padsp`:
+
+ padsp ruby entry.rb
+
+Please see Limitation if you want to run this program on os x.
+
+I confirmed the following platforms.
+
+* ruby 2.0.0p0 (2013-02-24 revision 39474) [x86\_64-linux]
+* ruby 1.9.3p194 (2012-04-20 revision 35410) [x86\_64-linux]
+* ruby 1.9.3p327 (2012-11-10 revision 37606) [x86\_64-darwin10.8.0]
+
+For those who are lazy, I'm attaching a screencast.
+
+### Description
+
+This program is a music-box quine.
+It prints itself with playing "Jesu, Joy of Man's Desiring".
+
+### Internal
+
+Like a real music box, this program consists of a mechanical part (code) and a piano roll.
+In the piano roll, `#` represents a pin that hits a note, and `|` represents a slur.
+The leftmost column corresponds 110Hz (low A).
+Every column corresponds a semitone higher than the left one.
+
+This program uses [the frequency modulation synthesis](http://en.wikipedia.org/wiki/Frequency_modulation_synthesis) to play the sound like a music-box.
+You can create a different-sounding tone by changing the parameter.
+For example, the following will play the sound like a harpsichord.
+
+ padsp ruby entry.rb 2.0
+
+Note that this program does *not* use an idiom to remove whitespace, such as `.split.join`. All newlines and spaces do not violate any of the Ruby syntax rules.
+
+### Limitation
+
+On os x, `/dev/dsp` is not available.
+You have to use sox by replacing the following part:
+
+ open("/dev/dsp","wb")
+
+with:
+
+ IO.popen("./pl","wb") \ No newline at end of file
diff --git a/jni/ruby/sample/trick2013/shinh/authors.markdown b/jni/ruby/sample/trick2013/shinh/authors.markdown
new file mode 100644
index 0000000..7ea2298
--- /dev/null
+++ b/jni/ruby/sample/trick2013/shinh/authors.markdown
@@ -0,0 +1,2 @@
+Shinichiro Hamaji
+Japan, .jp
diff --git a/jni/ruby/sample/trick2013/shinh/entry.rb b/jni/ruby/sample/trick2013/shinh/entry.rb
new file mode 100644
index 0000000..cd45173
--- /dev/null
+++ b/jni/ruby/sample/trick2013/shinh/entry.rb
@@ -0,0 +1,10 @@
+begin with an easy program.
+you should be able to write
+a program unless for you,
+program in ruby language is
+too difficult. At the end
+of your journey towards the
+ultimate program; you must
+be a part of a programming
+language. You will end if
+you != program
diff --git a/jni/ruby/sample/trick2013/shinh/remarks.markdown b/jni/ruby/sample/trick2013/shinh/remarks.markdown
new file mode 100644
index 0000000..1cd190d
--- /dev/null
+++ b/jni/ruby/sample/trick2013/shinh/remarks.markdown
@@ -0,0 +1,4 @@
+This program is a meaningless poem.
+This does nothing for you.
+Almost everything in this code is junk,
+but you and program would confuse you a bit.
diff --git a/jni/ruby/sample/trick2013/yhara/authors.markdown b/jni/ruby/sample/trick2013/yhara/authors.markdown
new file mode 100644
index 0000000..c0adc2b
--- /dev/null
+++ b/jni/ruby/sample/trick2013/yhara/authors.markdown
@@ -0,0 +1,3 @@
+* Yutaka Hara
+ * yutaka.hara.gmail.com
+ * cctld: jp
diff --git a/jni/ruby/sample/trick2013/yhara/entry.rb b/jni/ruby/sample/trick2013/yhara/entry.rb
new file mode 100644
index 0000000..a2deb54
--- /dev/null
+++ b/jni/ruby/sample/trick2013/yhara/entry.rb
@@ -0,0 +1,28 @@
+def _(&b)$><<->(x){x ? (String===x ?x.upcase:
+(Class===x ? x : x.class).name[$a?0:($a=5)]):
+" "}[ begin b[];rescue Exception;$!;end ] end
+
+_ { return }
+_ { method(:p).unbind }
+_ { eval "{ " }
+_ { Thread.current.join }
+_ { nil }
+_ { select }
+_ { ruby }
+_ { self.class }
+_ { Thread.current.group }
+_ { nil.to_h }
+_ { "\xFF".encode("big5") }
+_ { raise }
+_ { [0][1] }
+_ { Regexp.compile "*" }
+_ { RUBY_COPYRIGHT[32] }
+_ { binding }
+_ { :s.class.name[1] }
+_ { warn }
+_ { [a: :b][0] }
+_ { methods }
+_ { IO.class }
+_ { {}.fetch(0) }
+_ { open " " }
+_ { 1000000.chr }
diff --git a/jni/ruby/sample/trick2013/yhara/remarks.en.markdown b/jni/ruby/sample/trick2013/yhara/remarks.en.markdown
new file mode 100644
index 0000000..bd821e8
--- /dev/null
+++ b/jni/ruby/sample/trick2013/yhara/remarks.en.markdown
@@ -0,0 +1,23 @@
+### Remarks
+
+Just run it with no argument:
+
+ ruby entry.rb
+
+I confirmed the following implementations/platforms:
+
+* ruby 2.0.0p0 (2013-02-24 revision 39474) [x86\_64-darwin12.2.1]
+
+### Description
+
+It prints JUST ANOTHER RUBY HACKER¡£
+
+### Internals
+
+This script uses characters in constants in Object class. It
+intentionally raises some exceptions. The second 'U' comes from
+RUBY\_COPYRIGHT, "Yukihiro Matsumoto".
+
+### Limitation
+
+This program does not work on JRuby because "return" does not raise an exception.
diff --git a/jni/ruby/sample/trick2013/yhara/remarks.markdown b/jni/ruby/sample/trick2013/yhara/remarks.markdown
new file mode 100644
index 0000000..99cb4b5
--- /dev/null
+++ b/jni/ruby/sample/trick2013/yhara/remarks.markdown
@@ -0,0 +1,24 @@
+### Remarks
+
+引数ãªã—ã§æ™®é€šã«å®Ÿè¡Œã—ã¦ãã ã•ã„。
+
+ ruby entry.rb
+
+以下ã®å®Ÿè£…・プラットフォームã§å‹•ä½œç¢ºèªã—ã¦ã„ã¾ã™ã€‚
+
+* ruby 2.0.0p0 (2013-02-24 revision 39474) [x86\_64-darwin12.2.1]
+
+### Description
+
+JUST ANOTHER RUBY HACKERã¨è¡¨ç¤ºã—ã¾ã™ã€‚
+
+### Internals
+
+Objectクラスã®å®šæ•°ã‹ã‚‰æ–‡å­—を拾ã£ã¦ã„ã¾ã™ã€‚
+ãã®ãŸã‚ã«ã€æ„図的ã«ä¾‹å¤–ã‚’èµ·ã“ã—ã¦ã„ã¾ã™ã€‚
+「Uã€ãŒä¸€ã¤ã—ã‹è¦‹ã¤ã‹ã‚‰ãªã‹ã£ãŸã®ã§ã€ã‚‚ã†ä¸€å€‹ã¯RUBY\_COPYRIGHTã®
+「Yukihiro Matsumotoã€ã‹ã‚‰å–ã£ã¦ã„ã¾ã™ã€‚
+
+### Limitation
+
+JRubyã¯returnãŒã‚¨ãƒ©ãƒ¼ã«ãªã‚‰ãªãã¦ã€å‹•ãã¾ã›ã‚“ã§ã—ãŸã€‚
diff --git a/jni/ruby/sample/trojan.rb b/jni/ruby/sample/trojan.rb
new file mode 100644
index 0000000..cea0dae
--- /dev/null
+++ b/jni/ruby/sample/trojan.rb
@@ -0,0 +1,15 @@
+#! /usr/local/bin/ruby
+
+path = ENV['PATH'].split(File::PATH_SEPARATOR)
+
+for dir in path
+ if File.directory?(dir)
+ for f in d = Dir.open(dir)
+ fpath = File.join(dir, f)
+ if File.file?(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/jni/ruby/sample/tsvr.rb b/jni/ruby/sample/tsvr.rb
new file mode 100644
index 0000000..2fa6c87
--- /dev/null
+++ b/jni/ruby/sample/tsvr.rb
@@ -0,0 +1,20 @@
+# socket example - server side using thread
+# usage: ruby tsvr.rb
+
+require "socket"
+
+gs = TCPServer.open(0)
+addr = gs.addr
+addr.shift
+printf("server is on %s\n", addr.join(":"))
+
+loop do
+ Thread.start(gs.accept) do |s|
+ print(s, " is accepted\n")
+ while line = s.gets
+ s.write(line)
+ end
+ print(s, " is gone\n")
+ s.close
+ end
+end
diff --git a/jni/ruby/sample/uumerge.rb b/jni/ruby/sample/uumerge.rb
new file mode 100644
index 0000000..2576bcb
--- /dev/null
+++ b/jni/ruby/sample/uumerge.rb
@@ -0,0 +1,43 @@
+#!/usr/bin/env ruby
+
+if ARGV[0] == "-c"
+ out_stdout = 1
+ ARGV.shift
+end
+
+$sawbegin = 0
+$sawend = 0
+
+while line = gets()
+ if /^begin\s*(\d*)\s*(\S*)/ =~ line
+ $mode, $file = $1, $2
+ $sawbegin+=1
+ if out_stdout
+ out = STDOUT
+ else
+ out = open($file, "w") if $file != ""
+ end
+ out.binmode
+ break
+ end
+end
+
+raise "missing begin" unless $sawbegin
+
+out.binmode
+while line = gets()
+ if /^end/ =~ line
+ $sawend+=1
+ out.close unless out_stdout
+ File.chmod $mode.oct, $file unless out_stdout
+ next
+ end
+ line.sub!(/[a-z]+$/, "") # handle stupid trailing lowercase letters
+ next if /[a-z]/ =~ line
+ next if !(((($_[0] - 32) & 077) + 2) / 3 == $_.length / 4)
+ out << $_.unpack("u") if $sawbegin > $sawend
+end
+
+raise "missing end" if $sawbegin > $sawend
+raise "missing begin" if ! $sawbegin
+exit 0
diff --git a/jni/ruby/sample/weakref.rb b/jni/ruby/sample/weakref.rb
new file mode 100644
index 0000000..b9f38f9
--- /dev/null
+++ b/jni/ruby/sample/weakref.rb
@@ -0,0 +1,9 @@
+require 'weakref'
+
+foo = Object.new
+p foo.to_s # original's class
+foo = WeakRef.new(foo)
+p foo.to_s # should be same class
+ObjectSpace.garbage_collect
+ObjectSpace.garbage_collect
+p foo.to_s # should raise exception (recycled)
diff --git a/jni/ruby/sample/webrick/demo-app.rb b/jni/ruby/sample/webrick/demo-app.rb
new file mode 100644
index 0000000..c7a2a0a
--- /dev/null
+++ b/jni/ruby/sample/webrick/demo-app.rb
@@ -0,0 +1,66 @@
+require "pp"
+
+module DemoApplication
+ def initialize(config, enctype)
+ super
+ @enctype = enctype
+ end
+
+ def do_GET(req, res)
+ if req.path_info != "/"
+ res.set_redirect(WEBrick::HTTPStatus::Found, req.script_name + "/")
+ end
+ res.body =<<-_end_of_html_
+ <HTML>
+ <FORM method="POST" enctype=#{@enctype}>
+ text: <INPUT type="text" name="text"><BR>
+ file: <INPUT type="file" name="file"><BR>
+ check:
+ <INPUT type="checkbox" name="check" value="a">a,
+ <INPUT type="checkbox" name="check" value="b">b,
+ <INPUT type="checkbox" name="check" value="c">c,
+ <BR>
+ <INPUT type="submit">
+ </FORM>
+ </HTML>
+ _end_of_html_
+ res['content-type'] = 'text/html; charset=iso-8859-1'
+ end
+
+ def do_POST(req, res)
+ if req["content-length"].to_i > 1024*10
+ raise WEBrick::HTTPStatus::Forbidden, "file size too large"
+ end
+ res.body =<<-_end_of_html_
+ <HTML>
+ <H2>Query Parameters</H2>
+ #{display_query(req.query)}
+ <A href="#{req.path}">return</A>
+ <H2>Request</H2>
+ <PRE>#{WEBrick::HTMLUtils::escape(PP::pp(req, "", 80))}</PRE>
+ <H2>Response</H2>
+ <PRE>#{WEBrick::HTMLUtils::escape(PP::pp(res, "", 80))}</PRE>
+ </HTML>
+ _end_of_html_
+ res['content-type'] = 'text/html; charset=iso-8859-1'
+ end
+
+ private
+
+ def display_query(q)
+ ret = ""
+ q.each{|key, val|
+ ret << "<H3>#{WEBrick::HTMLUtils::escape(key)}</H3>"
+ ret << "<TABLE border=1>"
+ ret << make_tr("val", val.inspect)
+ ret << make_tr("val.to_a", val.to_a.inspect)
+ ret << make_tr("val.to_ary", val.to_ary.inspect)
+ ret << "</TABLE>"
+ }
+ ret
+ end
+
+ def make_tr(arg0, arg1)
+ "<TR><TD>#{arg0}</TD><TD>#{WEBrick::HTMLUtils::escape(arg1)}</TD></TR>"
+ end
+end
diff --git a/jni/ruby/sample/webrick/demo-multipart.cgi b/jni/ruby/sample/webrick/demo-multipart.cgi
new file mode 100644
index 0000000..0893fad
--- /dev/null
+++ b/jni/ruby/sample/webrick/demo-multipart.cgi
@@ -0,0 +1,12 @@
+#!/usr/bin/env ruby
+require "webrick/cgi"
+require "webrick/https" # should load if it runs on HTTPS server
+require "./demo-app"
+
+class DemoCGI < WEBrick::CGI
+ include DemoApplication
+end
+
+config = { :NPH => false }
+cgi = DemoCGI.new(config, "multipart/form-data")
+cgi.start
diff --git a/jni/ruby/sample/webrick/demo-servlet.rb b/jni/ruby/sample/webrick/demo-servlet.rb
new file mode 100644
index 0000000..9c18cc6
--- /dev/null
+++ b/jni/ruby/sample/webrick/demo-servlet.rb
@@ -0,0 +1,6 @@
+require "webrick"
+require "./demo-app"
+
+class DemoServlet < WEBrick::HTTPServlet::AbstractServlet
+ include DemoApplication
+end
diff --git a/jni/ruby/sample/webrick/demo-urlencoded.cgi b/jni/ruby/sample/webrick/demo-urlencoded.cgi
new file mode 100644
index 0000000..e4706f8
--- /dev/null
+++ b/jni/ruby/sample/webrick/demo-urlencoded.cgi
@@ -0,0 +1,12 @@
+#!/usr/bin/env ruby
+require "webrick/cgi"
+require "webrick/https" # should load if it runs on HTTPS server
+require "./demo-app"
+
+class DemoCGI < WEBrick::CGI
+ include DemoApplication
+end
+
+config = { :NPH => false }
+cgi = DemoCGI.new(config, "application/x-www-form-urlencoded")
+cgi.start
diff --git a/jni/ruby/sample/webrick/hello.cgi b/jni/ruby/sample/webrick/hello.cgi
new file mode 100644
index 0000000..35d2240
--- /dev/null
+++ b/jni/ruby/sample/webrick/hello.cgi
@@ -0,0 +1,11 @@
+#!/usr/bin/env ruby
+require "webrick/cgi"
+
+class HelloCGI < WEBrick::CGI
+ def do_GET(req, res)
+ res["content-type"] = "text/plain"
+ res.body = "Hello, world.\n"
+ end
+end
+
+HelloCGI.new.start
diff --git a/jni/ruby/sample/webrick/hello.rb b/jni/ruby/sample/webrick/hello.rb
new file mode 100644
index 0000000..4d02676
--- /dev/null
+++ b/jni/ruby/sample/webrick/hello.rb
@@ -0,0 +1,8 @@
+require "webrick"
+
+class HelloServlet < WEBrick::HTTPServlet::AbstractServlet
+ def do_GET(req, res)
+ res["content-type"] = "text/plain"
+ res.body = "Hello, world.\n"
+ end
+end
diff --git a/jni/ruby/sample/webrick/httpd.rb b/jni/ruby/sample/webrick/httpd.rb
new file mode 100644
index 0000000..b0edf47
--- /dev/null
+++ b/jni/ruby/sample/webrick/httpd.rb
@@ -0,0 +1,23 @@
+require "webrick"
+
+httpd = WEBrick::HTTPServer.new(
+ :DocumentRoot => File::dirname(__FILE__),
+ :Port => 10080,
+ :Logger => WEBrick::Log.new($stderr, WEBrick::Log::DEBUG),
+ :AccessLog => [
+ [ $stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
+ [ $stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
+ [ $stderr, WEBrick::AccessLog::AGENT_LOG_FORMAT ],
+ ],
+ :CGIPathEnv => ENV["PATH"] # PATH environment variable for CGI.
+)
+
+require "./hello"
+httpd.mount("/hello", HelloServlet)
+
+require "./demo-servlet"
+httpd.mount("/urlencoded", DemoServlet, "application/x-www-form-urlencoded")
+httpd.mount("/multipart", DemoServlet, "multipart/form-data")
+
+trap(:INT){ httpd.shutdown }
+httpd.start
diff --git a/jni/ruby/sample/webrick/httpproxy.rb b/jni/ruby/sample/webrick/httpproxy.rb
new file mode 100644
index 0000000..c84457e
--- /dev/null
+++ b/jni/ruby/sample/webrick/httpproxy.rb
@@ -0,0 +1,25 @@
+require "webrick"
+require "webrick/httpproxy"
+
+# The :ProxyContentHandler proc will be invoked before sending a response to
+# the User-Agent. You can inspect the pair of request and response messages
+# (or edit the response message if necessary).
+
+pch = Proc.new{|req, res|
+ p [ req.request_line, res.status_line ]
+}
+
+def upstream_proxy
+ if prx = ENV["http_proxy"]
+ return URI.parse(prx)
+ end
+ return nil
+end
+
+httpd = WEBrick::HTTPProxyServer.new(
+ :Port => 10080,
+ :ProxyContentHandler => pch,
+ :ProxyURI => upstream_proxy
+)
+Signal.trap(:INT){ httpd.shutdown }
+httpd.start
diff --git a/jni/ruby/sample/webrick/httpsd.rb b/jni/ruby/sample/webrick/httpsd.rb
new file mode 100644
index 0000000..a120782
--- /dev/null
+++ b/jni/ruby/sample/webrick/httpsd.rb
@@ -0,0 +1,33 @@
+require "webrick"
+require "webrick/https"
+
+hostname = WEBrick::Utils::getservername
+subject = [["O", "ruby-lang.org"], ["OU", "sample"], ["CN", hostname]]
+comment = "Comment for self-signed certificate"
+
+httpd = WEBrick::HTTPServer.new(
+ :DocumentRoot => File::dirname(__FILE__),
+ :Port => 10443,
+ :SSLEnable => true,
+
+ # Specify key pair and server certificate.
+ # :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.read("server.key")),
+ # :SSLCertificate => OpenSSL::X509::Certificate.new(File.read("server.crt")),
+
+ # specify the following SSL options if you want to use auto
+ # generated self-signed certificate.
+ :SSLCertName => subject,
+ :SSLComment => comment,
+
+ :CGIPathEnv => ENV["PATH"] # PATH environment variable for CGI.
+)
+
+require "./hello"
+httpd.mount("/hello", HelloServlet)
+
+require "./demo-servlet"
+httpd.mount("/urlencoded", DemoServlet, "application/x-www-form-urlencoded")
+httpd.mount("/multipart", DemoServlet, "multipart/form-data")
+
+trap(:INT){ httpd.shutdown }
+httpd.start