summaryrefslogtreecommitdiff
path: root/ruby_1_8_6/sample
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-08-22 01:53:51 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-08-22 01:53:51 +0000
commit1e760c0be3ed35874204114e7454509f740c0fe2 (patch)
treea75eb2b1eea073830902d1fa49c568c4525c8b57 /ruby_1_8_6/sample
parenta2055d63b41a6678dc7aeb17d0bece314e700c5a (diff)
add tag v1_8_6_71v1_8_5_71
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_5_71@13189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ruby_1_8_6/sample')
-rw-r--r--ruby_1_8_6/sample/README52
-rw-r--r--ruby_1_8_6/sample/biorhythm.rb160
-rw-r--r--ruby_1_8_6/sample/cal.rb154
-rw-r--r--ruby_1_8_6/sample/cbreak.rb36
-rw-r--r--ruby_1_8_6/sample/clnt.rb21
-rw-r--r--ruby_1_8_6/sample/dbmtest.rb14
-rw-r--r--ruby_1_8_6/sample/dir.rb12
-rw-r--r--ruby_1_8_6/sample/drb/README.rd56
-rw-r--r--ruby_1_8_6/sample/drb/README.rd.ja59
-rw-r--r--ruby_1_8_6/sample/drb/darray.rb12
-rw-r--r--ruby_1_8_6/sample/drb/darrayc.rb59
-rw-r--r--ruby_1_8_6/sample/drb/dbiff.rb51
-rw-r--r--ruby_1_8_6/sample/drb/dcdbiff.rb43
-rw-r--r--ruby_1_8_6/sample/drb/dchatc.rb41
-rw-r--r--ruby_1_8_6/sample/drb/dchats.rb70
-rw-r--r--ruby_1_8_6/sample/drb/dhasen.rb42
-rw-r--r--ruby_1_8_6/sample/drb/dhasenc.rb13
-rw-r--r--ruby_1_8_6/sample/drb/dlogc.rb16
-rw-r--r--ruby_1_8_6/sample/drb/dlogd.rb39
-rw-r--r--ruby_1_8_6/sample/drb/dqin.rb13
-rw-r--r--ruby_1_8_6/sample/drb/dqlib.rb14
-rw-r--r--ruby_1_8_6/sample/drb/dqout.rb14
-rw-r--r--ruby_1_8_6/sample/drb/dqueue.rb12
-rw-r--r--ruby_1_8_6/sample/drb/drbc.rb45
-rw-r--r--ruby_1_8_6/sample/drb/drbch.rb48
-rw-r--r--ruby_1_8_6/sample/drb/drbm.rb60
-rw-r--r--ruby_1_8_6/sample/drb/drbmc.rb22
-rw-r--r--ruby_1_8_6/sample/drb/drbs-acl.rb51
-rw-r--r--ruby_1_8_6/sample/drb/drbs.rb64
-rw-r--r--ruby_1_8_6/sample/drb/drbssl_c.rb19
-rw-r--r--ruby_1_8_6/sample/drb/drbssl_s.rb31
-rw-r--r--ruby_1_8_6/sample/drb/extserv_test.rb80
-rw-r--r--ruby_1_8_6/sample/drb/gw_ct.rb29
-rw-r--r--ruby_1_8_6/sample/drb/gw_cu.rb28
-rw-r--r--ruby_1_8_6/sample/drb/gw_s.rb10
-rw-r--r--ruby_1_8_6/sample/drb/holderc.rb22
-rw-r--r--ruby_1_8_6/sample/drb/holders.rb63
-rw-r--r--ruby_1_8_6/sample/drb/http0.rb77
-rw-r--r--ruby_1_8_6/sample/drb/http0serv.rb119
-rw-r--r--ruby_1_8_6/sample/drb/name.rb117
-rw-r--r--ruby_1_8_6/sample/drb/namec.rb36
-rw-r--r--ruby_1_8_6/sample/drb/old_tuplespace.rb214
-rw-r--r--ruby_1_8_6/sample/drb/rinda_ts.rb7
-rw-r--r--ruby_1_8_6/sample/drb/rindac.rb17
-rw-r--r--ruby_1_8_6/sample/drb/rindas.rb18
-rw-r--r--ruby_1_8_6/sample/drb/ring_echo.rb30
-rw-r--r--ruby_1_8_6/sample/drb/ring_inspect.rb30
-rw-r--r--ruby_1_8_6/sample/drb/ring_place.rb25
-rw-r--r--ruby_1_8_6/sample/drb/simpletuple.rb91
-rw-r--r--ruby_1_8_6/sample/drb/speedc.rb21
-rw-r--r--ruby_1_8_6/sample/drb/speeds.rb31
-rw-r--r--ruby_1_8_6/sample/dualstack-fetch.rb48
-rw-r--r--ruby_1_8_6/sample/dualstack-httpd.rb55
-rw-r--r--ruby_1_8_6/sample/eval.rb41
-rw-r--r--ruby_1_8_6/sample/export.rb40
-rw-r--r--ruby_1_8_6/sample/exyacc.rb22
-rw-r--r--ruby_1_8_6/sample/fact.rb9
-rw-r--r--ruby_1_8_6/sample/fib.awk5
-rw-r--r--ruby_1_8_6/sample/fib.pl11
-rw-r--r--ruby_1_8_6/sample/fib.py10
-rw-r--r--ruby_1_8_6/sample/fib.rb10
-rw-r--r--ruby_1_8_6/sample/fib.scm8
-rw-r--r--ruby_1_8_6/sample/freq.rb12
-rw-r--r--ruby_1_8_6/sample/from.rb98
-rw-r--r--ruby_1_8_6/sample/fullpath.rb23
-rw-r--r--ruby_1_8_6/sample/getopts.test36
-rw-r--r--ruby_1_8_6/sample/goodfriday.rb48
-rw-r--r--ruby_1_8_6/sample/less.rb17
-rw-r--r--ruby_1_8_6/sample/list.rb80
-rw-r--r--ruby_1_8_6/sample/list2.rb16
-rw-r--r--ruby_1_8_6/sample/list3.rb18
-rw-r--r--ruby_1_8_6/sample/logger/app.rb46
-rw-r--r--ruby_1_8_6/sample/logger/log.rb27
-rw-r--r--ruby_1_8_6/sample/logger/shifting.rb26
-rw-r--r--ruby_1_8_6/sample/mine.rb175
-rw-r--r--ruby_1_8_6/sample/mkproto.rb27
-rw-r--r--ruby_1_8_6/sample/mpart.rb44
-rw-r--r--ruby_1_8_6/sample/mrshtest.rb13
-rw-r--r--ruby_1_8_6/sample/observ.rb32
-rw-r--r--ruby_1_8_6/sample/occur.pl9
-rw-r--r--ruby_1_8_6/sample/occur.rb12
-rw-r--r--ruby_1_8_6/sample/occur2.rb16
-rw-r--r--ruby_1_8_6/sample/openssl/c_rehash.rb174
-rw-r--r--ruby_1_8_6/sample/openssl/cert2text.rb23
-rw-r--r--ruby_1_8_6/sample/openssl/cert_store_view.rb911
-rw-r--r--ruby_1_8_6/sample/openssl/certstore.rb161
-rw-r--r--ruby_1_8_6/sample/openssl/cipher.rb33
-rw-r--r--ruby_1_8_6/sample/openssl/crlstore.rb122
-rw-r--r--ruby_1_8_6/sample/openssl/echo_cli.rb37
-rw-r--r--ruby_1_8_6/sample/openssl/echo_svr.rb62
-rw-r--r--ruby_1_8_6/sample/openssl/gen_csr.rb50
-rw-r--r--ruby_1_8_6/sample/openssl/smime_read.rb23
-rw-r--r--ruby_1_8_6/sample/openssl/smime_write.rb23
-rw-r--r--ruby_1_8_6/sample/openssl/wget.rb33
-rw-r--r--ruby_1_8_6/sample/optparse/opttest.rb85
-rwxr-xr-xruby_1_8_6/sample/optparse/subcommand.rb19
-rw-r--r--ruby_1_8_6/sample/philos.rb54
-rw-r--r--ruby_1_8_6/sample/pi.rb18
-rw-r--r--ruby_1_8_6/sample/rcs.awk33
-rw-r--r--ruby_1_8_6/sample/rcs.dat17
-rw-r--r--ruby_1_8_6/sample/rcs.rb39
-rw-r--r--ruby_1_8_6/sample/regx.rb23
-rwxr-xr-xruby_1_8_6/sample/rss/blend.rb73
-rwxr-xr-xruby_1_8_6/sample/rss/convert.rb69
-rw-r--r--ruby_1_8_6/sample/rss/list_description.rb82
-rwxr-xr-xruby_1_8_6/sample/rss/re_read.rb64
-rw-r--r--ruby_1_8_6/sample/rss/rss_recent.rb81
-rw-r--r--ruby_1_8_6/sample/sieve.rb14
-rw-r--r--ruby_1_8_6/sample/svr.rb34
-rw-r--r--ruby_1_8_6/sample/test.rb2036
-rw-r--r--ruby_1_8_6/sample/testunit/adder.rb13
-rw-r--r--ruby_1_8_6/sample/testunit/subtracter.rb12
-rw-r--r--ruby_1_8_6/sample/testunit/tc_adder.rb18
-rw-r--r--ruby_1_8_6/sample/testunit/tc_subtracter.rb18
-rw-r--r--ruby_1_8_6/sample/testunit/ts_examples.rb7
-rw-r--r--ruby_1_8_6/sample/time.rb8
-rw-r--r--ruby_1_8_6/sample/trojan.rb15
-rw-r--r--ruby_1_8_6/sample/tsvr.rb20
-rw-r--r--ruby_1_8_6/sample/uumerge.rb43
-rw-r--r--ruby_1_8_6/sample/webrick/demo-app.rb66
-rw-r--r--ruby_1_8_6/sample/webrick/demo-multipart.cgi12
-rw-r--r--ruby_1_8_6/sample/webrick/demo-servlet.rb6
-rw-r--r--ruby_1_8_6/sample/webrick/demo-urlencoded.cgi12
-rw-r--r--ruby_1_8_6/sample/webrick/hello.cgi11
-rw-r--r--ruby_1_8_6/sample/webrick/hello.rb8
-rw-r--r--ruby_1_8_6/sample/webrick/httpd.rb23
-rw-r--r--ruby_1_8_6/sample/webrick/httpproxy.rb26
-rw-r--r--ruby_1_8_6/sample/webrick/httpsd.rb33
128 files changed, 8186 insertions, 0 deletions
diff --git a/ruby_1_8_6/sample/README b/ruby_1_8_6/sample/README
new file mode 100644
index 0000000000..53d16de335
--- /dev/null
+++ b/ruby_1_8_6/sample/README
@@ -0,0 +1,52 @@
+README this file
+biorhythm.rb biorhythm calculator
+cal.rb cal(1) clone
+cbreak.rb no echo done by ioctl
+clnt.rb socket client
+dbmtest.rb test for dbm
+dir.rb directory access
+dualstack-fetch.rb IPv6 demo
+dualstack-httpd.rb IPv6 demo
+dstore.rb object database on dbm
+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
+getopts.test test fot getopt.rb
+goodfriday.rb print various christian calendar event.
+io.rb io test
+irb.rb interactive ruby
+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
+mrshtest.rb test marshal
+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
+rd2html.rb rd (Ruby Document) to HTML translator
+regx.rb regular expression tester
+sieve.rb sieve of Eratosthenes
+svr.rb socket server
+test.rb test suite used by `make test'
+time.rb /usr/bin/time clone
+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/ruby_1_8_6/sample/biorhythm.rb b/ruby_1_8_6/sample/biorhythm.rb
new file mode 100644
index 0000000000..c7e26c4fff
--- /dev/null
+++ b/ruby_1_8_6/sample/biorhythm.rb
@@ -0,0 +1,160 @@
+#!/usr/local/bin/ruby
+#
+# biorhythm.rb -
+# $Release Version: $
+# $Revision$
+# $Date$
+# 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 "parsearg.rb"
+require "parsedate.rb"
+
+def usage()
+ print "Usage:\n"
+ print "biorhythm.rb [options]\n"
+ print " options...\n"
+ print " -D YYYYMMDD(birthday) : use default values.\n"
+ print " --sdate | --date YYYYMMDD : use system date; use specified date.\n"
+ print " --birthday YYYYMMDD : specifies your birthday.\n"
+ print " -v | -g : show values or graph.\n"
+ print " --days DAYS : graph range (only in effect for graphs).\n"
+ print " --help : help\n"
+end
+$USAGE = 'usage'
+
+def printHeader(y, m, d, p, w)
+ print "\n>>> Biorhythm <<<\n"
+ printf "The birthday %04d.%02d.%02d is a %s\n", y, m, d, w
+ printf "Age in days: [%d]\n\n", p
+end
+
+def getPosition(z)
+ pi = 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 parsedate(s)
+ ParseDate::parsedate(s).values_at(0, 1, 2)
+end
+
+def name_of_week(date)
+ Date::DAYNAMES[date.wday]
+end
+
+#
+# main program
+#
+parseArgs(0, nil, "vg", "D:", "sdate", "date:", "birthday:", "days:")
+
+if $OPT_D
+ dd = Date.today
+ bd = Date.new(*parsedate($OPT_D))
+ ausgabeart = "g"
+else
+ if $OPT_birthday
+ bd = Date.new(*parsedate($OPT_birthday))
+ else
+ STDERR.print("Birthday (YYYYMMDD) : ")
+ unless (si = STDIN.gets.chop).empty?
+ bd = Date.new(*parsedate(si))
+ end
+ end
+ if !bd
+ STDERR.print "BAD Input Birthday!!\n"
+ exit()
+ end
+
+ if $OPT_sdate
+ dd = Date.today
+ elsif $OPT_date
+ dd = Date.new(*parsedate($OPT_date))
+ else
+ STDERR.print("Date [<RETURN> for Systemdate] (YYYYMMDD) : ")
+ unless (si = STDIN.gets.chop).empty?
+ dd = Date.new(*parsedate(si))
+ end
+ end
+ dd ||= Date.today
+
+ if $OPT_v
+ ausgabeart = "v"
+ elsif $OPT_g
+ ausgabeart = "g"
+ else
+ STDERR.print("Values for today or Graph (v/g) [default g] : ")
+ ausgabeart = STDIN.gets.chop
+ end
+end
+if ausgabeart == "v"
+ printHeader(bd.year, bd.month, bd.day, dd - bd, name_of_week(bd))
+ print "\n"
+
+ phys, emot, geist = getPosition(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
+ if $OPT_days
+ display_period = $OPT_days.to_i
+ elsif $OPT_D
+ display_period = 9
+ else
+ STDERR.printf("Graph for how many days [default 10] : ")
+ display_period = STDIN.gets.chop
+ if display_period.empty?
+ display_period = 9
+ else
+ display_period = display_period.to_i - 1
+ end
+ end
+
+ printHeader(bd.year, bd.month, bd.day, dd - bd, name_of_week(bd))
+ 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 = getPosition(z)
+
+ printf "%04d.%02d.%02d : ", dd.year, dd.month, dd.day
+ p = (phys / 2.0 + 0.5).to_i
+ e = (emot / 2.0 + 0.5).to_i
+ g = (geist / 2.0 + 0.5).to_i
+ graph = "." * 51
+ graph[25] = ?|
+ graph[p] = ?P
+ graph[e] = ?E
+ graph[g] = ?M
+ print graph, "\n"
+ dd = dd + 1
+ end
+ print " -------------------------+-------------------------\n\n"
+end
diff --git a/ruby_1_8_6/sample/cal.rb b/ruby_1_8_6/sample/cal.rb
new file mode 100644
index 0000000000..fa20352f71
--- /dev/null
+++ b/ruby_1_8_6/sample/cal.rb
@@ -0,0 +1,154 @@
+#! /usr/bin/env ruby
+
+# cal.rb: Written by Tadayoshi Funaba 1998-2004
+# $Id: cal.rb,v 2.7 2004-01-10 23:52:51+09 tadf Exp $
+
+require 'date'
+
+class Cal
+
+ START =
+ {
+ 'cn' => true, # 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' => true, # Japan
+ 'no' => 2342032, # Norway
+ 'pl' => 2299161, # Poland
+ 'pt' => 2299161, # Portugal
+ 'ru' => 2421639, # Russia
+ 'se' => 2361390, # Sweden
+ 'us' => 2361222, # United States
+ 'os' => false, # (old style)
+ 'ns' => true # (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{|d| Date.valid_date?(y, m, d, @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 not @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 'getopts'
+
+ def usage
+ warn 'usage: cal [-c iso3166] [-jmty] [[month] year]'
+ exit 1
+ end
+
+ usage unless getopts('jmty', "c:#{Cal::DEFAULT_START}")
+
+ y, m = ARGV.values_at(1, 0).compact.collect{|x| x.to_i}
+ $OPT_y ||= (y and not m)
+
+ to = Date.today
+ y ||= to.year
+ m ||= to.mon
+
+ usage unless m >= 1 and m <= 12
+ usage unless y >= -4712
+ usage if Cal::START[$OPT_c].nil?
+
+ cal = Cal.new
+
+ cal.opt_j($OPT_j)
+ cal.opt_m($OPT_m)
+ cal.opt_t($OPT_t)
+ cal.opt_y($OPT_y)
+ cal.opt_c($OPT_c)
+
+ print cal.print(y, m)
+
+end
diff --git a/ruby_1_8_6/sample/cbreak.rb b/ruby_1_8_6/sample/cbreak.rb
new file mode 100644
index 0000000000..cbb15d2f41
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/clnt.rb b/ruby_1_8_6/sample/clnt.rb
new file mode 100644
index 0000000000..0f3d17bf19
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/dbmtest.rb b/ruby_1_8_6/sample/dbmtest.rb
new file mode 100644
index 0000000000..c77cc2065b
--- /dev/null
+++ b/ruby_1_8_6/sample/dbmtest.rb
@@ -0,0 +1,14 @@
+# ruby dbm acess
+require "dbm"
+
+d = DBM.open("test")
+keys = d.keys
+if keys.length > 0 then
+ for k in keys; print k, "\n"; end
+ for v in d.values; print v, "\n"; end
+else
+ d['foobar'] = 'FB'
+ d['baz'] = 'BZ'
+ d['quux'] = 'QX'
+end
+
diff --git a/ruby_1_8_6/sample/dir.rb b/ruby_1_8_6/sample/dir.rb
new file mode 100644
index 0000000000..b627383946
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/README.rd b/ruby_1_8_6/sample/drb/README.rd
new file mode 100644
index 0000000000..5cf1f51913
--- /dev/null
+++ b/ruby_1_8_6/sample/drb/README.rd
@@ -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 - ((<URI: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/ruby_1_8_6/sample/drb/README.rd.ja b/ruby_1_8_6/sample/drb/README.rd.ja
new file mode 100644
index 0000000000..04143b9ad5
--- /dev/null
+++ b/ruby_1_8_6/sample/drb/README.rd.ja
@@ -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 - ((<URI: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/ruby_1_8_6/sample/drb/darray.rb b/ruby_1_8_6/sample/drb/darray.rb
new file mode 100644
index 0000000000..95ee01ff03
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/darrayc.rb b/ruby_1_8_6/sample/drb/darrayc.rb
new file mode 100644
index 0000000000..6f5ff6bb5d
--- /dev/null
+++ b/ruby_1_8_6/sample/drb/darrayc.rb
@@ -0,0 +1,59 @@
+=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
+
+puts "# each, retry"
+retried = false
+ro.each do |x|
+ puts x
+ if x == 4 && !retried
+ puts 'retry'
+ retried = true
+ retry
+ end
+end
+
diff --git a/ruby_1_8_6/sample/drb/dbiff.rb b/ruby_1_8_6/sample/drb/dbiff.rb
new file mode 100644
index 0000000000..8faef50b07
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dcdbiff.rb b/ruby_1_8_6/sample/drb/dcdbiff.rb
new file mode 100644
index 0000000000..6a24680c33
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dchatc.rb b/ruby_1_8_6/sample/drb/dchatc.rb
new file mode 100644
index 0000000000..b506f5bbba
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dchats.rb b/ruby_1_8_6/sample/drb/dchats.rb
new file mode 100644
index 0000000000..012dfeeebe
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dhasen.rb b/ruby_1_8_6/sample/drb/dhasen.rb
new file mode 100644
index 0000000000..fb1724afa3
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dhasenc.rb b/ruby_1_8_6/sample/drb/dhasenc.rb
new file mode 100644
index 0000000000..8114e9228d
--- /dev/null
+++ b/ruby_1_8_6/sample/drb/dhasenc.rb
@@ -0,0 +1,13 @@
+=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/ruby_1_8_6/sample/drb/dlogc.rb b/ruby_1_8_6/sample/drb/dlogc.rb
new file mode 100644
index 0000000000..c75bc7b520
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dlogd.rb b/ruby_1_8_6/sample/drb/dlogd.rb
new file mode 100644
index 0000000000..9f9aa2fd56
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dqin.rb b/ruby_1_8_6/sample/drb/dqin.rb
new file mode 100644
index 0000000000..3ba1caa80c
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dqlib.rb b/ruby_1_8_6/sample/drb/dqlib.rb
new file mode 100644
index 0000000000..75f2e6115b
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dqout.rb b/ruby_1_8_6/sample/drb/dqout.rb
new file mode 100644
index 0000000000..4700e55cf7
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/dqueue.rb b/ruby_1_8_6/sample/drb/dqueue.rb
new file mode 100644
index 0000000000..a5a43655fd
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/drbc.rb b/ruby_1_8_6/sample/drb/drbc.rb
new file mode 100644
index 0000000000..00132b46c8
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/drbch.rb b/ruby_1_8_6/sample/drb/drbch.rb
new file mode 100644
index 0000000000..495ff1c346
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/drbm.rb b/ruby_1_8_6/sample/drb/drbm.rb
new file mode 100644
index 0000000000..74a15a4696
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/drbmc.rb b/ruby_1_8_6/sample/drb/drbmc.rb
new file mode 100644
index 0000000000..c654fcea05
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/drbs-acl.rb b/ruby_1_8_6/sample/drb/drbs-acl.rb
new file mode 100644
index 0000000000..151dd945d8
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/drbs.rb b/ruby_1_8_6/sample/drb/drbs.rb
new file mode 100644
index 0000000000..b76e283c80
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/drbssl_c.rb b/ruby_1_8_6/sample/drb/drbssl_c.rb
new file mode 100644
index 0000000000..65112f6e78
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/drbssl_s.rb b/ruby_1_8_6/sample/drb/drbssl_s.rb
new file mode 100644
index 0000000000..4d96f591d4
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/extserv_test.rb b/ruby_1_8_6/sample/drb/extserv_test.rb
new file mode 100644
index 0000000000..83d871a6a2
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/gw_ct.rb b/ruby_1_8_6/sample/drb/gw_ct.rb
new file mode 100644
index 0000000000..0622784018
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/gw_cu.rb b/ruby_1_8_6/sample/drb/gw_cu.rb
new file mode 100644
index 0000000000..0e5ed36b8f
--- /dev/null
+++ b/ruby_1_8_6/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('drubyunix:', 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/ruby_1_8_6/sample/drb/gw_s.rb b/ruby_1_8_6/sample/drb/gw_s.rb
new file mode 100644
index 0000000000..c2bea0baad
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/holderc.rb b/ruby_1_8_6/sample/drb/holderc.rb
new file mode 100644
index 0000000000..8dd72ebd11
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/holders.rb b/ruby_1_8_6/sample/drb/holders.rb
new file mode 100644
index 0000000000..2d9974f3fc
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/http0.rb b/ruby_1_8_6/sample/drb/http0.rb
new file mode 100644
index 0000000000..7649925282
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/http0serv.rb b/ruby_1_8_6/sample/drb/http0serv.rb
new file mode 100644
index 0000000000..100d126b8f
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/name.rb b/ruby_1_8_6/sample/drb/name.rb
new file mode 100644
index 0000000000..86b478fbec
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/namec.rb b/ruby_1_8_6/sample/drb/namec.rb
new file mode 100644
index 0000000000..f6db6f3022
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/old_tuplespace.rb b/ruby_1_8_6/sample/drb/old_tuplespace.rb
new file mode 100644
index 0000000000..3e13b92ee1
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/rinda_ts.rb b/ruby_1_8_6/sample/drb/rinda_ts.rb
new file mode 100644
index 0000000000..6f2fae5c0f
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/rindac.rb b/ruby_1_8_6/sample/drb/rindac.rb
new file mode 100644
index 0000000000..72be09deaf
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/rindas.rb b/ruby_1_8_6/sample/drb/rindas.rb
new file mode 100644
index 0000000000..9fd9ada2d1
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/ring_echo.rb b/ruby_1_8_6/sample/drb/ring_echo.rb
new file mode 100644
index 0000000000..0633aa839a
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/ring_inspect.rb b/ruby_1_8_6/sample/drb/ring_inspect.rb
new file mode 100644
index 0000000000..c096cd7034
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/ring_place.rb b/ruby_1_8_6/sample/drb/ring_place.rb
new file mode 100644
index 0000000000..0ceef7c65a
--- /dev/null
+++ b/ruby_1_8_6/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('/dev/null')
+ STDOUT.reopen('/dev/null', 'w')
+ STDERR.reopen('/dev/null', 'w')
+ DRb.thread.join
+end
diff --git a/ruby_1_8_6/sample/drb/simpletuple.rb b/ruby_1_8_6/sample/drb/simpletuple.rb
new file mode 100644
index 0000000000..3ae9208c79
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/speedc.rb b/ruby_1_8_6/sample/drb/speedc.rb
new file mode 100644
index 0000000000..14d526d48d
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/drb/speeds.rb b/ruby_1_8_6/sample/drb/speeds.rb
new file mode 100644
index 0000000000..76b4b29dba
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/dualstack-fetch.rb b/ruby_1_8_6/sample/dualstack-fetch.rb
new file mode 100644
index 0000000000..1897a3d8e9
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/dualstack-httpd.rb b/ruby_1_8_6/sample/dualstack-httpd.rb
new file mode 100644
index 0000000000..893b29feba
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/eval.rb b/ruby_1_8_6/sample/eval.rb
new file mode 100644
index 0000000000..90b839e873
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/export.rb b/ruby_1_8_6/sample/export.rb
new file mode 100644
index 0000000000..949e5b10bf
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/exyacc.rb b/ruby_1_8_6/sample/exyacc.rb
new file mode 100644
index 0000000000..5818825e25
--- /dev/null
+++ b/ruby_1_8_6/sample/exyacc.rb
@@ -0,0 +1,22 @@
+#! /usr/local/bin/ruby -Kn
+# usage: exyacc.rb [yaccfiles]
+# this is coverted from exyacc.pl in the camel book
+
+$/ = nil
+
+while gets()
+ sbeg = $_.index("\n%%") + 1
+ send = $_.rindex("\n%%") + 1
+ $_ = $_[sbeg, send-sbeg]
+ sub!(/.*\n/, "")
+ gsub!(/'\{'/, "'\001'")
+ gsub!(/'\}'/, "'\002'")
+ gsub!(%r{\*/}, "\003\003")
+ gsub!(%r{/\*[^\003]*\003\003}, '')
+ while gsub!(/\{[^{}]*\}/, ''); end
+ gsub!(/'\001'/, "'{'")
+ gsub!(/'\002'/, "'}'")
+ while gsub!(/^[ \t]*\n(\s)/, '\1'); end
+ gsub!(/([:|])[ \t\n]+(\w)/, '\1 \2')
+ print $_
+end
diff --git a/ruby_1_8_6/sample/fact.rb b/ruby_1_8_6/sample/fact.rb
new file mode 100644
index 0000000000..d8147a40f1
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/fib.awk b/ruby_1_8_6/sample/fib.awk
new file mode 100644
index 0000000000..7ebe8930f5
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/fib.pl b/ruby_1_8_6/sample/fib.pl
new file mode 100644
index 0000000000..945a4929a7
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/fib.py b/ruby_1_8_6/sample/fib.py
new file mode 100644
index 0000000000..8318021d24
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/fib.rb b/ruby_1_8_6/sample/fib.rb
new file mode 100644
index 0000000000..cde4fba082
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/fib.scm b/ruby_1_8_6/sample/fib.scm
new file mode 100644
index 0000000000..b246ca50ac
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/freq.rb b/ruby_1_8_6/sample/freq.rb
new file mode 100644
index 0000000000..362753f71f
--- /dev/null
+++ b/ruby_1_8_6/sample/freq.rb
@@ -0,0 +1,12 @@
+# word occurrence listing
+# usege: 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/ruby_1_8_6/sample/from.rb b/ruby_1_8_6/sample/from.rb
new file mode 100644
index 0000000000..59cc387792
--- /dev/null
+++ b/ruby_1_8_6/sample/from.rb
@@ -0,0 +1,98 @@
+#! /usr/local/bin/ruby
+
+require "parsedate"
+require "kconv"
+require "mailread"
+
+include ParseDate
+include Kconv
+
+class String
+
+ def kconv(code = Kconv::EUC)
+ Kconv.kconv(self, code, Kconv::AUTO)
+ end
+
+ def kjust(len)
+ len += 1
+ me = self[0, len].ljust(len)
+ if me =~ /.$/ and $&.size == 2
+ me[-2..-1] = ' '
+ me[-2, 2] = ' '
+ end
+ me.chop!
+ end
+
+end
+
+if ARGV[0] == '-w'
+ wait = TRUE
+ ARGV.shift
+end
+
+if ARGV.length == 0
+ file = ENV['MAIL']
+ user = ENV['USER'] || ENV['USERNAME'] || ENV['LOGNAME']
+else
+ file = user = ARGV[0]
+ ARGV.clear
+end
+
+if file == nil or !File.exist? file
+ [ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m|
+ if File.exist? f = "#{m}/mail/#{user}"
+ file = f
+ break
+ end
+ end
+end
+
+$outcount = 0;
+def fromout(date, from, subj)
+ return if !date
+ y, m, d = parsedate(date) if date
+ y ||= 0; m ||= 0; d ||= 0
+ if from
+ from.gsub! /\n/, ""
+ else
+ from = "sombody@somewhere"
+ end
+ if subj
+ subj.gsub! /\n/, ""
+ else
+ subj = "(nil)"
+ end
+ if ENV['LANG'] =~ /sjis/i
+ lang = Kconv::SJIS
+ else
+ lang = Kconv::EUC
+ end
+ from = from.kconv(lang).kjust(28)
+ subj = subj.kconv(lang).kjust(40)
+ printf "%02d/%02d/%02d [%s] %s\n",y%100,m,d,from,subj
+ $outcount += 1
+end
+
+if File.exist?(file)
+ atime = File.atime(file)
+ mtime = File.mtime(file)
+ f = open(file, "r")
+ begin
+ until f.eof?
+ mail = Mail.new(f)
+ fromout mail.header['Date'],mail.header['From'],mail.header['Subject']
+ end
+ ensure
+ f.close
+ File.utime(atime, mtime, file)
+ end
+end
+
+if $outcount == 0
+ print "You have no mail.\n"
+ sleep 2 if wait
+elsif wait
+ system "stty cbreak -echo"
+ getc()
+ system "stty cooked echo"
+end
diff --git a/ruby_1_8_6/sample/fullpath.rb b/ruby_1_8_6/sample/fullpath.rb
new file mode 100644
index 0000000000..8472e5d8f4
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/getopts.test b/ruby_1_8_6/sample/getopts.test
new file mode 100644
index 0000000000..2866bccea8
--- /dev/null
+++ b/ruby_1_8_6/sample/getopts.test
@@ -0,0 +1,36 @@
+#! /usr/local/bin/ruby
+
+load("parsearg.rb")
+
+def usage()
+ printf "Usage:\n"
+ printf "%s -d [-x x] [-y y] [--geometry geom] [--version] [string ...]\n", $0
+end
+
+$USAGE = 'usage'
+parseArgs(0, "d&(x|y)", "dfg", "x:", "y:", "geometry:800x600", "version")
+if ($OPT_d)
+ if $OPT_version
+ printf "version 1.0\n"
+ end
+ if ($OPT_x)
+ printf("x = %d\n", $OPT_x.to_i)
+ end
+ if ($OPT_y)
+ printf("y = %d\n", $OPT_y.to_i)
+ end
+ if ($OPT_geometry)
+ printf("geometry = %s\n", $OPT_geometry)
+ end
+ if $OPT_f
+ printf "f = TRUE\n"
+ end
+ if $OPT_g
+ printf "g = TRUE\n"
+ end
+end
+
+while (ARGV.length != 0)
+ print "other = ", ARGV[0], "\n"
+ ARGV.shift
+end
diff --git a/ruby_1_8_6/sample/goodfriday.rb b/ruby_1_8_6/sample/goodfriday.rb
new file mode 100644
index 0000000000..a95cfe819f
--- /dev/null
+++ b/ruby_1_8_6/sample/goodfriday.rb
@@ -0,0 +1,48 @@
+#! /usr/bin/env ruby
+
+# goodfriday.rb: Written by Tadayoshi Funaba 1998, 2000, 2002
+# $Id: goodfriday.rb,v 1.1 1998-03-08 18:44:44+09 tadf Exp $
+
+require 'date'
+
+def easter(y)
+ g = (y % 19) + 1
+ c = (y / 100) + 1
+ x = (3 * c / 4) - 12
+ z = ((8 * c + 5) / 25) - 5
+ d = (5 * y / 4) - x - 10
+ e = (11 * g + 20 + z - x) % 30
+ e += 1 if e == 25 and g > 11 or e == 24
+ n = 44 - e
+ n += 30 if n < 21
+ n = n + 7 - ((d + n) % 7)
+ if n <= 31 then [y, 3, n] else [y, 4, n - 31] end
+end
+
+es = Date.new(*easter(Time.now.year))
+[[-9*7, 'Septuagesima Sunday'],
+ [-8*7, 'Sexagesima Sunday'],
+ [-7*7, 'Quinquagesima Sunday (Shrove Sunday)'],
+ [-48, 'Shrove Monday'],
+ [-47, 'Shrove Tuesday'],
+ [-46, 'Ash Wednesday'],
+ [-6*7, 'Quadragesima Sunday'],
+ [-3*7, 'Mothering Sunday'],
+ [-2*7, 'Passion Sunday'],
+ [-7, 'Palm Sunday'],
+ [-3, 'Maunday Thursday'],
+ [-2, 'Good Friday'],
+ [-1, 'Easter Eve'],
+ [0, 'Easter Day'],
+ [1, 'Easter Monday'],
+ [7, 'Low Sunday'],
+ [5*7, 'Rogation Sunday'],
+ [39, 'Ascension Day (Holy Thursday)'],
+ [42, 'Sunday after Ascension Day'],
+ [7*7, 'Pentecost (Whitsunday)'],
+ [50, 'Whitmonday'],
+ [8*7, 'Trinity Sunday'],
+ [60, 'Corpus Christi (Thursday after Trinity)']].
+each do |xs|
+ puts((es + xs.shift).to_s + ' ' + xs.shift)
+end
diff --git a/ruby_1_8_6/sample/less.rb b/ruby_1_8_6/sample/less.rb
new file mode 100644
index 0000000000..8be359108f
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/list.rb b/ruby_1_8_6/sample/list.rb
new file mode 100644
index 0000000000..221f7edb16
--- /dev/null
+++ b/ruby_1_8_6/sample/list.rb
@@ -0,0 +1,80 @@
+# 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
+ 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/ruby_1_8_6/sample/list2.rb b/ruby_1_8_6/sample/list2.rb
new file mode 100644
index 0000000000..914cb8996e
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/list3.rb b/ruby_1_8_6/sample/list3.rb
new file mode 100644
index 0000000000..1d756fdff0
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/logger/app.rb b/ruby_1_8_6/sample/logger/app.rb
new file mode 100644
index 0000000000..924bcba4b0
--- /dev/null
+++ b/ruby_1_8_6/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) occured.'
+ puts 'See "app.log".'
+end
diff --git a/ruby_1_8_6/sample/logger/log.rb b/ruby_1_8_6/sample/logger/log.rb
new file mode 100644
index 0000000000..aab80e462e
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/logger/shifting.rb b/ruby_1_8_6/sample/logger/shifting.rb
new file mode 100644
index 0000000000..bd8852a4ae
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/mine.rb b/ruby_1_8_6/sample/mine.rb
new file mode 100644
index 0000000000..8fc27e0c6d
--- /dev/null
+++ b/ruby_1_8_6/sample/mine.rb
@@ -0,0 +1,175 @@
+#! /usr/bin/ruby -Ke
+
+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=["¡¦","£±","£²","£³","£´","£µ","£¶","£·","£¸","¡ú","¡ü","@@"]
+ 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/ruby_1_8_6/sample/mkproto.rb b/ruby_1_8_6/sample/mkproto.rb
new file mode 100644
index 0000000000..754ca2dff2
--- /dev/null
+++ b/ruby_1_8_6/sample/mkproto.rb
@@ -0,0 +1,27 @@
+$/ = nil
+while line = gets()
+ if /^((void|VALUE|int|char *\*|ID|struct [\w_]+ *\*|st_table *\*) *)?\n([\w\d_]+)\(.*\)\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\d_]+),/
+ type = $2.strip
+ args.push $1.strip
+ arg = $'
+ else
+ type = ""
+ end
+ while arg.sub!(/(\** *[\w\d_]+)(,|$)/, "") && $~
+ args.push type + " " + $1.strip
+ end
+ else
+ args.push arg.strip
+ end
+ end
+ printf "%s);\n", args.join(', ')
+ redo
+ end
+end
diff --git a/ruby_1_8_6/sample/mpart.rb b/ruby_1_8_6/sample/mpart.rb
new file mode 100644
index 0000000000..a88eba0ef6
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/mrshtest.rb b/ruby_1_8_6/sample/mrshtest.rb
new file mode 100644
index 0000000000..8d2dc9936b
--- /dev/null
+++ b/ruby_1_8_6/sample/mrshtest.rb
@@ -0,0 +1,13 @@
+include Marshal
+a = 25.6;
+pt = Struct.new('Point', :x,:y);
+x = pt.new(10, 10)
+y = pt.new(20, 20)
+rt = Struct.new('Rectangle', :origin,:corner);
+z = rt.new(x, y)
+c = Object.new
+s = [a, x, z, c, c, "fff"];
+p s
+d = dump(s);
+p d
+p load(d)
diff --git a/ruby_1_8_6/sample/observ.rb b/ruby_1_8_6/sample/observ.rb
new file mode 100644
index 0000000000..72e5178b38
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/occur.pl b/ruby_1_8_6/sample/occur.pl
new file mode 100644
index 0000000000..1f5fcf27a4
--- /dev/null
+++ b/ruby_1_8_6/sample/occur.pl
@@ -0,0 +1,9 @@
+while (<>) {
+ for (split(/\W+/)) {
+ $freq{$_}++;
+ }
+}
+
+for (sort keys %freq) {
+ print "$_ -- $freq{$_}\n";
+}
diff --git a/ruby_1_8_6/sample/occur.rb b/ruby_1_8_6/sample/occur.rb
new file mode 100644
index 0000000000..8bb09e15ad
--- /dev/null
+++ b/ruby_1_8_6/sample/occur.rb
@@ -0,0 +1,12 @@
+# word occurrence listing
+# usege: ruby occur.rb file..
+freq = Hash.new(0)
+while gets()
+ for word in split(/\W+/)
+ freq[word] += 1
+ end
+end
+
+for word in freq.keys.sort!
+ print word, " -- ", freq[word], "\n"
+end
diff --git a/ruby_1_8_6/sample/occur2.rb b/ruby_1_8_6/sample/occur2.rb
new file mode 100644
index 0000000000..53885c0ba7
--- /dev/null
+++ b/ruby_1_8_6/sample/occur2.rb
@@ -0,0 +1,16 @@
+# word occurrence listing
+# usege: ruby occur2.rb file..
+freq = {}
+while gets()
+ for word in split(/\W+/)
+ begin
+ freq[word] += 1
+ rescue NameError
+ freq[word] = 1
+ end
+ end
+end
+
+for word in freq.keys.sort
+ printf("%s -- %d\n", word, freq[word])
+end
diff --git a/ruby_1_8_6/sample/openssl/c_rehash.rb b/ruby_1_8_6/sample/openssl/c_rehash.rb
new file mode 100644
index 0000000000..afbb654517
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/openssl/cert2text.rb b/ruby_1_8_6/sample/openssl/cert2text.rb
new file mode 100644
index 0000000000..50da224e76
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/openssl/cert_store_view.rb b/ruby_1_8_6/sample/openssl/cert_store_view.rb
new file mode 100644
index 0000000000..26c4d527f7
--- /dev/null
+++ b/ruby_1_8_6/sample/openssl/cert_store_view.rb
@@ -0,0 +1,911 @@
+#!/usr/bin/env ruby
+
+require 'fox'
+require 'openssl'
+require 'time'
+require 'certstore'
+require 'getopts'
+
+include Fox
+
+module CertDumpSupport
+ def cert_label(cert)
+ subject_alt_name =
+ cert.extensions.find { |ext| ext.oid == 'subjectAltName' }
+ if subject_alt_name
+ subject_alt_name.value.split(/\s*,\s/).each do |alt_name_pair|
+ alt_tag, alt_name = alt_name_pair.split(/:/)
+ return alt_name
+ end
+ end
+ name_label(cert.subject)
+ end
+
+ def name_label(name)
+ ary = name.to_a
+ if (cn = ary.find { |rdn| rdn[0] == 'CN' })
+ return cn[1]
+ end
+ if ary.last[0] == 'OU'
+ return ary.last[1]
+ end
+ name.to_s
+ end
+
+ def name_text(name)
+ name.to_a.collect { |tag, value|
+ "#{tag} = #{value}"
+ }.reverse.join("\n")
+ end
+
+ def bn_label(bn)
+ ("0" << sprintf("%X", bn)).scan(/../).join(" ")
+ end
+end
+
+class CertDump
+ include CertDumpSupport
+
+ def initialize(cert)
+ @cert = cert
+ end
+
+ def get_dump(tag)
+ case tag
+ when 'Version'
+ version
+ when 'Serial'
+ serial
+ when 'Signature Algorithm'
+ signature_algorithm
+ when 'Issuer'
+ issuer
+ when 'Validity'
+ validity
+ when 'Not before'
+ not_before
+ when 'Not after'
+ not_after
+ when 'Subject'
+ subject
+ when 'Public key'
+ public_key
+ else
+ ext(tag)
+ end
+ end
+
+ def get_dump_line(tag)
+ case tag
+ when 'Version'
+ version_line
+ when 'Serial'
+ serial_line
+ when 'Signature Algorithm'
+ signature_algorithm_line
+ when 'Subject'
+ subject_line
+ when 'Issuer'
+ issuer_line
+ when 'Validity'
+ validity_line
+ when 'Not before'
+ not_before_line
+ when 'Not after'
+ not_after_line
+ when 'Public key'
+ public_key_line
+ else
+ ext_line(tag)
+ end
+ end
+
+private
+
+ def version
+ "Version: #{@cert.version + 1}"
+ end
+
+ def version_line
+ version
+ end
+
+ def serial
+ bn_label(@cert.serial)
+ end
+
+ def serial_line
+ serial
+ end
+
+ def signature_algorithm
+ @cert.signature_algorithm
+ end
+
+ def signature_algorithm_line
+ signature_algorithm
+ end
+
+ def subject
+ name_text(@cert.subject)
+ end
+
+ def subject_line
+ @cert.subject.to_s
+ end
+
+ def issuer
+ name_text(@cert.issuer)
+ end
+
+ def issuer_line
+ @cert.issuer.to_s
+ end
+
+ def validity
+ <<EOS
+Not before: #{not_before}
+Not after: #{not_after}
+EOS
+ end
+
+ def validity_line
+ "from #{@cert.not_before.iso8601} to #{@cert.not_after.iso8601}"
+ end
+
+ def not_before
+ @cert.not_before.to_s
+ end
+
+ def not_before_line
+ not_before
+ end
+
+ def not_after
+ @cert.not_after.to_s
+ end
+
+ def not_after_line
+ not_after
+ end
+
+ def public_key
+ @cert.public_key.to_text
+ end
+
+ def public_key_line
+ "#{@cert.public_key.class} -- " << public_key.scan(/\A[^\n]*/)[0] << '...'
+ end
+
+ def ext(tag)
+ @cert.extensions.each do |ext|
+ if ext.oid == tag
+ return ext_detail(tag, ext.value)
+ end
+ end
+ "(unknown)"
+ end
+
+ def ext_line(tag)
+ ext(tag).tr("\r\n", '')
+ end
+
+ def ext_detail(tag, value)
+ value
+ end
+end
+
+class CrlDump
+ include CertDumpSupport
+
+ def initialize(crl)
+ @crl = crl
+ end
+
+ def get_dump(tag)
+ case tag
+ when 'Version'
+ version
+ when 'Signature Algorithm'
+ signature_algorithm
+ when 'Issuer'
+ issuer
+ when 'Last update'
+ last_update
+ when 'Next update'
+ next_update
+ else
+ ext(tag)
+ end
+ end
+
+ def get_dump_line(tag)
+ case tag
+ when 'Version'
+ version_line
+ when 'Signature Algorithm'
+ signature_algorithm_line
+ when 'Issuer'
+ issuer_line
+ when 'Last update'
+ last_update_line
+ when 'Next update'
+ next_update_line
+ else
+ ext_line(tag)
+ end
+ end
+
+private
+
+ def version
+ "Version: #{@crl.version + 1}"
+ end
+
+ def version_line
+ version
+ end
+
+ def signature_algorithm
+ @crl.signature_algorithm
+ end
+
+ def signature_algorithm_line
+ signature_algorithm
+ end
+
+ def issuer
+ name_text(@crl.issuer)
+ end
+
+ def issuer_line
+ @crl.issuer.to_s
+ end
+
+ def last_update
+ @crl.last_update.to_s
+ end
+
+ def last_update_line
+ last_update
+ end
+
+ def next_update
+ @crl.next_update.to_s
+ end
+
+ def next_update_line
+ next_update
+ end
+
+ def ext(tag)
+ @crl.extensions.each do |ext|
+ if ext.oid == tag
+ return ext_detail(tag, ext.value)
+ end
+ end
+ "(unknown)"
+ end
+
+ def ext_line(tag)
+ ext(tag).tr("\r\n", '')
+ end
+
+ def ext_detail(tag, value)
+ value
+ end
+end
+
+class RevokedDump
+ include CertDumpSupport
+
+ def initialize(revoked)
+ @revoked = revoked
+ end
+
+ def get_dump(tag)
+ case tag
+ when 'Serial'
+ serial
+ when 'Time'
+ time
+ else
+ ext(tag)
+ end
+ end
+
+ def get_dump_line(tag)
+ case tag
+ when 'Serial'
+ serial_line
+ when 'Time'
+ time_line
+ else
+ ext_line(tag)
+ end
+ end
+
+private
+
+ def serial
+ bn_label(@revoked.serial)
+ end
+
+ def serial_line
+ serial
+ end
+
+ def time
+ @revoked.time.to_s
+ end
+
+ def time_line
+ time
+ end
+
+ def ext(tag)
+ @revoked.extensions.each do |ext|
+ if ext.oid == tag
+ return ext_detail(tag, ext.value)
+ end
+ end
+ "(unknown)"
+ end
+
+ def ext_line(tag)
+ ext(tag).tr("\r\n", '')
+ end
+
+ def ext_detail(tag, value)
+ value
+ end
+end
+
+class RequestDump
+ include CertDumpSupport
+
+ def initialize(req)
+ @req = req
+ end
+
+ def get_dump(tag)
+ case tag
+ when 'Version'
+ version
+ when 'Signature Algorithm'
+ signature_algorithm
+ when 'Subject'
+ subject
+ when 'Public key'
+ public_key
+ else
+ attributes(tag)
+ end
+ end
+
+ def get_dump_line(tag)
+ case tag
+ when 'Version'
+ version_line
+ when 'Signature Algorithm'
+ signature_algorithm_line
+ when 'Subject'
+ subject_line
+ when 'Public key'
+ public_key_line
+ else
+ attributes_line(tag)
+ end
+ end
+
+private
+
+ def version
+ "Version: #{@req.version + 1}"
+ end
+
+ def version_line
+ version
+ end
+
+ def signature_algorithm
+ @req.signature_algorithm
+ end
+
+ def signature_algorithm_line
+ signature_algorithm
+ end
+
+ def subject
+ name_text(@req.subject)
+ end
+
+ def subject_line
+ @req.subject.to_s
+ end
+
+ def public_key
+ @req.public_key.to_text
+ end
+
+ def public_key_line
+ "#{@req.public_key.class} -- " << public_key.scan(/\A[^\n]*/)[0] << '...'
+ end
+
+ def attributes(tag)
+ "(unknown)"
+ end
+
+ def attributes_line(tag)
+ attributes(tag).tr("\r\n", '')
+ end
+end
+
+class CertStoreView < FXMainWindow
+ class CertTree
+ include CertDumpSupport
+
+ def initialize(observer, tree)
+ @observer = observer
+ @tree = tree
+ @tree.connect(SEL_COMMAND) do |sender, sel, item|
+ if item.data
+ @observer.getApp().beginWaitCursor do
+ @observer.show_item(item.data)
+ end
+ else
+ @observer.show_item(nil)
+ end
+ end
+ end
+
+ def show(cert_store)
+ @tree.clearItems
+ @self_signed_ca_node = add_item_last(nil, "Trusted root CA")
+ @other_ca_node = add_item_last(nil, "Intermediate CA")
+ @ee_node = add_item_last(nil, "Personal")
+ @crl_node = add_item_last(nil, "CRL")
+ @request_node = add_item_last(nil, "Request")
+ @verify_path_node = add_item_last(nil, "Certification path")
+ show_certs(cert_store)
+ end
+
+ def show_certs(cert_store)
+ remove_items(@self_signed_ca_node)
+ remove_items(@other_ca_node)
+ remove_items(@ee_node)
+ remove_items(@crl_node)
+ remove_items(@request_node)
+ import_certs(cert_store)
+ end
+
+ def show_request(req)
+ node = add_item_last(@request_node, name_label(req.subject), req)
+ @tree.selectItem(node)
+ @observer.show_item(req)
+ end
+
+ def show_verify_path(verify_path)
+ add_verify_path(verify_path)
+ end
+
+ private
+
+ def open_node(node)
+ node.expanded = node.opened = true
+ end
+
+ def close_node(node)
+ node.expanded = node.opened = false
+ end
+
+ def import_certs(cert_store)
+ cert_store.self_signed_ca.each do |cert|
+ add_item_last(@self_signed_ca_node, cert_label(cert), cert)
+ end
+ cert_store.other_ca.each do |cert|
+ add_item_last(@other_ca_node, cert_label(cert), cert)
+ end
+ cert_store.ee.each do |cert|
+ add_item_last(@ee_node, cert_label(cert), cert)
+ end
+ cert_store.crl.each do |crl|
+ node = add_item_last(@crl_node, name_label(crl.issuer), crl)
+ close_node(node)
+ crl.revoked.each do |revoked|
+ add_item_last(node, bn_label(revoked.serial), revoked)
+ end
+ end
+ cert_store.request.each do |req|
+ add_item_last(@requestnode, name_label(req.subject), req)
+ end
+ end
+
+ def add_verify_path(verify_path)
+ node = @verify_path_node
+ last_cert = nil
+ verify_path.reverse_each do |ok, cert, crl_check, error_string|
+ warn = []
+ if @observer.cert_store.is_ca?(cert)
+ warn << 'NO ARL' unless crl_check
+ else
+ warn << 'NO CRL' unless crl_check
+ end
+ warn_str = '(' << warn.join(", ") << ')'
+ warn_mark = warn.empty? ? '' : '!'
+ label = if ok
+ "OK#{warn_mark}..." + cert_label(cert)
+ else
+ "NG(#{error_string})..." + cert_label(cert)
+ end
+ label << warn_str unless warn.empty?
+ node = add_item_last(node, label, cert)
+ node.expanded = true
+ last_cert = cert
+ end
+ if last_cert
+ @tree.selectItem(node)
+ @observer.show_item(last_cert)
+ end
+ end
+
+ def add_item_last(parent, label, obj = nil)
+ node = @tree.addItemLast(parent, FXTreeItem.new(label))
+ node.data = obj if obj
+ open_node(node)
+ node
+ end
+
+ def remove_items(node)
+ while node.getNumChildren > 0
+ @tree.removeItem(node.getFirst)
+ end
+ end
+ end
+
+ class CertInfo
+ def initialize(observer, table)
+ @observer = observer
+ @table = table
+ @table.leadingRows = 0
+ @table.leadingCols = 0
+ @table.trailingRows = 0
+ @table.trailingCols = 0
+ @table.showVertGrid(false)
+ @table.showHorzGrid(false)
+ @table.setTableSize(1, 2)
+ @table.setColumnWidth(0, 125)
+ @table.setColumnWidth(1, 350)
+ end
+
+ def show(item)
+ @observer.show_detail(nil, nil)
+ if item.nil?
+ set_column_size(1)
+ return
+ end
+ case item
+ when OpenSSL::X509::Certificate
+ show_cert(item)
+ when OpenSSL::X509::CRL
+ show_crl(item)
+ when OpenSSL::X509::Revoked
+ show_revoked(item)
+ when OpenSSL::X509::Request
+ show_request(item)
+ else
+ raise NotImplementedError.new("Unknown item type #{item.class}.")
+ end
+ end
+
+ private
+
+ def show_cert(cert)
+ wrap = CertDump.new(cert)
+ items = []
+ items << ['Version', wrap.get_dump_line('Version')]
+ items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]
+ items << ['Issuer', wrap.get_dump_line('Issuer')]
+ items << ['Serial', wrap.get_dump_line('Serial')]
+ #items << ['Not before', wrap.get_dump_line('Not before')]
+ #items << ['Not after', wrap.get_dump_line('Not after')]
+ items << ['Subject', wrap.get_dump_line('Subject')]
+ items << ['Public key', wrap.get_dump_line('Public key')]
+ items << ['Validity', wrap.get_dump_line('Validity')]
+ (cert.extensions.sort { |a, b| a.oid <=> b.oid }).each do |ext|
+ items << [ext.oid, wrap.get_dump_line(ext.oid)]
+ end
+ show_items(cert, items)
+ end
+
+ def show_crl(crl)
+ wrap = CrlDump.new(crl)
+ items = []
+ items << ['Version', wrap.get_dump_line('Version')]
+ items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]
+ items << ['Issuer', wrap.get_dump_line('Issuer')]
+ items << ['Last update', wrap.get_dump_line('Last update')]
+ items << ['Next update', wrap.get_dump_line('Next update')]
+ crl.extensions.each do |ext|
+ items << [ext.oid, wrap.get_dump_line(ext.oid)]
+ end
+ show_items(crl, items)
+ end
+
+ def show_revoked(revoked)
+ wrap = RevokedDump.new(revoked)
+ items = []
+ items << ['Serial', wrap.get_dump_line('Serial')]
+ items << ['Time', wrap.get_dump_line('Time')]
+ revoked.extensions.each do |ext|
+ items << [ext.oid, wrap.get_dump_line(ext.oid)]
+ end
+ show_items(revoked, items)
+ end
+
+ def show_request(req)
+ wrap = RequestDump.new(req)
+ items = []
+ items << ['Version', wrap.get_dump_line('Version')]
+ items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]
+ items << ['Subject', wrap.get_dump_line('Subject')]
+ items << ['Public key', wrap.get_dump_line('Public key')]
+ req.attributes.each do |attr|
+ items << [attr.attr, wrap.get_dump_line(attr.oid)]
+ end
+ show_items(req, items)
+ end
+
+ def show_items(obj, items)
+ set_column_size(items.size)
+ items.each_with_index do |ele, idx|
+ tag, value = ele
+ @table.setItemText(idx, 0, tag)
+ @table.getItem(idx, 0).data = tag
+ @table.setItemText(idx, 1, value.to_s)
+ @table.getItem(idx, 1).data = tag
+ end
+ @table.connect(SEL_COMMAND) do |sender, sel, loc|
+ item = @table.getItem(loc.row, loc.col)
+ @observer.show_detail(obj, item.data)
+ end
+ justify_table
+ end
+
+ def set_column_size(size)
+ col0_width = @table.getColumnWidth(0)
+ col1_width = @table.getColumnWidth(1)
+ @table.setTableSize(size, 2)
+ @table.setColumnWidth(0, col0_width)
+ @table.setColumnWidth(1, col1_width)
+ end
+
+ def justify_table
+ for col in 0..@table.numCols-1
+ for row in 0..@table.numRows-1
+ @table.getItem(row, col).justify = FXTableItem::LEFT
+ end
+ end
+ end
+ end
+
+ class CertDetail
+ def initialize(observer, detail)
+ @observer = observer
+ @detail = detail
+ end
+
+ def show(item, tag)
+ if item.nil?
+ @detail.text = ''
+ return
+ end
+ case item
+ when OpenSSL::X509::Certificate
+ show_cert(item, tag)
+ when OpenSSL::X509::CRL
+ show_crl(item, tag)
+ when OpenSSL::X509::Revoked
+ show_revoked(item, tag)
+ when OpenSSL::X509::Request
+ show_request(item, tag)
+ else
+ raise NotImplementedError.new("Unknown item type #{item.class}.")
+ end
+ end
+
+ private
+
+ def show_cert(cert, tag)
+ wrap = CertDump.new(cert)
+ @detail.text = wrap.get_dump(tag)
+ end
+
+ def show_crl(crl, tag)
+ wrap = CrlDump.new(crl)
+ @detail.text = wrap.get_dump(tag)
+ end
+
+ def show_revoked(revoked, tag)
+ wrap = RevokedDump.new(revoked)
+ @detail.text = wrap.get_dump(tag)
+ end
+
+ def show_request(request, tag)
+ wrap = RequestDump.new(request)
+ @detail.text = wrap.get_dump(tag)
+ end
+ end
+
+ attr_reader :cert_store
+
+ def initialize(app, cert_store)
+ @cert_store = cert_store
+ @verify_filter = 0
+ @verify_filename = nil
+ full_width = 800
+ full_height = 500
+ horz_pos = 300
+
+ super(app, "Certificate store", nil, nil, DECOR_ALL, 0, 0, full_width,
+ full_height)
+
+ FXTooltip.new(self.getApp())
+
+ menubar = FXMenubar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
+ file_menu = FXMenuPane.new(self)
+ FXMenuTitle.new(menubar, "&File", nil, file_menu)
+ file_open_menu = FXMenuPane.new(self)
+ FXMenuCommand.new(file_open_menu, "&Directory\tCtl-O").connect(SEL_COMMAND,
+ method(:on_cmd_file_open_dir))
+ FXMenuCascade.new(file_menu, "&Open\tCtl-O", nil, file_open_menu)
+ FXMenuCommand.new(file_menu, "&Quit\tCtl-Q", nil, getApp(), FXApp::ID_QUIT)
+
+ tool_menu = FXMenuPane.new(self)
+ FXMenuTitle.new(menubar, "&Tool", nil, tool_menu)
+ FXMenuCommand.new(tool_menu, "&Verify\tCtl-N").connect(SEL_COMMAND,
+ method(:on_cmd_tool_verify))
+ FXMenuCommand.new(tool_menu, "&Show Request\tCtl-R").connect(SEL_COMMAND,
+ method(:on_cmd_tool_request))
+
+ base_frame = FXHorizontalFrame.new(self, LAYOUT_FILL_X | LAYOUT_FILL_Y)
+ splitter_horz = FXSplitter.new(base_frame, LAYOUT_SIDE_TOP | LAYOUT_FILL_X |
+ LAYOUT_FILL_Y | SPLITTER_TRACKING | SPLITTER_HORIZONTAL)
+
+ # Cert tree
+ cert_tree_frame = FXHorizontalFrame.new(splitter_horz, LAYOUT_FILL_X |
+ LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK)
+ cert_tree_frame.setWidth(horz_pos)
+ cert_tree = FXTreeList.new(cert_tree_frame, 0, nil, 0,
+ TREELIST_BROWSESELECT | TREELIST_SHOWS_LINES | TREELIST_SHOWS_BOXES |
+ TREELIST_ROOT_BOXES | LAYOUT_FILL_X | LAYOUT_FILL_Y)
+ @cert_tree = CertTree.new(self, cert_tree)
+
+ # Cert info
+ splitter_vert = FXSplitter.new(splitter_horz, LAYOUT_SIDE_TOP |
+ LAYOUT_FILL_X | LAYOUT_FILL_Y | SPLITTER_TRACKING | SPLITTER_VERTICAL |
+ SPLITTER_REVERSED)
+ cert_list_base = FXVerticalFrame.new(splitter_vert, LAYOUT_FILL_X |
+ LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0)
+ cert_list_frame = FXHorizontalFrame.new(cert_list_base, FRAME_SUNKEN |
+ FRAME_THICK | LAYOUT_FILL_X | LAYOUT_FILL_Y)
+ cert_info = FXTable.new(cert_list_frame, 2, 10, nil, 0, FRAME_SUNKEN |
+ TABLE_COL_SIZABLE | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 2, 2, 2, 2)
+ @cert_info = CertInfo.new(self, cert_info)
+
+ cert_detail_base = FXVerticalFrame.new(splitter_vert, LAYOUT_FILL_X |
+ LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0)
+ cert_detail_frame = FXHorizontalFrame.new(cert_detail_base, FRAME_SUNKEN |
+ FRAME_THICK | LAYOUT_FILL_X | LAYOUT_FILL_Y)
+ cert_detail = FXText.new(cert_detail_frame, nil, 0, TEXT_READONLY |
+ LAYOUT_FILL_X | LAYOUT_FILL_Y)
+ @cert_detail = CertDetail.new(self, cert_detail)
+
+ show_init
+ end
+
+ def create
+ super
+ show(PLACEMENT_SCREEN)
+ end
+
+ def show_init
+ @cert_tree.show(@cert_store)
+ show_item(nil)
+ end
+
+ def show_certs
+ @cert_tree.show_certs(@cert_store)
+ end
+
+ def show_request(req)
+ @cert_tree.show_request(req)
+ end
+
+ def show_verify_path(verify_path)
+ @cert_tree.show_verify_path(verify_path)
+ end
+
+ def show_item(item)
+ @cert_info.show(item) if @cert_info
+ end
+
+ def show_detail(item, tag)
+ @cert_detail.show(item, tag) if @cert_detail
+ end
+
+ def verify(certfile)
+ path = verify_certfile(certfile)
+ show_certs # CRL could be change.
+ show_verify_path(path)
+ end
+
+private
+
+ def on_cmd_file_open_dir(sender, sel, ptr)
+ dir = FXFileDialog.getOpenDirectory(self, "Open certificate directory", ".")
+ unless dir.empty?
+ begin
+ @cert_store = CertStore.new(dir)
+ rescue
+ show_error($!)
+ end
+ show_init
+ end
+ 1
+ end
+
+ def on_cmd_tool_verify(sender, sel, ptr)
+ dialog = FXFileDialog.new(self, "Verify certificate")
+ dialog.filename = ''
+ dialog.patternList = ["All Files (*)", "PEM formatted certificate (*.pem)"]
+ dialog.currentPattern = @verify_filter
+ if dialog.execute != 0
+ @verify_filename = dialog.filename
+ verify(@verify_filename)
+ end
+ @verify_filter = dialog.currentPattern
+ 1
+ end
+
+ def on_cmd_tool_request(sender, sel, ptr)
+ dialog = FXFileDialog.new(self, "Show request")
+ dialog.filename = ''
+ dialog.patternList = ["All Files (*)", "PEM formatted certificate (*.pem)"]
+ if dialog.execute != 0
+ req = @cert_store.generate_cert(dialog.filename)
+ show_request(req)
+ end
+ 1
+ end
+
+ def verify_certfile(filename)
+ begin
+ cert = @cert_store.generate_cert(filename)
+ result = @cert_store.verify(cert)
+ @cert_store.scan_certs
+ result
+ rescue
+ show_error($!)
+ []
+ end
+ end
+
+ def show_error(e)
+ msg = e.inspect + "\n" + e.backtrace.join("\n")
+ FXMessageBox.error(self, MBOX_OK, "Error", msg)
+ end
+end
+
+getopts nil, "cert:"
+
+certs_dir = ARGV.shift or raise "#{$0} cert_dir"
+certfile = $OPT_cert
+app = FXApp.new("CertStore", "FoxTest")
+cert_store = CertStore.new(certs_dir)
+w = CertStoreView.new(app, cert_store)
+app.create
+if certfile
+ w.verify(certfile)
+end
+app.run
diff --git a/ruby_1_8_6/sample/openssl/certstore.rb b/ruby_1_8_6/sample/openssl/certstore.rb
new file mode 100644
index 0000000000..bbc637f668
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/openssl/cipher.rb b/ruby_1_8_6/sample/openssl/cipher.rb
new file mode 100644
index 0000000000..6e8cdb9427
--- /dev/null
+++ b/ruby_1_8_6/sample/openssl/cipher.rb
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+require 'openssl'
+
+text = "abcdefghijklmnopqrstuvwxyz"
+pass = "secret password"
+salt = "8 octets" # or nil
+alg = "DES-EDE3-CBC"
+#alg = "AES-128-CBC"
+
+puts "--Setup--"
+puts %(clear text: "#{text}")
+puts %(password: "#{pass}")
+puts %(salt: "#{salt}")
+puts %(cipher alg: "#{alg}")
+puts
+
+puts "--Encrypting--"
+des = OpenSSL::Cipher::Cipher.new(alg)
+des.pkcs5_keyivgen(pass, salt)
+des.encrypt
+cipher = des.update(text)
+cipher << des.final
+puts %(encrypted text: #{cipher.inspect})
+puts
+
+puts "--Decrypting--"
+des = OpenSSL::Cipher::Cipher.new(alg)
+des.pkcs5_keyivgen(pass, salt)
+des.decrypt
+out = des.update(cipher)
+out << des.final
+puts %(decrypted text: "#{out}")
+puts
diff --git a/ruby_1_8_6/sample/openssl/crlstore.rb b/ruby_1_8_6/sample/openssl/crlstore.rb
new file mode 100644
index 0000000000..b305913eb0
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/openssl/echo_cli.rb b/ruby_1_8_6/sample/openssl/echo_cli.rb
new file mode 100644
index 0000000000..29b356a7ad
--- /dev/null
+++ b/ruby_1_8_6/sample/openssl/echo_cli.rb
@@ -0,0 +1,37 @@
+#!/usr/bin/env ruby
+
+require 'socket'
+require 'openssl'
+require 'getopts'
+
+getopts nil, "p:2000", "c:", "k:", "C:"
+
+host = ARGV[0] || "localhost"
+port = $OPT_p
+cert_file = $OPT_c
+key_file = $OPT_k
+ca_path = $OPT_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
+ssl.sync_close = true # if true the underlying socket will be
+ # closed in SSLSocket#close. (default: false)
+while line = $stdin.gets
+ ssl.write line
+ print ssl.gets
+end
+
+ssl.close
diff --git a/ruby_1_8_6/sample/openssl/echo_svr.rb b/ruby_1_8_6/sample/openssl/echo_svr.rb
new file mode 100644
index 0000000000..be8e10fa26
--- /dev/null
+++ b/ruby_1_8_6/sample/openssl/echo_svr.rb
@@ -0,0 +1,62 @@
+#!/usr/bin/env ruby
+
+require 'socket'
+require 'openssl'
+require 'getopts'
+
+getopts nil, "p:2000", "c:", "k:", "C:"
+
+port = $OPT_p
+cert_file = $OPT_c
+key_file = $OPT_k
+ca_path = $OPT_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
+ while line = ns.gets
+ ns.write line
+ end
+ ns.close
+end
diff --git a/ruby_1_8_6/sample/openssl/gen_csr.rb b/ruby_1_8_6/sample/openssl/gen_csr.rb
new file mode 100644
index 0000000000..5858acd9f2
--- /dev/null
+++ b/ruby_1_8_6/sample/openssl/gen_csr.rb
@@ -0,0 +1,50 @@
+#!/usr/bin/env ruby
+
+require 'getopts'
+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
+
+getopts nil, "key:", "csrout:", "keyout:"
+keypair_file = $OPT_key
+csrout = $OPT_csrout || "csr.pem"
+keyout = $OPT_keyout || "keypair.pem"
+
+$stdout.sync = true
+name_str = ARGV.shift or usage()
+p name_str
+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
diff --git a/ruby_1_8_6/sample/openssl/smime_read.rb b/ruby_1_8_6/sample/openssl/smime_read.rb
new file mode 100644
index 0000000000..0f08f54f7e
--- /dev/null
+++ b/ruby_1_8_6/sample/openssl/smime_read.rb
@@ -0,0 +1,23 @@
+require 'getopts'
+require 'openssl'
+include OpenSSL
+
+getopts nil, "c:", "k:", "C:"
+
+cert_file = $OPT_c
+key_file = $OPT_k
+ca_path = $OPT_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/ruby_1_8_6/sample/openssl/smime_write.rb b/ruby_1_8_6/sample/openssl/smime_write.rb
new file mode 100644
index 0000000000..ce32cd8146
--- /dev/null
+++ b/ruby_1_8_6/sample/openssl/smime_write.rb
@@ -0,0 +1,23 @@
+require 'openssl'
+require 'getopts'
+include OpenSSL
+
+getopts nil, "c:", "k:", "r:"
+
+cert_file = $OPT_c
+key_file = $OPT_k
+rcpt_file = $OPT_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/ruby_1_8_6/sample/openssl/wget.rb b/ruby_1_8_6/sample/openssl/wget.rb
new file mode 100644
index 0000000000..0362ab980d
--- /dev/null
+++ b/ruby_1_8_6/sample/openssl/wget.rb
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+
+require 'net/https'
+require 'getopts'
+
+getopts nil, 'C:'
+
+ca_path = $OPT_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 ca_path
+ h.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ h.ca_path = ca_path
+ else
+ $stderr.puts "!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!"
+ 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/ruby_1_8_6/sample/optparse/opttest.rb b/ruby_1_8_6/sample/optparse/opttest.rb
new file mode 100644
index 0000000000..61b157bce5
--- /dev/null
+++ b/ruby_1_8_6/sample/optparse/opttest.rb
@@ -0,0 +1,85 @@
+#!/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..."
+
+ # separater
+ opts.on_tail
+ opts.on_tail("common options:")
+
+ # no argument, shows at tail
+ opts.on_tail("--help", "show this message") {puts opts; exit}
+
+ # mandatory argument
+ opts.on("-r", "--require=LIBRARY", String,
+ "require the LIBRARY, before",
+ "executing your script") {|@library|}
+
+ # optional argument
+ opts.on("-i", "--inplace=[EXTENSION]",
+ "edit ARGV files in place", # multiline description
+ "(make backup if EXTENSION supplied)") {|@inplace| @inplace ||= ''}
+
+ opts.on("-N=[NUM]", Integer) {|@number|}
+
+ # additional class
+ opts.on("-t", "--[no-]time[=TIME]", Time, "it's the time") {|@time|}
+
+ # limit argument syntax
+ opts.on("-[0-7]", "-F", "--irs=[OCTAL]", OptionParser::OctalInteger,
+ "specify record separator", "(\\0, if no argument)") {|@irs|}
+
+ # boolean switch(default true)
+ @exec = true
+ opts.on("-n", "--no-exec[=FLAG]", TrueClass, "not really execute") {|@exec|}
+
+ # array
+ opts.on("-a", "--list[=LIST,LIST]", Array, "list") {|@list|}
+
+ # fixed size array
+ opts.on("--pair[=car,cdr]", Array, "pair") {|@x, @y|}
+
+ # keyword completion
+ opts.on("--code=CODE", CODES, CODE_ALIASES, "select coding system",
+ "("+CODES.join(",")+",", " "+CODE_ALIASES.keys.join(",")+")") {|@code|}
+
+ # optional argument with keyword completion
+ opts.on("--type[=TYPE]", [:text, :binary], "select type(text, binary)") {|@type|}
+
+ # boolean switch with optional argument(default false)
+ opts.on("-v", "--[no-]verbose=[FLAG]", "run verbosely") {|@verbose|}
+
+ # easy way, set local variable
+ opts.on("-q", "--quit", "quit when ARGV is empty") {|@quit|}
+
+ # 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 {|@#{var}|}"))
+ 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
+(print ARGV.options; exit) 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/ruby_1_8_6/sample/optparse/subcommand.rb b/ruby_1_8_6/sample/optparse/subcommand.rb
new file mode 100755
index 0000000000..21c42dd60a
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/philos.rb b/ruby_1_8_6/sample/philos.rb
new file mode 100644
index 0000000000..119e7c36b9
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/pi.rb b/ruby_1_8_6/sample/pi.rb
new file mode 100644
index 0000000000..63be974285
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/rcs.awk b/ruby_1_8_6/sample/rcs.awk
new file mode 100644
index 0000000000..08979285c9
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/rcs.dat b/ruby_1_8_6/sample/rcs.dat
new file mode 100644
index 0000000000..61c88bff89
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/rcs.rb b/ruby_1_8_6/sample/rcs.rb
new file mode 100644
index 0000000000..0bdf81c45d
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/regx.rb b/ruby_1_8_6/sample/regx.rb
new file mode 100644
index 0000000000..aaf4b5f1ee
--- /dev/null
+++ b/ruby_1_8_6/sample/regx.rb
@@ -0,0 +1,23 @@
+st = "\033[7m"
+en = "\033[m"
+#st = "<<"
+#en = ">>"
+
+while TRUE
+ print "str> "
+ STDOUT.flush
+ input = gets
+ break if not input
+ if input != ""
+ str = input
+ str.chop!
+ end
+ print "pat> "
+ STDOUT.flush
+ re = gets
+ break if not re
+ re.chop!
+ str.gsub! re, "#{st}\\&#{en}"
+ print str, "\n"
+end
+print "\n"
diff --git a/ruby_1_8_6/sample/rss/blend.rb b/ruby_1_8_6/sample/rss/blend.rb
new file mode 100755
index 0000000000..2fbd6efed6
--- /dev/null
+++ b/ruby_1_8_6/sample/rss/blend.rb
@@ -0,0 +1,73 @@
+#!/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.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/ruby_1_8_6/sample/rss/convert.rb b/ruby_1_8_6/sample/rss/convert.rb
new file mode 100755
index 0000000000..394b13e8eb
--- /dev/null
+++ b/ruby_1_8_6/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)$/
+ 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/ruby_1_8_6/sample/rss/list_description.rb b/ruby_1_8_6/sample/rss/list_description.rb
new file mode 100644
index 0000000000..bb1f9636e2
--- /dev/null
+++ b/ruby_1_8_6/sample/rss/list_description.rb
@@ -0,0 +1,82 @@
+#!/usr/bin/env ruby
+
+require "nkf"
+class String
+ # From tdiary.rb
+ def shorten( len = 120 )
+ lines = NKF::nkf( "-e -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 = "euc-jp"
+ rescue RSS::UnknownConversionMethodError
+ error($!) if verbose
+ end
+ rss.channel.title ||= "Unknown"
+ rss.items.each do |item|
+ item.title ||= "Unknown"
+ 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/ruby_1_8_6/sample/rss/re_read.rb b/ruby_1_8_6/sample/rss/re_read.rb
new file mode 100755
index 0000000000..c19a5099bb
--- /dev/null
+++ b/ruby_1_8_6/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 RSS: #{fname}"
+ RSS::Parser.parse(rss.to_s)
+ read = true
+ rescue RSS::InvalidRSSError
+ error($!) if verbose
+ ## do non validate parse for invalid RSS 1.0
+ begin
+ rss = RSS::Parser.parse(source, false)
+ rescue RSS::Error
+ ## invalid RSS.
+ error($!) if verbose
+ end
+ rescue RSS::Error
+ error($!) if verbose
+ end
+
+ if rss.nil?
+ puts "Invalid RSS: #{fname}"
+ elsif !read
+ puts "Re-read invalid RSS: #{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/ruby_1_8_6/sample/rss/rss_recent.rb b/ruby_1_8_6/sample/rss/rss_recent.rb
new file mode 100644
index 0000000000..7821df5c7b
--- /dev/null
+++ b/ruby_1_8_6/sample/rss/rss_recent.rb
@@ -0,0 +1,81 @@
+#!/usr/bin/env ruby
+
+require "nkf"
+class String
+ # From tdiary.rb
+ def shorten( len = 120 )
+ lines = NKF::nkf( "-e -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 = "euc-jp"
+ rescue RSS::UnknownConversionMethodError
+ error($!) if verbose
+ end
+ rss.items.each do |item|
+ if item.respond_to?(:pubDate) and item.pubDate
+ class << item
+ alias_method(:dc_date, :pubDate)
+ end
+ end
+ if item.respond_to?(:dc_date) and item.dc_date
+ items << [rss.channel, item]
+ end
+ 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/ruby_1_8_6/sample/sieve.rb b/ruby_1_8_6/sample/sieve.rb
new file mode 100644
index 0000000000..e0bb21d640
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/svr.rb b/ruby_1_8_6/sample/svr.rb
new file mode 100644
index 0000000000..11cfc5fbfe
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/test.rb b/ruby_1_8_6/sample/test.rb
new file mode 100644
index 0000000000..e7f2d251b7
--- /dev/null
+++ b/ruby_1_8_6/sample/test.rb
@@ -0,0 +1,2036 @@
+#! /usr/bin/env ruby
+
+$KCODE = "none"
+$testnum=0
+$ntest=0
+$failed = 0
+
+def test_check(what)
+ printf "%s\n", what
+ $what = what
+ $testnum = 0
+end
+
+def test_ok(cond,n=1)
+ $testnum+=1
+ $ntest+=1
+ if cond
+ printf "ok %d\n", $testnum
+ else
+ where = caller(n)[0]
+ printf "not ok %s %d -- %s\n", $what, $testnum, where
+ $failed+=1
+ end
+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 = *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,2])
+a = *[*[]]; test_ok(a == nil)
+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 == [[]])
+*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 == [])
+*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 = *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,[]])
+
+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 *nil; end; f {|a| test_ok(a == nil)}
+def f; yield *1; end; f {|a| test_ok(a == 1)}
+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]]; 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 *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,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 *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 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 *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 == nil)
+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 == nil)
+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 *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 == nil)
+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 == nil)
+def r; return *[*[]]; end; a = *r(); test_ok(a == nil)
+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 == [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 *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 == [nil])
+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 == [nil])
+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 *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 == [nil])
+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 == [nil])
+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,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 *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,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])
+
+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 *nil; end; test_ok(a == nil)
+a = loop do break *1; end; test_ok(a == 1)
+a = loop do break *[]; end; test_ok(a == nil)
+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 == nil)
+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 *nil; end; test_ok(a == [nil])
+*a = loop do break *1; end; test_ok(a == [1])
+*a = loop do break *[]; end; test_ok(a == [nil])
+*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 == [nil])
+*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 *nil; end; test_ok(a == [nil])
+*a = *loop do break *1; end; test_ok(a == [1])
+*a = *loop do break *[]; end; test_ok(a == [nil])
+*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 == [nil])
+*a = *loop do break *[*[1]]; end; test_ok(a == [1])
+*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 *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,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(nil){next *nil}
+r(1){next *1}
+r(nil){next *[]}
+r(1){next *[1]}
+r(nil){next *[nil]}
+r([]){next *[[]]}
+r(nil){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([nil]){next *nil}
+r([1]){next *1}
+r([nil]){next *[]}
+r([1]){next *[1]}
+r([nil]){next *[nil]}
+r([]){next *[[]]}
+r([1,2]){next *[1,2]}
+r([nil]){next *[*[]]}
+r([1]){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,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,nil,[]]){next *nil}
+r([1,nil,[]]){next *1}
+r([nil,nil,[]]){next *[]}
+r([1,nil,[]]){next *[1]}
+r([nil,nil,[]]){next *[nil]}
+r([nil,nil,[]]){next *[[]]}
+r([1,2,[]]){next *[1,2]}
+r([nil,nil,[]]){next *[*[]]}
+r([1,nil,[]]){next *[*[1]]}
+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";
+
+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 tmp.gets()
+ line = $_
+ gsub(/vt100/, 'VT100')
+ if $_ != line
+ $_.gsub!('VT100', 'Vt100')
+ redo
+ end
+ $bad = 1 if /vt100/ =~ $_
+ $bad = 1 if /VT100/ =~ $_
+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
+ test_ok(true) if $! == $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 no 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}
+$y = {1, 2, 2, 4, 3, 6}
+
+test_ok($x[1] == 2)
+
+test_ok(begin
+ for k,v in $y
+ 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 = $y.keys.sort.join(":")
+test_ok($z == "1:2:3")
+
+$z = $y.values.sort.join(":")
+test_ok($z == "2:4:6")
+test_ok($x == $y)
+
+$y.shift
+test_ok($y.length == 2)
+
+$z = [1,2]
+$y[$z] = 256
+test_ok($y[$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
+
+tt{|i| break if i == 5}
+test_ok(i == 5)
+
+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])
+
+$done = false
+$x = []
+for i in 1 .. 7 # see how retry works in iterator loop
+ if i == 4 and not $done
+ $done = true
+ retry
+ end
+ $x.push(i)
+end
+test_ok($x.size == 10)
+test_ok($x == [1, 2, 3, 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 m
+ test_ok(block_given?)
+end
+m{p 'test'}
+
+def m
+ test_ok(block_given?,&proc{})
+end
+m{p 'test'}
+
+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 argument_test(state, proc, *args)
+ x = state
+ begin
+ proc.call(*args)
+ rescue ArgumentError
+ x = !x
+ end
+ test_ok(x,2)
+end
+
+argument_test(true, lambda{||})
+argument_test(false, lambda{||}, 1)
+argument_test(true, lambda{|a,|}, 1)
+argument_test(false, lambda{|a,|})
+argument_test(false, lambda{|a,|}, 1,2)
+
+def get_block(&block)
+ block
+end
+
+test_ok(Proc == get_block{}.class)
+argument_test(true, get_block{||})
+argument_test(true, get_block{||}, 1)
+argument_test(true, get_block{|a,|}, 1)
+argument_test(true, get_block{|a,|})
+argument_test(true, get_block{|a,|}, 1,2)
+
+argument_test(true, get_block(&lambda{||}))
+argument_test(false, get_block(&lambda{||}),1)
+argument_test(true, get_block(&lambda{|a,|}),1)
+argument_test(false, get_block(&lambda{|a,|}),1,2)
+
+block = get_block{11}
+test_ok(block.class == Proc)
+test_ok(block.to_proc.class == Proc)
+test_ok(block.clone.call == 11)
+test_ok(get_block(&block).class == Proc)
+
+lambda = lambda{44}
+test_ok(lambda.class == Proc)
+test_ok(lambda.to_proc.class == Proc)
+test_ok(lambda.clone.call == 44)
+test_ok(get_block(&lambda).class == Proc)
+
+test_ok(Proc.new{|a,| a}.call(1,2,3) == 1)
+argument_test(true, Proc.new{|a,|}, 1,2)
+
+def test_return1
+ Proc.new {
+ return 55
+ }.call + 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
+ proc_call{return 42}+1
+end
+test_ok(proc_return1() == 42)
+def proc_return2
+ proc_yield{return 42}+1
+end
+test_ok(proc_return2() == 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, get_block{break})
+ljump_test(true, lambda{break})
+
+test_ok(block.arity == -1)
+test_ok(lambda.arity == -1)
+test_ok(lambda{||}.arity == 0)
+test_ok(lambda{|a|}.arity == 1)
+test_ok(lambda{|a,|}.arity == 1)
+test_ok(lambda{|a,b|}.arity == 2)
+
+def marity_test(m)
+ method = method(m)
+ test_ok(method.arity == method.to_proc.arity)
+end
+marity_test(:test_ok)
+marity_test(:marity_test)
+marity_test(:p)
+
+lambda(&method(:test_ok)).call(true)
+lambda(&get_block{|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}
+
+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)
+ p i
+ $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 == 225)
+test_ok(?\M-\C-a == 129)
+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 != $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{|i| i}
+test_ok($proc.call(2) == 2)
+test_ok($proc.call(3) == 3)
+
+$proc = proc{|i| i*2}
+test_ok($proc.call(2) == 4)
+test_ok($proc.call(3) == 6)
+
+proc{
+ iii=5 # nested local variable
+ $proc = proc{|i|
+ iii = i
+ }
+ $proc2 = proc {
+ $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{|sig| $x = 2}
+ Process.kill "SIGINT", $$
+ sleep 0.1
+ test_ok($x == 2)
+
+ trap "SIGINT", proc{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 = proc{}
+eval "i4 = 1", x
+test_ok(eval("i4", x) == 1)
+x = proc{proc{}}.call
+eval "i4 = 22", x
+test_ok(eval("i4", x) == 22)
+$x = []
+x = proc{proc{}}.call
+eval "(0..9).each{|i5| $x[i5] = proc{i5*2}}", x
+test_ok($x[4].call == 8)
+
+x = binding
+eval "i = 1", x
+test_ok(eval("i", x) == 1)
+x = proc{binding}.call
+eval "i = 22", x
+test_ok(eval("i", x) == 22)
+$x = []
+x = proc{binding}.call
+eval "(0..9).each{|i5| $x[i5] = proc{i5*2}}", x
+test_ok($x[4].call == 8)
+x = proc{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 {
+ p = binding
+ eval "foo11 = 1", p
+ foo22 = 5
+ proc{foo11=22}.call
+ proc{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
+
+p1 = proc{i7 = 0; proc{i7}}.call
+test_ok(p1.call == 0)
+eval "i7=5", p1
+test_ok(p1.call == 5)
+test_ok(!defined?(i7))
+
+p1 = proc{i7 = 0; proc{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)
+
+test_check "system"
+test_ok(`echo foobar` == "foobar\n")
+test_ok(`./miniruby -e 'print "foobar"'` == 'foobar')
+
+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` == 'nil')
+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"`
+
+$bad = false
+if (dir = File.dirname(File.dirname($0))) == '.'
+ dir = ""
+else
+ dir << "/"
+end
+
+def valid_syntax?(code, fname)
+ eval("BEGIN {return true}\n#{code}", nil, fname, 0)
+rescue Exception
+ puts $!.message
+ false
+end
+
+for script in Dir["#{dir}{lib,sample,ext}/**/*.rb"]
+ unless valid_syntax? IO::read(script), script
+ $bad = true
+ end
+end
+test_ok(!$bad)
+
+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"
+ 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"
+ include Olympians # OK to cause warning (intentional)
+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_check "trace"
+$x = 1234
+$y = 0
+trace_var :$x, proc{$y = $x}
+$x = 40414
+test_ok($y == $x)
+
+untrace_var :$x
+$x = 19660208
+test_ok($y != $x)
+
+trace_var :$x, proc{$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 "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
+
+if $failed > 0
+ printf "test: %d failed %d\n", $ntest, $failed
+else
+ printf "end of test(test: %d)\n", $ntest
+end
diff --git a/ruby_1_8_6/sample/testunit/adder.rb b/ruby_1_8_6/sample/testunit/adder.rb
new file mode 100644
index 0000000000..aa5c88cc7b
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/testunit/subtracter.rb b/ruby_1_8_6/sample/testunit/subtracter.rb
new file mode 100644
index 0000000000..2c08247805
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/testunit/tc_adder.rb b/ruby_1_8_6/sample/testunit/tc_adder.rb
new file mode 100644
index 0000000000..8453beb20a
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/testunit/tc_subtracter.rb b/ruby_1_8_6/sample/testunit/tc_subtracter.rb
new file mode 100644
index 0000000000..d2c8313350
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/testunit/ts_examples.rb b/ruby_1_8_6/sample/testunit/ts_examples.rb
new file mode 100644
index 0000000000..3d24dd6522
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/time.rb b/ruby_1_8_6/sample/time.rb
new file mode 100644
index 0000000000..84fa9e1a8d
--- /dev/null
+++ b/ruby_1_8_6/sample/time.rb
@@ -0,0 +1,8 @@
+#! /usr/local/bin/ruby
+cmd = ARGV.join(" ")
+b = Time.now
+system(cmd)
+e = Time.now
+ut, st, cut, cst = Time.times.to_a
+total = (e - b).to_f
+STDERR.printf "%11.1f real %11.1f user %11.1f sys\n", total, cut, cst
diff --git a/ruby_1_8_6/sample/trojan.rb b/ruby_1_8_6/sample/trojan.rb
new file mode 100644
index 0000000000..3a35ac21c2
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/tsvr.rb b/ruby_1_8_6/sample/tsvr.rb
new file mode 100644
index 0000000000..52cdd32dce
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/uumerge.rb b/ruby_1_8_6/sample/uumerge.rb
new file mode 100644
index 0000000000..2576bcb864
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/webrick/demo-app.rb b/ruby_1_8_6/sample/webrick/demo-app.rb
new file mode 100644
index 0000000000..c7a2a0a6a4
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/webrick/demo-multipart.cgi b/ruby_1_8_6/sample/webrick/demo-multipart.cgi
new file mode 100644
index 0000000000..0893fadadf
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/webrick/demo-servlet.rb b/ruby_1_8_6/sample/webrick/demo-servlet.rb
new file mode 100644
index 0000000000..9c18cc65d1
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/webrick/demo-urlencoded.cgi b/ruby_1_8_6/sample/webrick/demo-urlencoded.cgi
new file mode 100644
index 0000000000..e4706f8b59
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/webrick/hello.cgi b/ruby_1_8_6/sample/webrick/hello.cgi
new file mode 100644
index 0000000000..35d2240df0
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/webrick/hello.rb b/ruby_1_8_6/sample/webrick/hello.rb
new file mode 100644
index 0000000000..4d02676818
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/webrick/httpd.rb b/ruby_1_8_6/sample/webrick/httpd.rb
new file mode 100644
index 0000000000..b0edf47582
--- /dev/null
+++ b/ruby_1_8_6/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/ruby_1_8_6/sample/webrick/httpproxy.rb b/ruby_1_8_6/sample/webrick/httpproxy.rb
new file mode 100644
index 0000000000..bca0cc4626
--- /dev/null
+++ b/ruby_1_8_6/sample/webrick/httpproxy.rb
@@ -0,0 +1,26 @@
+require "webrick"
+require "webrick/httpproxy"
+
+# :ProxyContentHandler will be invoked before sending
+# response to User-Agenge. You can inspect the pair of
+# request and response messages (or can 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/ruby_1_8_6/sample/webrick/httpsd.rb b/ruby_1_8_6/sample/webrick/httpsd.rb
new file mode 100644
index 0000000000..a120782c3c
--- /dev/null
+++ b/ruby_1_8_6/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