From 0dc342de848a642ecce8db697b8fecd83a63e117 Mon Sep 17 00:00:00 2001 From: yugui Date: Mon, 25 Aug 2008 15:02:05 +0000 Subject: added tag v1_9_0_4 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_0_4@18845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- trunk/sample/README | 47 + trunk/sample/biorhythm.rb | 124 ++ trunk/sample/cal.rb | 166 +++ trunk/sample/cbreak.rb | 36 + trunk/sample/clnt.rb | 21 + trunk/sample/coverage.rb | 60 + trunk/sample/dir.rb | 12 + trunk/sample/drb/README.rd | 56 + trunk/sample/drb/README.rd.ja | 59 + trunk/sample/drb/darray.rb | 12 + trunk/sample/drb/darrayc.rb | 47 + trunk/sample/drb/dbiff.rb | 51 + trunk/sample/drb/dcdbiff.rb | 43 + trunk/sample/drb/dchatc.rb | 41 + trunk/sample/drb/dchats.rb | 70 + trunk/sample/drb/dhasen.rb | 42 + trunk/sample/drb/dhasenc.rb | 13 + trunk/sample/drb/dlogc.rb | 16 + trunk/sample/drb/dlogd.rb | 39 + trunk/sample/drb/dqin.rb | 13 + trunk/sample/drb/dqlib.rb | 14 + trunk/sample/drb/dqout.rb | 14 + trunk/sample/drb/dqueue.rb | 12 + trunk/sample/drb/drbc.rb | 45 + trunk/sample/drb/drbch.rb | 48 + trunk/sample/drb/drbm.rb | 60 + trunk/sample/drb/drbmc.rb | 22 + trunk/sample/drb/drbs-acl.rb | 51 + trunk/sample/drb/drbs.rb | 64 + trunk/sample/drb/drbssl_c.rb | 19 + trunk/sample/drb/drbssl_s.rb | 31 + trunk/sample/drb/extserv_test.rb | 80 ++ trunk/sample/drb/gw_ct.rb | 29 + trunk/sample/drb/gw_cu.rb | 28 + trunk/sample/drb/gw_s.rb | 10 + trunk/sample/drb/holderc.rb | 22 + trunk/sample/drb/holders.rb | 63 + trunk/sample/drb/http0.rb | 77 ++ trunk/sample/drb/http0serv.rb | 119 ++ trunk/sample/drb/name.rb | 117 ++ trunk/sample/drb/namec.rb | 36 + trunk/sample/drb/old_tuplespace.rb | 214 +++ trunk/sample/drb/rinda_ts.rb | 7 + trunk/sample/drb/rindac.rb | 17 + trunk/sample/drb/rindas.rb | 18 + trunk/sample/drb/ring_echo.rb | 30 + trunk/sample/drb/ring_inspect.rb | 30 + trunk/sample/drb/ring_place.rb | 25 + trunk/sample/drb/simpletuple.rb | 91 ++ trunk/sample/drb/speedc.rb | 21 + trunk/sample/drb/speeds.rb | 31 + trunk/sample/dualstack-fetch.rb | 48 + trunk/sample/dualstack-httpd.rb | 55 + trunk/sample/eval.rb | 41 + trunk/sample/export.rb | 40 + trunk/sample/exyacc.rb | 20 + trunk/sample/fact.rb | 9 + trunk/sample/fib.awk | 5 + trunk/sample/fib.pl | 11 + trunk/sample/fib.py | 10 + trunk/sample/fib.rb | 10 + trunk/sample/fib.scm | 8 + trunk/sample/freq.rb | 12 + trunk/sample/from.rb | 113 ++ trunk/sample/fullpath.rb | 23 + trunk/sample/less.rb | 17 + trunk/sample/list.rb | 80 ++ trunk/sample/list2.rb | 16 + trunk/sample/list3.rb | 18 + trunk/sample/logger/app.rb | 46 + trunk/sample/logger/log.rb | 27 + trunk/sample/logger/shifting.rb | 26 + trunk/sample/mine.rb | 175 +++ trunk/sample/mkproto.rb | 27 + trunk/sample/mpart.rb | 44 + trunk/sample/observ.rb | 32 + trunk/sample/occur.pl | 9 + trunk/sample/occur.rb | 12 + trunk/sample/occur2.rb | 16 + trunk/sample/openssl/c_rehash.rb | 174 +++ trunk/sample/openssl/cert2text.rb | 23 + trunk/sample/openssl/certstore.rb | 161 +++ trunk/sample/openssl/cipher.rb | 54 + trunk/sample/openssl/crlstore.rb | 122 ++ trunk/sample/openssl/echo_cli.rb | 44 + trunk/sample/openssl/echo_svr.rb | 65 + trunk/sample/openssl/gen_csr.rb | 51 + trunk/sample/openssl/smime_read.rb | 23 + trunk/sample/openssl/smime_write.rb | 23 + trunk/sample/openssl/wget.rb | 34 + trunk/sample/optparse/opttest.rb | 85 ++ trunk/sample/optparse/subcommand.rb | 19 + trunk/sample/philos.rb | 54 + trunk/sample/pi.rb | 18 + trunk/sample/rcs.awk | 33 + trunk/sample/rcs.dat | 17 + trunk/sample/rcs.rb | 39 + trunk/sample/rdoc/markup/rdoc2latex.rb | 15 + trunk/sample/rdoc/markup/sample.rb | 40 + trunk/sample/ripper/ruby2html.rb | 112 ++ trunk/sample/ripper/strip-comment.rb | 19 + trunk/sample/rss/blend.rb | 79 ++ trunk/sample/rss/convert.rb | 69 + trunk/sample/rss/list_description.rb | 91 ++ trunk/sample/rss/re_read.rb | 64 + trunk/sample/rss/rss_recent.rb | 85 ++ trunk/sample/sieve.rb | 14 + trunk/sample/svr.rb | 34 + trunk/sample/test.rb | 2232 ++++++++++++++++++++++++++++++ trunk/sample/testunit/adder.rb | 13 + trunk/sample/testunit/subtracter.rb | 12 + trunk/sample/testunit/tc_adder.rb | 18 + trunk/sample/testunit/tc_subtracter.rb | 18 + trunk/sample/testunit/ts_examples.rb | 7 + trunk/sample/time.rb | 12 + trunk/sample/trojan.rb | 15 + trunk/sample/tsvr.rb | 20 + trunk/sample/uumerge.rb | 43 + trunk/sample/webrick/demo-app.rb | 66 + trunk/sample/webrick/demo-multipart.cgi | 12 + trunk/sample/webrick/demo-servlet.rb | 6 + trunk/sample/webrick/demo-urlencoded.cgi | 12 + trunk/sample/webrick/hello.cgi | 11 + trunk/sample/webrick/hello.rb | 8 + trunk/sample/webrick/httpd.rb | 23 + trunk/sample/webrick/httpproxy.rb | 26 + trunk/sample/webrick/httpsd.rb | 33 + 127 files changed, 7611 insertions(+) create mode 100644 trunk/sample/README create mode 100644 trunk/sample/biorhythm.rb create mode 100644 trunk/sample/cal.rb create mode 100644 trunk/sample/cbreak.rb create mode 100644 trunk/sample/clnt.rb create mode 100644 trunk/sample/coverage.rb create mode 100644 trunk/sample/dir.rb create mode 100644 trunk/sample/drb/README.rd create mode 100644 trunk/sample/drb/README.rd.ja create mode 100644 trunk/sample/drb/darray.rb create mode 100644 trunk/sample/drb/darrayc.rb create mode 100644 trunk/sample/drb/dbiff.rb create mode 100644 trunk/sample/drb/dcdbiff.rb create mode 100644 trunk/sample/drb/dchatc.rb create mode 100644 trunk/sample/drb/dchats.rb create mode 100644 trunk/sample/drb/dhasen.rb create mode 100644 trunk/sample/drb/dhasenc.rb create mode 100644 trunk/sample/drb/dlogc.rb create mode 100644 trunk/sample/drb/dlogd.rb create mode 100644 trunk/sample/drb/dqin.rb create mode 100644 trunk/sample/drb/dqlib.rb create mode 100644 trunk/sample/drb/dqout.rb create mode 100644 trunk/sample/drb/dqueue.rb create mode 100644 trunk/sample/drb/drbc.rb create mode 100644 trunk/sample/drb/drbch.rb create mode 100644 trunk/sample/drb/drbm.rb create mode 100644 trunk/sample/drb/drbmc.rb create mode 100644 trunk/sample/drb/drbs-acl.rb create mode 100644 trunk/sample/drb/drbs.rb create mode 100644 trunk/sample/drb/drbssl_c.rb create mode 100644 trunk/sample/drb/drbssl_s.rb create mode 100644 trunk/sample/drb/extserv_test.rb create mode 100644 trunk/sample/drb/gw_ct.rb create mode 100644 trunk/sample/drb/gw_cu.rb create mode 100644 trunk/sample/drb/gw_s.rb create mode 100644 trunk/sample/drb/holderc.rb create mode 100644 trunk/sample/drb/holders.rb create mode 100644 trunk/sample/drb/http0.rb create mode 100644 trunk/sample/drb/http0serv.rb create mode 100644 trunk/sample/drb/name.rb create mode 100644 trunk/sample/drb/namec.rb create mode 100644 trunk/sample/drb/old_tuplespace.rb create mode 100644 trunk/sample/drb/rinda_ts.rb create mode 100644 trunk/sample/drb/rindac.rb create mode 100644 trunk/sample/drb/rindas.rb create mode 100644 trunk/sample/drb/ring_echo.rb create mode 100644 trunk/sample/drb/ring_inspect.rb create mode 100644 trunk/sample/drb/ring_place.rb create mode 100644 trunk/sample/drb/simpletuple.rb create mode 100644 trunk/sample/drb/speedc.rb create mode 100644 trunk/sample/drb/speeds.rb create mode 100644 trunk/sample/dualstack-fetch.rb create mode 100644 trunk/sample/dualstack-httpd.rb create mode 100644 trunk/sample/eval.rb create mode 100644 trunk/sample/export.rb create mode 100644 trunk/sample/exyacc.rb create mode 100644 trunk/sample/fact.rb create mode 100644 trunk/sample/fib.awk create mode 100644 trunk/sample/fib.pl create mode 100644 trunk/sample/fib.py create mode 100644 trunk/sample/fib.rb create mode 100644 trunk/sample/fib.scm create mode 100644 trunk/sample/freq.rb create mode 100644 trunk/sample/from.rb create mode 100644 trunk/sample/fullpath.rb create mode 100644 trunk/sample/less.rb create mode 100644 trunk/sample/list.rb create mode 100644 trunk/sample/list2.rb create mode 100644 trunk/sample/list3.rb create mode 100644 trunk/sample/logger/app.rb create mode 100644 trunk/sample/logger/log.rb create mode 100644 trunk/sample/logger/shifting.rb create mode 100644 trunk/sample/mine.rb create mode 100644 trunk/sample/mkproto.rb create mode 100644 trunk/sample/mpart.rb create mode 100644 trunk/sample/observ.rb create mode 100644 trunk/sample/occur.pl create mode 100644 trunk/sample/occur.rb create mode 100644 trunk/sample/occur2.rb create mode 100644 trunk/sample/openssl/c_rehash.rb create mode 100644 trunk/sample/openssl/cert2text.rb create mode 100644 trunk/sample/openssl/certstore.rb create mode 100644 trunk/sample/openssl/cipher.rb create mode 100644 trunk/sample/openssl/crlstore.rb create mode 100644 trunk/sample/openssl/echo_cli.rb create mode 100644 trunk/sample/openssl/echo_svr.rb create mode 100644 trunk/sample/openssl/gen_csr.rb create mode 100644 trunk/sample/openssl/smime_read.rb create mode 100644 trunk/sample/openssl/smime_write.rb create mode 100644 trunk/sample/openssl/wget.rb create mode 100644 trunk/sample/optparse/opttest.rb create mode 100755 trunk/sample/optparse/subcommand.rb create mode 100644 trunk/sample/philos.rb create mode 100644 trunk/sample/pi.rb create mode 100644 trunk/sample/rcs.awk create mode 100644 trunk/sample/rcs.dat create mode 100644 trunk/sample/rcs.rb create mode 100644 trunk/sample/rdoc/markup/rdoc2latex.rb create mode 100644 trunk/sample/rdoc/markup/sample.rb create mode 100644 trunk/sample/ripper/ruby2html.rb create mode 100644 trunk/sample/ripper/strip-comment.rb create mode 100755 trunk/sample/rss/blend.rb create mode 100755 trunk/sample/rss/convert.rb create mode 100755 trunk/sample/rss/list_description.rb create mode 100755 trunk/sample/rss/re_read.rb create mode 100755 trunk/sample/rss/rss_recent.rb create mode 100644 trunk/sample/sieve.rb create mode 100644 trunk/sample/svr.rb create mode 100644 trunk/sample/test.rb create mode 100644 trunk/sample/testunit/adder.rb create mode 100644 trunk/sample/testunit/subtracter.rb create mode 100644 trunk/sample/testunit/tc_adder.rb create mode 100644 trunk/sample/testunit/tc_subtracter.rb create mode 100644 trunk/sample/testunit/ts_examples.rb create mode 100644 trunk/sample/time.rb create mode 100644 trunk/sample/trojan.rb create mode 100644 trunk/sample/tsvr.rb create mode 100644 trunk/sample/uumerge.rb create mode 100644 trunk/sample/webrick/demo-app.rb create mode 100644 trunk/sample/webrick/demo-multipart.cgi create mode 100644 trunk/sample/webrick/demo-servlet.rb create mode 100644 trunk/sample/webrick/demo-urlencoded.cgi create mode 100644 trunk/sample/webrick/hello.cgi create mode 100644 trunk/sample/webrick/hello.rb create mode 100644 trunk/sample/webrick/httpd.rb create mode 100644 trunk/sample/webrick/httpproxy.rb create mode 100644 trunk/sample/webrick/httpsd.rb (limited to 'trunk/sample') diff --git a/trunk/sample/README b/trunk/sample/README new file mode 100644 index 0000000000..9187a9df2a --- /dev/null +++ b/trunk/sample/README @@ -0,0 +1,47 @@ +README this file +biorhythm.rb biorhythm calculator +cal.rb cal(1) clone +cbreak.rb no echo done by ioctl +clnt.rb socket client +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 +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 +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 +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/trunk/sample/biorhythm.rb b/trunk/sample/biorhythm.rb new file mode 100644 index 0000000000..6465daa29f --- /dev/null +++ b/trunk/sample/biorhythm.rb @@ -0,0 +1,124 @@ +#!/usr/local/bin/ruby +# +# biorhythm.rb - +# $Release Version: $ +# $Revision$ +# by Yasuo OHBA(STAFS Development Room) +# +# -- +# +# +# + +# probably based on: +# +# Newsgroups: comp.sources.misc,de.comp.sources.os9 +# From: fkk@stasys.sta.sub.org (Frank Kaefer) +# Subject: v41i126: br - Biorhythm v3.0, Part01/01 +# Message-ID: <1994Feb1.070616.15982@sparky.sterling.com> +# Sender: kent@sparky.sterling.com (Kent Landfield) +# Organization: Sterling Software +# Date: Tue, 1 Feb 1994 07:06:16 GMT +# +# Posting-number: Volume 41, Issue 126 +# Archive-name: br/part01 +# Environment: basic, dos, os9 + +include Math +require "date.rb" +require "optparse" +require "optparse/date" + +def 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 prompt(msg) + $stderr.print msg + return gets.chomp +end + +# +# main program +# +options = { + :graph => true, + :date => Date.today, + :days => 9, +} +ARGV.options do |opts| + opts.on("-b", "--birthday=DATE", Date, "specify your birthday"){|v| + options[:birthday] = v + } + opts.on("--date=DATE", Date, "specify date to show"){|v| + options[:date] = v + } + opts.on("-g", "--show-graph", TrueClass, "show graph (default)"){|v| + options[:graph] = v + } + opts.on("-v", "--show-values", TrueClass, "show values"){|v| + options[:graph] = !v + } + opts.on("--days=DAYS", Integer, "graph range (only in effect for graph)"){|v| + options[:days] = v - 1 + } + opts.on_tail("-h", "--help", "show this message"){puts opts; exit} + begin + opts.parse! + rescue => ex + puts "Error: #{ex.message}" + puts opts + exit + end +end + +bd = options[:birthday] || Date.parse(prompt("Your birthday (YYYYMMDD): ")) +dd = options[:date] || Date.today +ausgabeart = options[:graph] ? "g" : "v" +display_period = options[:days] + +if ausgabeart == "v" + printHeader(bd.year, bd.month, bd.day, dd - bd, bd.strftime("%a")) + 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 + printHeader(bd.year, bd.month, bd.day, dd - bd, bd.strftime("%a")) + print " P=physical, E=emotional, M=mental\n" + print " -------------------------+-------------------------\n" + print " Bad Condition | Good Condition\n" + print " -------------------------+-------------------------\n" + + (dd - bd).step(dd - bd + display_period) do |z| + phys, emot, geist = 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/trunk/sample/cal.rb b/trunk/sample/cal.rb new file mode 100644 index 0000000000..387657490f --- /dev/null +++ b/trunk/sample/cal.rb @@ -0,0 +1,166 @@ +#! /usr/bin/env ruby + +# cal.rb: Written by Tadayoshi Funaba 1998-2004,2006,2008 +# $Id: cal.rb,v 2.11 2008-01-06 08:42:17+09 tadf Exp $ + +require 'date' + +class Cal + + START = + { + 'cn' => Date::GREGORIAN, # China + 'de' => 2342032, # Germany (protestant states) + 'dk' => 2342032, # Denmark + 'es' => 2299161, # Spain + 'fi' => 2361390, # Finland + 'fr' => 2299227, # France + 'gb' => 2361222, # United Kingdom + 'gr' => 2423868, # Greece + 'hu' => 2301004, # Hungary + 'it' => 2299161, # Italy + 'jp' => Date::GREGORIAN, # Japan + 'no' => 2342032, # Norway + 'pl' => 2299161, # Poland + 'pt' => 2299161, # Portugal + 'ru' => 2421639, # Russia + 'se' => 2361390, # Sweden + 'us' => 2361222, # United States + 'os' => Date::JULIAN, # (old style) + 'ns' => Date::GREGORIAN # (new style) + } + + DEFAULT_START = 'gb' + + def initialize + opt_j; opt_m; opt_t; opt_y; opt_c + end + + def opt_j(flag=false) @opt_j = flag end + def opt_m(flag=false) @opt_m = flag end + def opt_t(flag=false) @opt_t = flag end + def opt_y(flag=false) @opt_y = flag end + + def opt_c(arg=DEFAULT_START) @start = START[arg] end + + def set_params + @dw = if @opt_j then 3 else 2 end + @mw = (@dw + 1) * 7 - 1 + @mn = if @opt_j then 2 else 3 end + @tw = (@mw + 2) * @mn - 2 + @k = if @opt_m then 1 else 0 end + @da = if @opt_j then :yday else :mday end + end + + def pict(y, m) + d = (1..31).detect{|x| Date.valid_date?(y, m, x, @start)} + fi = Date.new(y, m, d, @start) + fi -= (fi.jd - @k + 1) % 7 + + ve = (fi..fi + 6).collect{|cu| + %w(S M Tu W Th F S)[cu.wday] + } + ve += (fi..fi + 41).collect{|cu| + if cu.mon == m then cu.send(@da) end.to_s + } + + ve = ve.collect{|e| e.rjust(@dw)} + + gr = group(ve, 7) + gr = trans(gr) if @opt_t + ta = gr.collect{|xs| xs.join(' ')} + + ca = %w(January February March April May June July + August September October November December)[m - 1] + ca = ca + ' ' + y.to_s if !@opt_y + ca = ca.center(@mw) + + ta.unshift(ca) + end + + def group(xs, n) + (0..xs.size / n - 1).collect{|i| xs[i * n, n]} + end + + def trans(xs) + (0..xs[0].size - 1).collect{|i| xs.collect{|x| x[i]}} + end + + def stack(xs) + if xs.empty? then [] else xs[0] + stack(xs[1..-1]) end + end + + def block(xs, n) + stack(group(xs, n).collect{|ys| trans(ys).collect{|zs| zs.join(' ')}}) + end + + def unlines(xs) + xs.collect{|x| x + "\n"}.join + end + + def monthly(y, m) + unlines(pict(y, m)) + end + + def addmon(y, m, n) + y, m = (y * 12 + (m - 1) + n).divmod(12) + return y, m + 1 + end + + def yearly(y) + y.to_s.center(@tw) + "\n\n" + + unlines(block((0..11).collect{|n| pict(*addmon(y, 1, n))}, @mn)) + "\n" + end + + def print(y, m) + set_params + if @opt_y then yearly(y) else monthly(y, m) end + end + +end + +if __FILE__ == $0 + + require 'getoptlong' + + def usage + warn 'usage: cal [-c iso3166] [-jmty] [[month] year]' + exit 1 + end + + cal = Cal.new + + begin + GetoptLong.new(['-c', GetoptLong::REQUIRED_ARGUMENT], + ['-j', GetoptLong::NO_ARGUMENT], + ['-m', GetoptLong::NO_ARGUMENT], + ['-t', GetoptLong::NO_ARGUMENT], + ['-y', GetoptLong::NO_ARGUMENT]). + each do |opt, arg| + case opt + when '-c'; cal.opt_c(arg) || raise + when '-j'; cal.opt_j(true) + when '-m'; cal.opt_m(true) + when '-t'; cal.opt_t(true) + when '-y'; cal.opt_y(true) + end + end + rescue + usage + end + + y, m = ARGV.values_at(1, 0).compact.collect{|x| x.to_i} + cal.opt_y(true) if y && !m + + to = Date.today + y ||= to.year + m ||= to.mon + + usage unless m >= 1 && m <= 12 + usage unless y >= -4712 + + print cal.print(y, m) + +end + +# See Bird & Wadler's Introduction to functional programming 4.5. diff --git a/trunk/sample/cbreak.rb b/trunk/sample/cbreak.rb new file mode 100644 index 0000000000..76b534a76a --- /dev/null +++ b/trunk/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/trunk/sample/clnt.rb b/trunk/sample/clnt.rb new file mode 100644 index 0000000000..0f3d17bf19 --- /dev/null +++ b/trunk/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/trunk/sample/coverage.rb b/trunk/sample/coverage.rb new file mode 100644 index 0000000000..3f45e9fc98 --- /dev/null +++ b/trunk/sample/coverage.rb @@ -0,0 +1,60 @@ +require "coverage.so" + +Coverage.start + +ext = ENV["COVERUBY_EXT"] || ".cov" +accum = ENV["COVERUBY_ACCUM"] +accum = !accum || accum == "" || !(%w(f n 0).include?(accum[0])) +pwd = Dir.pwd + +at_exit do + Dir.chdir(pwd) do + Coverage.result.each do |sfile, covs| + cfile = sfile + ext + + writable = proc do |f| + File.writable?(f) || File.writable?(File.dirname(f)) + end + unless writable[cfile] + cfile = cfile.gsub(File.PATH_SEPARATOR, "#") + next unless writable[cfile] + end + + readlines = proc do |f| + File.read(f).force_encoding("ASCII-8BIT").lines.to_a + end + + sources = (readlines[sfile] rescue []) + + pcovs = [] + if accum + pcovs = (readlines[cfile] rescue []).map.with_index do |line, idx| + if line[/^\s*(?:(#####)|(\d+)|-):\s*\d+:(.*)$/n] + cov, line = $1 ? 0 : ($2 ? $2.to_i : nil), $3 + if !sources[idx] || sources[idx].chomp != line.chomp + warn("source file changed, ignoring: `#{ cfile }'") + break [] + end + cov + else + p line + warn("coverage file corrupted, ignoring: #{ cfile }") + break [] + end + end + unless pcovs.empty? || pcovs.size == covs.size + warn("coverage file changed, ignoring: `#{ cfile }'") + pcovs = [] + end + end + + open(cfile, "w") do |out| + covs.zip(sources, pcovs).each_with_index do |(cov, line, pcov), idx| + cov += pcov || 0 if cov + cov = (cov ? (cov == 0 ? "#####" : cov.to_s) : "-").rjust(9) + out.puts("%s:% 5d:%s" % [cov, idx + 1, line]) + end + end + end + end +end diff --git a/trunk/sample/dir.rb b/trunk/sample/dir.rb new file mode 100644 index 0000000000..b627383946 --- /dev/null +++ b/trunk/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/trunk/sample/drb/README.rd b/trunk/sample/drb/README.rd new file mode 100644 index 0000000000..5cf1f51913 --- /dev/null +++ b/trunk/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 - (()) + * 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/trunk/sample/drb/README.rd.ja b/trunk/sample/drb/README.rd.ja new file mode 100644 index 0000000000..04143b9ad5 --- /dev/null +++ b/trunk/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 - (()) + * 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/trunk/sample/drb/darray.rb b/trunk/sample/drb/darray.rb new file mode 100644 index 0000000000..95ee01ff03 --- /dev/null +++ b/trunk/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/trunk/sample/drb/darrayc.rb b/trunk/sample/drb/darrayc.rb new file mode 100644 index 0000000000..b181d22699 --- /dev/null +++ b/trunk/sample/drb/darrayc.rb @@ -0,0 +1,47 @@ +=begin + distributed Ruby --- Array client + Copyright (c) 1999-2001 Masatoshi SEKI +=end + +require 'drb/drb' + +there = ARGV.shift || raise("usage: #{$0} ") + +DRb.start_service(nil, nil) +ro = DRbObject.new(nil, there) +p ro.size + +puts "# collect" +a = ro.collect { |x| + x + x +} +p a + +puts "# find" +p ro.find { |x| x.kind_of? String } + +puts "# each, break" +ro.each do |x| + next if x == "five" + puts x +end + +puts "# each, break" +ro.each do |x| + break if x == "five" + puts x +end + +puts "# each, next" +ro.each do |x| + next if x == "five" + puts x +end + +puts "# each, redo" +count = 0 +ro.each do |x| + count += 1 + puts count + redo if count == 3 +end diff --git a/trunk/sample/drb/dbiff.rb b/trunk/sample/drb/dbiff.rb new file mode 100644 index 0000000000..8faef50b07 --- /dev/null +++ b/trunk/sample/drb/dbiff.rb @@ -0,0 +1,51 @@ +# +# dbiff.rb - distributed cdbiff (server) +# * original: cdbiff by Satoru Takabayashi + +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/trunk/sample/drb/dcdbiff.rb b/trunk/sample/drb/dcdbiff.rb new file mode 100644 index 0000000000..6a24680c33 --- /dev/null +++ b/trunk/sample/drb/dcdbiff.rb @@ -0,0 +1,43 @@ +# +# dcdbiff.rb - distributed cdbiff (client) +# * original: cdbiff by Satoru Takabayashi + +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/trunk/sample/drb/dchatc.rb b/trunk/sample/drb/dchatc.rb new file mode 100644 index 0000000000..b506f5bbba --- /dev/null +++ b/trunk/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} ") + 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/trunk/sample/drb/dchats.rb b/trunk/sample/drb/dchats.rb new file mode 100644 index 0000000000..012dfeeebe --- /dev/null +++ b/trunk/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/trunk/sample/drb/dhasen.rb b/trunk/sample/drb/dhasen.rb new file mode 100644 index 0000000000..fb1724afa3 --- /dev/null +++ b/trunk/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/trunk/sample/drb/dhasenc.rb b/trunk/sample/drb/dhasenc.rb new file mode 100644 index 0000000000..8114e9228d --- /dev/null +++ b/trunk/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} ") +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/trunk/sample/drb/dlogc.rb b/trunk/sample/drb/dlogc.rb new file mode 100644 index 0000000000..c75bc7b520 --- /dev/null +++ b/trunk/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} ") + +DRb.start_service +ro = DRbObject.new(nil, there) +ro.log(123) +ro.log("hello") +sleep 2 +ro.log("wakeup") + diff --git a/trunk/sample/drb/dlogd.rb b/trunk/sample/drb/dlogd.rb new file mode 100644 index 0000000000..9f9aa2fd56 --- /dev/null +++ b/trunk/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/trunk/sample/drb/dqin.rb b/trunk/sample/drb/dqin.rb new file mode 100644 index 0000000000..3ba1caa80c --- /dev/null +++ b/trunk/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} ") + +DRb.start_service +queue = DRbObject.new(nil, there) +queue.push(DQEntry.new(DRb.uri)) diff --git a/trunk/sample/drb/dqlib.rb b/trunk/sample/drb/dqlib.rb new file mode 100644 index 0000000000..75f2e6115b --- /dev/null +++ b/trunk/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/trunk/sample/drb/dqout.rb b/trunk/sample/drb/dqout.rb new file mode 100644 index 0000000000..4700e55cf7 --- /dev/null +++ b/trunk/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} ") + +DRb.start_service +queue = DRbObject.new(nil, there) +entry = queue.pop +puts entry.greeting diff --git a/trunk/sample/drb/dqueue.rb b/trunk/sample/drb/dqueue.rb new file mode 100644 index 0000000000..a5a43655fd --- /dev/null +++ b/trunk/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/trunk/sample/drb/drbc.rb b/trunk/sample/drb/drbc.rb new file mode 100644 index 0000000000..00132b46c8 --- /dev/null +++ b/trunk/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} ") + 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/trunk/sample/drb/drbch.rb b/trunk/sample/drb/drbch.rb new file mode 100644 index 0000000000..495ff1c346 --- /dev/null +++ b/trunk/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} ") + 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/trunk/sample/drb/drbm.rb b/trunk/sample/drb/drbm.rb new file mode 100644 index 0000000000..74a15a4696 --- /dev/null +++ b/trunk/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 + | [#, "FOO"] + | [#, "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/trunk/sample/drb/drbmc.rb b/trunk/sample/drb/drbmc.rb new file mode 100644 index 0000000000..c654fcea05 --- /dev/null +++ b/trunk/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} ") + 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/trunk/sample/drb/drbs-acl.rb b/trunk/sample/drb/drbs-acl.rb new file mode 100644 index 0000000000..151dd945d8 --- /dev/null +++ b/trunk/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/trunk/sample/drb/drbs.rb b/trunk/sample/drb/drbs.rb new file mode 100644 index 0000000000..b76e283c80 --- /dev/null +++ b/trunk/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/trunk/sample/drb/drbssl_c.rb b/trunk/sample/drb/drbssl_c.rb new file mode 100644 index 0000000000..65112f6e78 --- /dev/null +++ b/trunk/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/trunk/sample/drb/drbssl_s.rb b/trunk/sample/drb/drbssl_s.rb new file mode 100644 index 0000000000..4d96f591d4 --- /dev/null +++ b/trunk/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/trunk/sample/drb/extserv_test.rb b/trunk/sample/drb/extserv_test.rb new file mode 100644 index 0000000000..83d871a6a2 --- /dev/null +++ b/trunk/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 []\nclient: #{$0} [quit] " 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/trunk/sample/drb/gw_ct.rb b/trunk/sample/drb/gw_ct.rb new file mode 100644 index 0000000000..0622784018 --- /dev/null +++ b/trunk/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/trunk/sample/drb/gw_cu.rb b/trunk/sample/drb/gw_cu.rb new file mode 100644 index 0000000000..0e5ed36b8f --- /dev/null +++ b/trunk/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/trunk/sample/drb/gw_s.rb b/trunk/sample/drb/gw_s.rb new file mode 100644 index 0000000000..c2bea0baad --- /dev/null +++ b/trunk/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/trunk/sample/drb/holderc.rb b/trunk/sample/drb/holderc.rb new file mode 100644 index 0000000000..8dd72ebd11 --- /dev/null +++ b/trunk/sample/drb/holderc.rb @@ -0,0 +1,22 @@ +require 'drb/drb' + +begin + there = ARGV.shift || raise +rescue + $stderr.puts("usage: #{$0} ") + 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/trunk/sample/drb/holders.rb b/trunk/sample/drb/holders.rb new file mode 100644 index 0000000000..2d9974f3fc --- /dev/null +++ b/trunk/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/trunk/sample/drb/http0.rb b/trunk/sample/drb/http0.rb new file mode 100644 index 0000000000..7649925282 --- /dev/null +++ b/trunk/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/trunk/sample/drb/http0serv.rb b/trunk/sample/drb/http0serv.rb new file mode 100644 index 0000000000..100d126b8f --- /dev/null +++ b/trunk/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/trunk/sample/drb/name.rb b/trunk/sample/drb/name.rb new file mode 100644 index 0000000000..86b478fbec --- /dev/null +++ b/trunk/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 + | # + | # + | 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/trunk/sample/drb/namec.rb b/trunk/sample/drb/namec.rb new file mode 100644 index 0000000000..f6db6f3022 --- /dev/null +++ b/trunk/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} " + 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/trunk/sample/drb/old_tuplespace.rb b/trunk/sample/drb/old_tuplespace.rb new file mode 100644 index 0000000000..3e13b92ee1 --- /dev/null +++ b/trunk/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/trunk/sample/drb/rinda_ts.rb b/trunk/sample/drb/rinda_ts.rb new file mode 100644 index 0000000000..6f2fae5c0f --- /dev/null +++ b/trunk/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/trunk/sample/drb/rindac.rb b/trunk/sample/drb/rindac.rb new file mode 100644 index 0000000000..72be09deaf --- /dev/null +++ b/trunk/sample/drb/rindac.rb @@ -0,0 +1,17 @@ +require 'drb/drb' +require 'rinda/rinda' + +uri = ARGV.shift || raise("usage: #{$0} ") + +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/trunk/sample/drb/rindas.rb b/trunk/sample/drb/rindas.rb new file mode 100644 index 0000000000..9fd9ada2d1 --- /dev/null +++ b/trunk/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} ") + +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/trunk/sample/drb/ring_echo.rb b/trunk/sample/drb/ring_echo.rb new file mode 100644 index 0000000000..0633aa839a --- /dev/null +++ b/trunk/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/trunk/sample/drb/ring_inspect.rb b/trunk/sample/drb/ring_inspect.rb new file mode 100644 index 0000000000..c096cd7034 --- /dev/null +++ b/trunk/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/trunk/sample/drb/ring_place.rb b/trunk/sample/drb/ring_place.rb new file mode 100644 index 0000000000..0ceef7c65a --- /dev/null +++ b/trunk/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/trunk/sample/drb/simpletuple.rb b/trunk/sample/drb/simpletuple.rb new file mode 100644 index 0000000000..3ae9208c79 --- /dev/null +++ b/trunk/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/trunk/sample/drb/speedc.rb b/trunk/sample/drb/speedc.rb new file mode 100644 index 0000000000..14d526d48d --- /dev/null +++ b/trunk/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/trunk/sample/drb/speeds.rb b/trunk/sample/drb/speeds.rb new file mode 100644 index 0000000000..76b4b29dba --- /dev/null +++ b/trunk/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/trunk/sample/dualstack-fetch.rb b/trunk/sample/dualstack-fetch.rb new file mode 100644 index 0000000000..1897a3d8e9 --- /dev/null +++ b/trunk/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/trunk/sample/dualstack-httpd.rb b/trunk/sample/dualstack-httpd.rb new file mode 100644 index 0000000000..69e3181863 --- /dev/null +++ b/trunk/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/trunk/sample/eval.rb b/trunk/sample/eval.rb new file mode 100644 index 0000000000..ed4b7c3de5 --- /dev/null +++ b/trunk/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/trunk/sample/export.rb b/trunk/sample/export.rb new file mode 100644 index 0000000000..949e5b10bf --- /dev/null +++ b/trunk/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 1 ? 2 : 1 + break if rlen + delta > len + rlen += delta + res += char + end + res += ' ' * (len - rlen) if rlen < len + res + end +end + +def fromout(date, from, subj) + return 0 if !date + y, m, d = Time.parse(date).to_a.reverse[4, 3] if date + y ||= 0; m ||= 0; d ||= 0 + from ||= "sombody@somewhere" + from.delete!("\r\n") + from = from.kconv(Encoding.default_external).kjust(28) + subj ||= "(nil)" + subj.delete!("\r\n") + subj = subj.kconv(Encoding.default_external).kjust(40) + printf "%02d/%02d/%02d [%s] %s\n", y%100, m, d, from, subj + return 1 +end + +def get_mailfile(user) + file = user + unless user + file = ENV['MAIL'] + user = ENV['USER'] || ENV['USERNAME'] || ENV['LOGNAME'] + end + + if file == nil or !File.exist?(file) + [ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m| + path = "#{m}/mail/#{user}" + if File.exist?(path) + file = path + break + end + end + end + file +end + +def from_main + if ARGV[0] == '-w' + wait = true + ARGV.shift + end + file = get_mailfile(ARGV[0]) + + outcount = 0 + if File.exist?(file) + atime = File.atime(file) + mtime = File.mtime(file) + open(file, "r") do |f| + until f.eof? + header = {} + f.each_line do |line| + next if /^From / =~ line # skip From-line + break if /^$/ =~ line # end of header + + if /^(?\S+?):\s*(?.*)/ =~ line + attr.capitalize! + header[attr] = value + elsif attr + header[attr] += "\n" + line.lstrip + end + end + + f.each_line do |line| + break if /^From / =~ line + end + outcount += fromout(header['Date'], header['From'], header['Subject']) + end + end + File.utime(atime, mtime, file) + end + + if outcount == 0 + print "You have no mail.\n" + sleep 2 if wait + elsif wait + system "stty cbreak -echo" + $stdin.getc + system "stty cooked echo" + end +end + +if __FILE__ == $0 + from_main +end + +__END__ + +=begin + += from.rb + +== USAGE + +ruby from.rb [-w] [username_or_filename] + +=end diff --git a/trunk/sample/fullpath.rb b/trunk/sample/fullpath.rb new file mode 100644 index 0000000000..8472e5d8f4 --- /dev/null +++ b/trunk/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/trunk/sample/less.rb b/trunk/sample/less.rb new file mode 100644 index 0000000000..8be359108f --- /dev/null +++ b/trunk/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/trunk/sample/list.rb b/trunk/sample/list.rb new file mode 100644 index 0000000000..221f7edb16 --- /dev/null +++ b/trunk/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 = " 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/trunk/sample/mkproto.rb b/trunk/sample/mkproto.rb new file mode 100644 index 0000000000..754ca2dff2 --- /dev/null +++ b/trunk/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/trunk/sample/mpart.rb b/trunk/sample/mpart.rb new file mode 100644 index 0000000000..a88eba0ef6 --- /dev/null +++ b/trunk/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/trunk/sample/observ.rb b/trunk/sample/observ.rb new file mode 100644 index 0000000000..72e5178b38 --- /dev/null +++ b/trunk/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/trunk/sample/occur.pl b/trunk/sample/occur.pl new file mode 100644 index 0000000000..1f5fcf27a4 --- /dev/null +++ b/trunk/sample/occur.pl @@ -0,0 +1,9 @@ +while (<>) { + for (split(/\W+/)) { + $freq{$_}++; + } +} + +for (sort keys %freq) { + print "$_ -- $freq{$_}\n"; +} diff --git a/trunk/sample/occur.rb b/trunk/sample/occur.rb new file mode 100644 index 0000000000..4ec6ae479b --- /dev/null +++ b/trunk/sample/occur.rb @@ -0,0 +1,12 @@ +# word occurrence listing +# usege: ruby occur.rb file.. +freq = Hash.new(0) +while line = gets() + for word in line.split(/\W+/) + freq[word] += 1 + end +end + +for word in freq.keys.sort! + print word, " -- ", freq[word], "\n" +end diff --git a/trunk/sample/occur2.rb b/trunk/sample/occur2.rb new file mode 100644 index 0000000000..53885c0ba7 --- /dev/null +++ b/trunk/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/trunk/sample/openssl/c_rehash.rb b/trunk/sample/openssl/c_rehash.rb new file mode 100644 index 0000000000..afbb654517 --- /dev/null +++ b/trunk/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/trunk/sample/openssl/cert2text.rb b/trunk/sample/openssl/cert2text.rb new file mode 100644 index 0000000000..50da224e76 --- /dev/null +++ b/trunk/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/trunk/sample/openssl/certstore.rb b/trunk/sample/openssl/certstore.rb new file mode 100644 index 0000000000..bbc637f668 --- /dev/null +++ b/trunk/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/trunk/sample/openssl/cipher.rb b/trunk/sample/openssl/cipher.rb new file mode 100644 index 0000000000..58b10d6046 --- /dev/null +++ b/trunk/sample/openssl/cipher.rb @@ -0,0 +1,54 @@ +#!/usr/bin/env ruby +require 'openssl' + +def crypt_by_password(alg, pass, salt, text) + puts "--Setup--" + puts %(cipher alg: "#{alg}") + puts %(plain text: "#{text}") + puts %(password: "#{pass}") + puts %(salt: "#{salt}") + puts + + puts "--Encrypting--" + enc = OpenSSL::Cipher::Cipher.new(alg) + enc.encrypt + enc.pkcs5_keyivgen(pass, salt) + cipher = enc.update(text) + cipher << enc.final + puts %(encrypted text: #{cipher.inspect}) + puts + + puts "--Decrypting--" + dec = OpenSSL::Cipher::Cipher.new(alg) + dec.decrypt + dec.pkcs5_keyivgen(pass, salt) + plain = dec.update(cipher) + plain << dec.final + puts %(decrypted text: "#{plain}") + puts +end + +def ciphers + ciphers = OpenSSL::Cipher.ciphers.sort + ciphers.each{|i| + if i.upcase != i && ciphers.include?(i.upcase) + ciphers.delete(i) + end + } + return ciphers +end + +puts "Supported ciphers in #{OpenSSL::OPENSSL_VERSION}:" +ciphers.each_with_index{|name, i| + printf("%-15s", name) + puts if (i + 1) % 5 == 0 +} +puts +puts + +alg = ARGV.shift || ciphers.first +pass = "secret password" +salt = "8 octets" # or nil +text = "abcdefghijklmnopqrstuvwxyz" + +crypt_by_password(alg, pass, salt, text) diff --git a/trunk/sample/openssl/crlstore.rb b/trunk/sample/openssl/crlstore.rb new file mode 100644 index 0000000000..b305913eb0 --- /dev/null +++ b/trunk/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/trunk/sample/openssl/echo_cli.rb b/trunk/sample/openssl/echo_cli.rb new file mode 100644 index 0000000000..069a21ec94 --- /dev/null +++ b/trunk/sample/openssl/echo_cli.rb @@ -0,0 +1,44 @@ +#!/usr/bin/env ruby + +require 'socket' +require 'openssl' +require 'optparse' + +options = ARGV.getopts("p:c:k:C:") + +host = ARGV[0] || "localhost" +port = options["p"] || "2000" +cert_file = options["c"] +key_file = options["k"] +ca_path = options["C"] + +ctx = OpenSSL::SSL::SSLContext.new() +if cert_file && key_file + ctx.cert = OpenSSL::X509::Certificate.new(File::read(cert_file)) + ctx.key = OpenSSL::PKey::RSA.new(File::read(key_file)) +end +if ca_path + ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER + ctx.ca_path = ca_path +else + $stderr.puts "!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!" +end + +s = TCPSocket.new(host, port) +ssl = OpenSSL::SSL::SSLSocket.new(s, ctx) +ssl.connect # start SSL session +p ssl.peer_cert +errors = Hash.new +OpenSSL::X509.constants.grep(/^V_(ERR_|OK)/).each do |name| + errors[OpenSSL::X509.const_get(name)] = name +end +p errors[ssl.verify_result] + +ssl.sync_close = true # if true the underlying socket will be + # closed in SSLSocket#close. (default: false) +while line = $stdin.gets + ssl.write line + puts ssl.gets.inspect +end + +ssl.close diff --git a/trunk/sample/openssl/echo_svr.rb b/trunk/sample/openssl/echo_svr.rb new file mode 100644 index 0000000000..719de6be84 --- /dev/null +++ b/trunk/sample/openssl/echo_svr.rb @@ -0,0 +1,65 @@ +#!/usr/bin/env ruby + +require 'socket' +require 'openssl' +require 'optparse' + +options = ARGV.getopts("p:c:k:C:") + +port = options["p"] || "2000" +cert_file = options["c"] +key_file = options["k"] +ca_path = options["C"] + +if cert_file && key_file + cert = OpenSSL::X509::Certificate.new(File::read(cert_file)) + key = OpenSSL::PKey::RSA.new(File::read(key_file)) +else + key = OpenSSL::PKey::RSA.new(512){ print "." } + puts + cert = OpenSSL::X509::Certificate.new + cert.version = 2 + cert.serial = 0 + name = OpenSSL::X509::Name.new([["C","JP"],["O","TEST"],["CN","localhost"]]) + cert.subject = name + cert.issuer = name + cert.not_before = Time.now + cert.not_after = Time.now + 3600 + cert.public_key = key.public_key + ef = OpenSSL::X509::ExtensionFactory.new(nil,cert) + cert.extensions = [ + ef.create_extension("basicConstraints","CA:FALSE"), + ef.create_extension("subjectKeyIdentifier","hash"), + ef.create_extension("extendedKeyUsage","serverAuth"), + ef.create_extension("keyUsage", + "keyEncipherment,dataEncipherment,digitalSignature") + ] + ef.issuer_certificate = cert + cert.add_extension ef.create_extension("authorityKeyIdentifier", + "keyid:always,issuer:always") + cert.sign(key, OpenSSL::Digest::SHA1.new) +end + +ctx = OpenSSL::SSL::SSLContext.new() +ctx.key = key +ctx.cert = cert +if ca_path + ctx.verify_mode = + OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT + ctx.ca_path = ca_path +else + $stderr.puts "!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!" +end + +tcps = TCPServer.new(port) +ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx) +loop do + ns = ssls.accept + puts "connected from #{ns.peeraddr}" + while line = ns.gets + puts line.inspect + ns.write line + end + puts "connection closed" + ns.close +end diff --git a/trunk/sample/openssl/gen_csr.rb b/trunk/sample/openssl/gen_csr.rb new file mode 100644 index 0000000000..4228707fdb --- /dev/null +++ b/trunk/sample/openssl/gen_csr.rb @@ -0,0 +1,51 @@ +#!/usr/bin/env ruby + +require 'optparse' +require 'openssl' + +include OpenSSL + +def usage + myname = File::basename($0) + $stderr.puts < "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") {|lib|@library=lib} + + # optional argument + opts.on("-i", "--inplace=[EXTENSION]", + "edit ARGV files in place", # multiline description + "(make backup if EXTENSION supplied)") {|inplace| @inplace = inplace || ''} + + opts.on("-N=[NUM]", Integer) {|num|@number=num} + + # additional class + opts.on("-t", "--[no-]time[=TIME]", Time, "it's the time") {|time|@time=time} + + # limit argument syntax + opts.on("-[0-7]", "-F", "--irs=[OCTAL]", OptionParser::OctalInteger, + "specify record separator", "(\\0, if no argument)") {|irs|@irs=irs} + + # boolean switch(default true) + @exec = true + opts.on("-n", "--no-exec[=FLAG]", TrueClass, "not really execute") {|exec|@exec=exec} + + # array + opts.on("-a", "--list[=LIST,LIST]", Array, "list") {|list|@list=list} + + # fixed size array + opts.on("--pair[=car,cdr]", Array, "pair") {|x,y|@x=x; @y=y} + + # keyword completion + opts.on("--code=CODE", CODES, CODE_ALIASES, "select coding system", + "("+CODES.join(",")+",", " "+CODE_ALIASES.keys.join(",")+")") {|c|@code=c} + + # optional argument with keyword completion + opts.on("--type[=TYPE]", [:text, :binary], "select type(text, binary)") {|t|@type=t} + + # boolean switch with optional argument(default false) + opts.on("-v", "--[no-]verbose=[FLAG]", "run verbosely") {|v|@verbose=v} + + # easy way, set local variable + opts.on("-q", "--quit", "quit when ARGV is empty") {|q|@quit=q} + + # adding on the fly + opts.on("--add=SWITCH=[ARG]", "add option on the fly", /\A(\w+)(?:=.+)?\Z/) do + |opt, var| + opts.on("--#{opt}", "added in runtime", &eval("proc {|x|@#{var}=x}")) + end + + opts.on_head("specific options:") + + # no argument + opts.on_tail("--version", "show version") do + puts OptionParser::Version.join('.') + exit + end + opts.parse! +end + +pp self +begin print ARGV.options; exit end if @quit +ARGV.options = nil # no more parse +puts "ARGV = #{ARGV.join(' ')}" if !ARGV.empty? +#opts.variable.each {|sym| puts "#{sym} = #{opts.send(sym).inspect}"} diff --git a/trunk/sample/optparse/subcommand.rb b/trunk/sample/optparse/subcommand.rb new file mode 100755 index 0000000000..21c42dd60a --- /dev/null +++ b/trunk/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/trunk/sample/philos.rb b/trunk/sample/philos.rb new file mode 100644 index 0000000000..5c8f43c819 --- /dev/null +++ b/trunk/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/trunk/sample/pi.rb b/trunk/sample/pi.rb new file mode 100644 index 0000000000..63be974285 --- /dev/null +++ b/trunk/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/trunk/sample/rcs.awk b/trunk/sample/rcs.awk new file mode 100644 index 0000000000..08979285c9 --- /dev/null +++ b/trunk/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/trunk/sample/rcs.dat b/trunk/sample/rcs.dat new file mode 100644 index 0000000000..61c88bff89 --- /dev/null +++ b/trunk/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/trunk/sample/rcs.rb b/trunk/sample/rcs.rb new file mode 100644 index 0000000000..0bdf81c45d --- /dev/null +++ b/trunk/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/trunk/sample/rdoc/markup/rdoc2latex.rb b/trunk/sample/rdoc/markup/rdoc2latex.rb new file mode 100644 index 0000000000..aa8079eb90 --- /dev/null +++ b/trunk/sample/rdoc/markup/rdoc2latex.rb @@ -0,0 +1,15 @@ +#!/usr/local/bin/ruby +# Illustration of a script to convert an RDoc-style file to a LaTeX document + +require 'rdoc/markup' +require 'rdoc/markup/to_latex' + +p = RDoc::Markup.new +h = RDoc::Markup::ToLaTeX.new + +#puts "\\documentclass{report}" +#puts "\\usepackage{tabularx}" +#puts "\\usepackage{parskip}" +#puts "\\begin{document}" +puts p.convert(ARGF.read, h) +#puts "\\end{document}" diff --git a/trunk/sample/rdoc/markup/sample.rb b/trunk/sample/rdoc/markup/sample.rb new file mode 100644 index 0000000000..db5d88d150 --- /dev/null +++ b/trunk/sample/rdoc/markup/sample.rb @@ -0,0 +1,40 @@ +# This program illustrates the basic use of the SimpleMarkup +# class. It extracts the first comment block from the +# simple_markup.rb file and converts it into HTML on +# standard output. Run it using +# +# % ruby sample.rb +# +# You should be in the sample/rdoc/markup/ directory when you do this, +# as it hardwires the path to the files it needs to require. +# This isn't necessary in the code you write once you've +# installed the package. +# +# For a better way of formatting code comment blocks (and more) +# see the rdoc package. +# + +require 'rdoc/markup/simple_markup' +require 'rdoc/markup/simple_markup/to_html' + +# Extract the comment block from the source file + +input_string = "" + +File.foreach("../../../lib/rdoc/markup/simple_markup.rb") do |line| + break unless line.gsub!(/^\# ?/, '') + input_string << line +end + +# Create a markup object +markup = SM::SimpleMarkup.new + +# Attach it to an HTML formatter +h = SM::ToHtml.new + +# And convert out comment block to html. Wrap it a body +# tag pair to let browsers view it + +puts "" +puts markup.convert(input_string, h) +puts "" diff --git a/trunk/sample/ripper/ruby2html.rb b/trunk/sample/ripper/ruby2html.rb new file mode 100644 index 0000000000..8f64f5a713 --- /dev/null +++ b/trunk/sample/ripper/ruby2html.rb @@ -0,0 +1,112 @@ +#!/usr/bin/env ruby +# $originalId: ruby2html.rb,v 1.2 2005/09/23 22:53:47 aamine Exp $ + +TEMPLATE_LINE = __LINE__ + 2 +TEMPLATE = <<-EndTemplate + + + + +<% if css %> + +<% end %> + <%= File.basename(f.path) %> + + +
+<%
+    if print_line_number
+      Ruby2HTML.compile(f).each_with_index do |line, idx|
+%><%= sprintf('%4d  %s', idx+1, line) %><%
+      end
+    else
+%><%= Ruby2HTML.compile(f) %><%
+    end
+%>
+
+ + +EndTemplate + +require 'ripper' +require 'stringio' +require 'cgi' +require 'erb' +require 'optparse' + +def main + encoding = 'us-ascii' + css = nil + print_line_number = false + parser = OptionParser.new + parser.banner = "Usage: #{File.basename($0)} [-l] [...]" + parser.on('--encoding=NAME', 'Character encoding [us-ascii].') {|name| + encoding = name + } + parser.on('--css=URL', 'Set a link to CSS.') {|url| + css = url + } + parser.on('-l', '--line-number', 'Show line number.') { + print_line_number = true + } + parser.on('--help', 'Prints this message and quit.') { + puts parser.help + exit 0 + } + begin + parser.parse! + rescue OptionParser::ParseError => err + $stderr.puts err + $stderr.puts parser.help + exit 1 + end + puts ruby2html(ARGF, encoding, css, print_line_number) +end + +class ERB + attr_accessor :lineno + + remove_method :result + def result(b) + eval(@src, b, (@filename || '(erb)'), (@lineno || 1)) + end +end + +def ruby2html(f, encoding, css, print_line_number) + erb = ERB.new(TEMPLATE, nil, '>') + erb.filename = __FILE__ + erb.lineno = TEMPLATE_LINE + erb.result(binding()) +end + +class Ruby2HTML < Ripper::Filter + def Ruby2HTML.compile(f) + buf = StringIO.new + Ruby2HTML.new(f).parse(buf) + buf.string + end + + def on_default(event, tok, f) + f << CGI.escapeHTML(tok) + end + + def on_kw(tok, f) + f << %Q[#{CGI.escapeHTML(tok)}] + end + + def on_comment(tok, f) + f << %Q[#{CGI.escapeHTML(tok.rstrip)}\n] + end + + def on_tstring_beg(tok, f) + f << %Q[#{CGI.escapeHTML(tok)}] + end + + def on_tstring_end(tok, f) + f << %Q[#{CGI.escapeHTML(tok)}] + end +end + +if $0 == __FILE__ + main +end diff --git a/trunk/sample/ripper/strip-comment.rb b/trunk/sample/ripper/strip-comment.rb new file mode 100644 index 0000000000..bd26b6a377 --- /dev/null +++ b/trunk/sample/ripper/strip-comment.rb @@ -0,0 +1,19 @@ +# $Id$ + +require 'ripper/filter' + +class CommentStripper < Ripper::Filter + def CommentStripper.strip(src) + new(src).parse(nil) + end + + def on_default(event, token, data) + print token + end + + def on_comment(token, data) + puts + end +end + +CommentStripper.strip(ARGF) diff --git a/trunk/sample/rss/blend.rb b/trunk/sample/rss/blend.rb new file mode 100755 index 0000000000..351f6f373f --- /dev/null +++ b/trunk/sample/rss/blend.rb @@ -0,0 +1,79 @@ +#!/usr/bin/env ruby + +require "rss" + +feeds = [] +verbose = false +encoding = "UTF-8" + +def error(exception) + mark = "=" * 20 + mark = "#{mark} error #{mark}" + STDERR.puts mark + STDERR.puts exception.class + STDERR.puts exception.message + STDERR.puts exception.backtrace + STDERR.puts mark +end + +before_time = Time.now +ARGV.each do |fname| + if fname == '-v' + verbose = true + next + end + rss = nil + f = File.new(fname).read + begin + ## do validate parse + rss = RSS::Parser.parse(f) + rescue RSS::InvalidRSSError + error($!) if verbose + ## do non validate parse for invalid RSS 1.0 + begin + rss = RSS::Parser.parse(f, false) + rescue RSS::Error + ## invalid RSS. + error($!) if verbose + end + rescue RSS::Error + error($!) if verbose + end + if rss.nil? + STDERR.puts "#{fname} does not include RSS 1.0 or 0.9x/2.0" + else + begin + rss.output_encoding = encoding + rescue RSS::UnknownConversionMethodError + error($!) if verbose + end + feeds << rss + end +end +processing_time = Time.now - before_time + +rss = RSS::Maker.make("1.0") do |maker| + maker.encoding = encoding + maker.channel.about = "http://example.com/blend.rdf" + maker.channel.title = "blended feeds" + maker.channel.link = "http://example.com/" + maker.channel.description = "blended feeds generated by RSS Parser" + + feeds.each do |feed| + feed.items.each do |item| + item.setup_maker(maker.items) + end + end + + maker.items.each do |item| + item.title ||= "UNKNOWN" + item.link ||= "UNKNOWN" + end + + maker.items.do_sort = true + maker.items.max_size = 15 +end +puts rss + +STDERR.puts "Used XML parser: #{RSS::Parser.default_parser}" +STDERR.puts "Processing time: #{processing_time}s" diff --git a/trunk/sample/rss/convert.rb b/trunk/sample/rss/convert.rb new file mode 100755 index 0000000000..e6bff4c623 --- /dev/null +++ b/trunk/sample/rss/convert.rb @@ -0,0 +1,69 @@ +#!/usr/bin/env ruby + +require "rss" + +feeds = [] +verbose = false +encoding = "UTF-8" +to_version = "1.0" + +def error(exception) + mark = "=" * 20 + mark = "#{mark} error #{mark}" + STDERR.puts mark + STDERR.puts exception.class + STDERR.puts exception.message + STDERR.puts exception.backtrace + STDERR.puts mark +end + +before_time = Time.now +ARGV.each do |fname| + case fname + when '-v' + verbose = true + next + when /^-t(0\.91|1\.0|2\.0|atom)$/ + to_version = $1 + next + end + rss = nil + f = File.read(fname) + begin + ## do validate parse + rss = RSS::Parser.parse(f) + rescue RSS::InvalidRSSError + error($!) if verbose + ## do non validate parse for invalid RSS 1.0 + begin + rss = RSS::Parser.parse(f, false) + rescue RSS::Error + ## invalid RSS. + error($!) if verbose + end + rescue RSS::Error + error($!) if verbose + end + if rss.nil? + STDERR.puts "#{fname} does not include RSS 1.0 or 0.9x/2.0" + else + begin + rss.output_encoding = encoding + rescue RSS::UnknownConversionMethodError + error($!) if verbose + end + feeds << [fname, rss] + end +end +processing_time = Time.now - before_time + +feeds.each do |fname, rss| + converted_rss = rss.to_xml(to_version) + output_name = fname.sub(/(\.[^\.]+)$/, "-#{to_version}\\1") + File.open(output_name, "w") do |output| + output.print(converted_rss) + end +end + +STDERR.puts "Used XML parser: #{RSS::Parser.default_parser}" +STDERR.puts "Processing time: #{processing_time}s" diff --git a/trunk/sample/rss/list_description.rb b/trunk/sample/rss/list_description.rb new file mode 100755 index 0000000000..d4b98a9ac6 --- /dev/null +++ b/trunk/sample/rss/list_description.rb @@ -0,0 +1,91 @@ +#!/usr/bin/env ruby + +require "nkf" +class String + # From tdiary.rb + def shorten( len = 120 ) + lines = NKF::nkf( "-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 = rss.to_rss("1.0") do |maker| + maker.channel.about ||= maker.channel.link + maker.channel.description ||= "No description" + maker.items.each do |item| + item.title ||= "No title" + item.link ||= "UNKNOWN" + end + end + next if rss.nil? + + rss.items.each do |item| + channels[rss.channel.title] ||= [] + channels[rss.channel.title] << item if item.description + end + end +end +processing_time = Time.now - before_time + +channels.sort do |x, y| + x[0] <=> y[0] +end[0..20].each do |title, items| + puts "Channel: #{title}" unless items.empty? + items.sort do |x, y| + x.title <=> y.title + end[0..10].each do |item| + puts " Item: #{item.title.shorten(50)}" + puts " Description: #{item.description.shorten(50)}" + end +end + +puts "Used XML parser: #{RSS::Parser.default_parser}" +puts "Processing time: #{processing_time}s" diff --git a/trunk/sample/rss/re_read.rb b/trunk/sample/rss/re_read.rb new file mode 100755 index 0000000000..ee54a18a88 --- /dev/null +++ b/trunk/sample/rss/re_read.rb @@ -0,0 +1,64 @@ +#!/usr/bin/env ruby + +require "rss" + +def error(exception) + mark = "=" * 20 + mark = "#{mark} error #{mark}" + puts mark + puts exception.class + puts exception.message + puts exception.backtrace + puts mark +end + +verbose = false +before_time = Time.now + +ARGV.each do |fname| + if fname == '-v' + verbose = true + next + end + source = nil + File.open(fname) do |f| + source = f.read + end + + rss = nil + read = false + begin + rss = RSS::Parser.parse(source) + puts "Re-read valid feed: #{fname}" + RSS::Parser.parse(rss.to_s) + read = true + rescue RSS::InvalidRSSError + error($!) if verbose + ## do non validate parse for invalid feed + begin + rss = RSS::Parser.parse(source, false) + rescue RSS::Error + ## invalid feed + error($!) if verbose + end + rescue RSS::Error + error($!) if verbose + end + + if rss.nil? + puts "Invalid feed: #{fname}" + elsif !read + puts "Re-read invalid feed: #{fname}" + begin + RSS::Parser.parse(rss.to_s) + rescue RSS::Error + puts " Error occurred: #{fname}" + error($!) if verbose + end + end +end + +processing_time = Time.now - before_time + +puts "Used XML parser: #{RSS::Parser.default_parser}" +puts "Processing time: #{processing_time}s" diff --git a/trunk/sample/rss/rss_recent.rb b/trunk/sample/rss/rss_recent.rb new file mode 100755 index 0000000000..38b57c37fa --- /dev/null +++ b/trunk/sample/rss/rss_recent.rb @@ -0,0 +1,85 @@ +#!/usr/bin/env ruby + +require "nkf" +class String + # From tdiary.rb + def shorten( len = 120 ) + lines = NKF::nkf( "-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 = rss.to_rss("1.0") do |maker| + maker.channel.about ||= maker.channel.link + maker.channel.description ||= "No description" + maker.items.each do |item| + item.title ||= "UNKNOWN" + item.link ||= "UNKNOWN" + end + end + next if rss.nil? + + rss.items.each do |item| + items << [rss.channel, item] if item.dc_date + end + end +end +processing_time = Time.now - before_time + +items.sort do |x, y| + y[1].dc_date <=> x[1].dc_date +end[0..20].each do |channel, item| + puts "#{item.dc_date.localtime.iso8601}: " << + "#{channel.title}: #{item.title}" + puts " Description: #{item.description.shorten(50)}" if item.description +end + +puts "Used XML parser: #{RSS::Parser.default_parser}" +puts "Processing time: #{processing_time}s" diff --git a/trunk/sample/sieve.rb b/trunk/sample/sieve.rb new file mode 100644 index 0000000000..e0bb21d640 --- /dev/null +++ b/trunk/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/trunk/sample/svr.rb b/trunk/sample/svr.rb new file mode 100644 index 0000000000..11cfc5fbfe --- /dev/null +++ b/trunk/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/trunk/sample/test.rb b/trunk/sample/test.rb new file mode 100644 index 0000000000..3f24bd071a --- /dev/null +++ b/trunk/sample/test.rb @@ -0,0 +1,2232 @@ +#! /usr/bin/env ruby + +$testnum=0 +$ntest=0 +$failed = 0 + +def test_check(what) + STDERR.print "\nsample/test.rb:#{what} " + $what = what + $testnum = 0 +end + +def test_ok(cond,n=1) + $testnum+=1 + $ntest+=1 + where = (st = caller(n)) ? st[0] : "caller error! (n=#{n}, trace=#{caller(0).join(', ')}" + if cond + STDERR.print "." + printf "ok %d (%s)\n", $testnum, where + else + STDERR.print "F" + printf "not ok %s %d -- %s\n", $what, $testnum, where + $failed+=1 + end + STDOUT.flush + STDERR.flush +end + +# make sure conditional operators work + +test_check "assignment" + +a=[]; a[0] ||= "bar"; +test_ok(a[0] == "bar") +h={}; h["foo"] ||= "bar"; +test_ok(h["foo"] == "bar") + +aa = 5 +aa ||= 25 +test_ok(aa == 5) +bb ||= 25 +test_ok(bb == 25) +cc &&=33 +test_ok(cc == nil) +cc = 5 +cc &&=44 +test_ok(cc == 44) + +a = nil; test_ok(a == nil) +a = 1; test_ok(a == 1) +a = []; test_ok(a == []) +a = [1]; test_ok(a == [1]) +a = [nil]; test_ok(a == [nil]) +a = [[]]; test_ok(a == [[]]) +a = [1,2]; test_ok(a == [1,2]) +a = [*[]]; test_ok(a == []) +a = [*[1]]; test_ok(a == [1]) +a = [*[1,2]]; test_ok(a == [1,2]) + +a = *[]; test_ok(a == []) +a = *[1]; test_ok(a == [1]) +a = *[nil]; test_ok(a == [nil]) +a = *[[]]; test_ok(a == [[]]) +a = *[1,2]; test_ok(a == [1,2]) +a = *[*[]]; test_ok(a == []) +a = *[*[1]]; test_ok(a == [1]) +a = *[*[1,2]]; test_ok(a == [1,2]) + +a, = nil; test_ok(a == nil) +a, = 1; test_ok(a == 1) +a, = []; test_ok(a == nil) +a, = [1]; test_ok(a == 1) +a, = [nil]; test_ok(a == nil) +a, = [[]]; test_ok(a == []) +a, = 1,2; test_ok(a == 1) +a, = [1,2]; test_ok(a == 1) +a, = [*[]]; test_ok(a == nil) +a, = [*[1]]; test_ok(a == 1) +a, = *[1,2]; test_ok(a == 1) +a, = [*[1,2]]; test_ok(a == 1) + +a, = *[]; test_ok(a == nil) +a, = *[1]; test_ok(a == 1) +a, = *[nil]; test_ok(a == nil) +a, = *[[]]; test_ok(a == []) +a, = *[1,2]; test_ok(a == 1) +a, = *[*[]]; test_ok(a == nil) +a, = *[*[1]]; test_ok(a == 1) +a, = *[*[1,2]]; test_ok(a == 1) + +*a = nil; test_ok(a == [nil]) +*a = 1; test_ok(a == [1]) +*a = []; test_ok(a == []) +*a = [1]; test_ok(a == [1]) +*a = [nil]; test_ok(a == [nil]) +*a = [[]]; test_ok(a == [[]]) +*a = [1,2]; test_ok(a == [1,2]) +*a = [*[]]; test_ok(a == []) +*a = [*[1]]; test_ok(a == [1]) +*a = [*[1,2]]; test_ok(a == [1,2]) + +*a = *[]; test_ok(a == []) +*a = *[1]; test_ok(a == [1]) +*a = *[nil]; test_ok(a == [nil]) +*a = *[[]]; test_ok(a == [[]]) +*a = *[1,2]; test_ok(a == [1,2]) +*a = *[*[]]; test_ok(a == []) +*a = *[*[1]]; test_ok(a == [1]) +*a = *[*[1,2]]; test_ok(a == [1,2]) + +a,b,*c = nil; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = 1; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = []; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = [1]; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = [nil]; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = [[]]; test_ok([a,b,c] == [[],nil,[]]) +a,b,*c = [1,2]; test_ok([a,b,c] == [1,2,[]]) +a,b,*c = [*[]]; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = [*[1]]; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = [*[1,2]]; test_ok([a,b,c] == [1,2,[]]) + +a,b,*c = *[]; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = *[1]; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = *[nil]; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = *[[]]; test_ok([a,b,c] == [[],nil,[]]) +a,b,*c = *[1,2]; test_ok([a,b,c] == [1,2,[]]) +a,b,*c = *[*[]]; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = *[*[1]]; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = *[*[1,2]]; test_ok([a,b,c] == [1,2,[]]) + +def f; yield nil; end; f {|a| test_ok(a == nil)} +def f; yield 1; end; f {|a| test_ok(a == 1)} +def f; yield []; end; f {|a| test_ok(a == [])} +def f; yield [1]; end; f {|a| test_ok(a == [1])} +def f; yield [nil]; end; f {|a| test_ok(a == [nil])} +def f; yield [[]]; end; f {|a| test_ok(a == [[]])} +def f; yield [*[]]; end; f {|a| test_ok(a == [])} +def f; yield [*[1]]; end; f {|a| test_ok(a == [1])} +def f; yield [*[1,2]]; end; f {|a| test_ok(a == [1,2])} +def f; yield *[]; end; f {|a| test_ok(a == nil)} +def f; yield *[1]; end; f {|a| test_ok(a == 1)} +def f; yield *[nil]; end; f {|a| test_ok(a == nil)} +def f; yield *[[]]; end; f {|a| test_ok(a == [])} +def f; yield *[*[]]; end; f {|a| test_ok(a == nil)} +def f; yield *[*[1]]; end; f {|a| test_ok(a == 1)} +def f; yield *[*[1,2]]; end; f {|a| test_ok(a == 1)} + +def f; yield; end; f {|a,| test_ok(a == nil)} +def f; yield nil; end; f {|a,| test_ok(a == nil)} +def f; yield 1; end; f {|a,| test_ok(a == 1)} +def f; yield []; end; f {|a,| test_ok(a == nil)} +def f; yield [1]; end; f {|a,| test_ok(a == 1)} +def f; yield [nil]; end; f {|a,| test_ok(a == nil)} +def f; yield [[]]; end; f {|a,| test_ok(a == [])} +def f; yield [*[]]; end; f {|a,| test_ok(a == nil)} +def f; yield [*[1]]; end; f {|a,| test_ok(a == 1)} +def f; yield [*[1,2]]; end; f {|a,| test_ok(a == 1)} + +def f; yield *[]; end; f {|a,| test_ok(a == nil)} +def f; yield *[1]; end; f {|a,| test_ok(a == 1)} +def f; yield *[nil]; end; f {|a,| test_ok(a == nil)} +def f; yield *[[]]; end; f {|a,| test_ok(a == nil)} +def f; yield *[*[]]; end; f {|a,| test_ok(a == nil)} +def f; yield *[*[1]]; end; f {|a,| test_ok(a == 1)} +def f; yield *[*[1,2]]; end; f {|a,| test_ok(a == 1)} + +def f; yield; end; f {|*a| test_ok(a == [])} +def f; yield nil; end; f {|*a| test_ok(a == [nil])} +def f; yield 1; end; f {|*a| test_ok(a == [1])} +def f; yield []; end; f {|*a| test_ok(a == [[]])} +def f; yield [1]; end; f {|*a| test_ok(a == [[1]])} +def f; yield [nil]; end; f {|*a| test_ok(a == [[nil]])} +def f; yield [[]]; end; f {|*a| test_ok(a == [[[]]])} +def f; yield [1,2]; end; f {|*a| test_ok(a == [[1,2]])} +def f; yield [*[]]; end; f {|*a| test_ok(a == [[]])} +def f; yield [*[1]]; end; f {|*a| test_ok(a == [[1]])} +def f; yield [*[1,2]]; end; f {|*a| test_ok(a == [[1,2]])} + +def f; yield *[]; end; f {|*a| test_ok(a == [])} +def f; yield *[1]; end; f {|*a| test_ok(a == [1])} +def f; yield *[nil]; end; f {|*a| test_ok(a == [nil])} +def f; yield *[[]]; end; f {|*a| test_ok(a == [[]])} +def f; yield *[*[]]; end; f {|*a| test_ok(a == [])} +def f; yield *[*[1]]; end; f {|*a| test_ok(a == [1])} +def f; yield *[*[1,2]]; end; f {|*a| test_ok(a == [1,2])} + +def f; yield; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield nil; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield 1; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])} +def f; yield []; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield [1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])} +def f; yield [nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield [[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])} +def f; yield [*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield [*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])} +def f; yield [*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])} + +def f; yield *[]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield *[1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])} +def f; yield *[nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield *[[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield *[*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])} +def f; yield *[*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])} +def f; yield *[*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])} + +def r; return; end; a = r(); test_ok(a == nil) +def r; return nil; end; a = r(); test_ok(a == nil) +def r; return 1; end; a = r(); test_ok(a == 1) +def r; return []; end; a = r(); test_ok(a == []) +def r; return [1]; end; a = r(); test_ok(a == [1]) +def r; return [nil]; end; a = r(); test_ok(a == [nil]) +def r; return [[]]; end; a = r(); test_ok(a == [[]]) +def r; return [*[]]; end; a = r(); test_ok(a == []) +def r; return [*[1]]; end; a = r(); test_ok(a == [1]) +def r; return [*[1,2]]; end; a = r(); test_ok(a == [1,2]) + +def r; return *[]; end; a = r(); test_ok(a == []) +def r; return *[1]; end; a = r(); test_ok(a == [1]) +def r; return *[nil]; end; a = r(); test_ok(a == [nil]) +def r; return *[[]]; end; a = r(); test_ok(a == [[]]) +def r; return *[*[]]; end; a = r(); test_ok(a == []) +def r; return *[*[1]]; end; a = r(); test_ok(a == [1]) +def r; return *[*[1,2]]; end; a = r(); test_ok(a == [1,2]) + +def r; return *[[]]; end; a = *r(); test_ok(a == [[]]) +def r; return *[*[1,2]]; end; a = *r(); test_ok(a == [1,2]) + +def r; return; end; *a = r(); test_ok(a == [nil]) +def r; return nil; end; *a = r(); test_ok(a == [nil]) +def r; return 1; end; *a = r(); test_ok(a == [1]) +def r; return []; end; *a = r(); test_ok(a == []) +def r; return [1]; end; *a = r(); test_ok(a == [1]) +def r; return [nil]; end; *a = r(); test_ok(a == [nil]) +def r; return [[]]; end; *a = r(); test_ok(a == [[]]) +def r; return [1,2]; end; *a = r(); test_ok(a == [1,2]) +def r; return [*[]]; end; *a = r(); test_ok(a == []) +def r; return [*[1]]; end; *a = r(); test_ok(a == [1]) +def r; return [*[1,2]]; end; *a = r(); test_ok(a == [1,2]) + +def r; return *[]; end; *a = r(); test_ok(a == []) +def r; return *[1]; end; *a = r(); test_ok(a == [1]) +def r; return *[nil]; end; *a = r(); test_ok(a == [nil]) +def r; return *[[]]; end; *a = r(); test_ok(a == [[]]) +def r; return *[1,2]; end; *a = r(); test_ok(a == [1,2]) +def r; return *[*[]]; end; *a = r(); test_ok(a == []) +def r; return *[*[1]]; end; *a = r(); test_ok(a == [1]) +def r; return *[*[1,2]]; end; *a = r(); test_ok(a == [1,2]) + +def r; return *[[]]; end; *a = *r(); test_ok(a == [[]]) +def r; return *[1,2]; end; *a = *r(); test_ok(a == [1,2]) +def r; return *[*[1,2]]; end; *a = *r(); test_ok(a == [1,2]) + +def r; return; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]]) +def r; return nil; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]]) +def r; return 1; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]]) +def r; return []; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]]) +def r; return [1]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]]) +def r; return [nil]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]]) +def r; return [[]]; end; a,b,*c = r(); test_ok([a,b,c] == [[],nil,[]]) +def r; return [1,2]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]]) +def r; return [*[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]]) +def r; return [*[1]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]]) +def r; return [*[1,2]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]]) + +def r; return *[]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]]) +def r; return *[1]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]]) +def r; return *[nil]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]]) +def r; return *[[]]; end; a,b,*c = r(); test_ok([a,b,c] == [[],nil,[]]) +def r; return *[1,2]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]]) +def r; return *[*[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]]) +def r; return *[*[1]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]]) +def r; return *[*[1,2]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]]) + +f = lambda {|r,| test_ok([] == r)} +f.call([], *[]) + +f = lambda {|r,*l| test_ok([] == r); test_ok([1] == l)} +f.call([], *[1]) + +f = lambda{|x| x} +test_ok(f.call(42) == 42) +test_ok(f.call([42]) == [42]) +test_ok(f.call([[42]]) == [[42]]) +test_ok(f.call([42,55]) == [42,55]) + +f = lambda{|x,| x} +test_ok(f.call(42) == 42) +test_ok(f.call([42]) == [42]) +test_ok(f.call([[42]]) == [[42]]) +test_ok(f.call([42,55]) == [42,55]) + +f = lambda{|*x| x} +test_ok(f.call(42) == [42]) +test_ok(f.call([42]) == [[42]]) +test_ok(f.call([[42]]) == [[[42]]]) +test_ok(f.call([42,55]) == [[42,55]]) +test_ok(f.call(42,55) == [42,55]) + +a,=*[1] +test_ok(a == 1) +a,=*[[1]] +test_ok(a == [1]) +a,=*[[[1]]] +test_ok(a == [[1]]) + +x, (y, z) = 1, 2, 3 +test_ok([1,2,nil] == [x,y,z]) +x, (y, z) = 1, [2,3] +test_ok([1,2,3] == [x,y,z]) +x, (y, z) = 1, [2] +test_ok([1,2,nil] == [x,y,z]) + +a = loop do break; end; test_ok(a == nil) +a = loop do break nil; end; test_ok(a == nil) +a = loop do break 1; end; test_ok(a == 1) +a = loop do break []; end; test_ok(a == []) +a = loop do break [1]; end; test_ok(a == [1]) +a = loop do break [nil]; end; test_ok(a == [nil]) +a = loop do break [[]]; end; test_ok(a == [[]]) +a = loop do break [*[]]; end; test_ok(a == []) +a = loop do break [*[1]]; end; test_ok(a == [1]) +a = loop do break [*[1,2]]; end; test_ok(a == [1,2]) + +a = loop do break *[]; end; test_ok(a == []) +a = loop do break *[1]; end; test_ok(a == [1]) +a = loop do break *[nil]; end; test_ok(a == [nil]) +a = loop do break *[[]]; end; test_ok(a == [[]]) +a = loop do break *[*[]]; end; test_ok(a == []) +a = loop do break *[*[1]]; end; test_ok(a == [1]) +a = loop do break *[*[1,2]]; end; test_ok(a == [1,2]) + +*a = loop do break; end; test_ok(a == [nil]) +*a = loop do break nil; end; test_ok(a == [nil]) +*a = loop do break 1; end; test_ok(a == [1]) +*a = loop do break []; end; test_ok(a == []) +*a = loop do break [1]; end; test_ok(a == [1]) +*a = loop do break [nil]; end; test_ok(a == [nil]) +*a = loop do break [[]]; end; test_ok(a == [[]]) +*a = loop do break [1,2]; end; test_ok(a == [1,2]) +*a = loop do break [*[]]; end; test_ok(a == []) +*a = loop do break [*[1]]; end; test_ok(a == [1]) +*a = loop do break [*[1,2]]; end; test_ok(a == [1,2]) + +*a = loop do break *[]; end; test_ok(a == []) +*a = loop do break *[1]; end; test_ok(a == [1]) +*a = loop do break *[nil]; end; test_ok(a == [nil]) +*a = loop do break *[[]]; end; test_ok(a == [[]]) +*a = loop do break *[1,2]; end; test_ok(a == [1,2]) +*a = loop do break *[*[]]; end; test_ok(a == []) +*a = loop do break *[*[1]]; end; test_ok(a == [1]) +*a = loop do break *[*[1,2]]; end; test_ok(a == [1,2]) + +*a = *loop do break *[[]]; end; test_ok(a == [[]]) +*a = *loop do break *[1,2]; end; test_ok(a == [1,2]) +*a = *loop do break *[*[1,2]]; end; test_ok(a == [1,2]) + +a,b,*c = loop do break; end; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = loop do break nil; end; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = loop do break 1; end; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = loop do break []; end; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = loop do break [1]; end; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = loop do break [nil]; end; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = loop do break [[]]; end; test_ok([a,b,c] == [[],nil,[]]) +a,b,*c = loop do break [1,2]; end; test_ok([a,b,c] == [1,2,[]]) +a,b,*c = loop do break [*[]]; end; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = loop do break [*[1]]; end; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = loop do break [*[1,2]]; end; test_ok([a,b,c] == [1,2,[]]) + +a,b,*c = loop do break *[]; end; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = loop do break *[1]; end; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = loop do break *[nil]; end; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = loop do break *[[]]; end; test_ok([a,b,c] == [[],nil,[]]) +a,b,*c = loop do break *[1,2]; end; test_ok([a,b,c] == [1,2,[]]) +a,b,*c = loop do break *[*[]]; end; test_ok([a,b,c] == [nil,nil,[]]) +a,b,*c = loop do break *[*[1]]; end; test_ok([a,b,c] == [1,nil,[]]) +a,b,*c = loop do break *[*[1,2]]; end; test_ok([a,b,c] == [1,2,[]]) + +def r(val); a = yield(); test_ok(a == val, 2); end +r(nil){next} +r(nil){next nil} +r(1){next 1} +r([]){next []} +r([1]){next [1]} +r([nil]){next [nil]} +r([[]]){next [[]]} +r([]){next [*[]]} +r([1]){next [*[1]]} +r([1,2]){next [*[1,2]]} + +r([]){next *[]} +r([1]){next *[1]} +r([nil]){next *[nil]} +r([[]]){next *[[]]} +r([]){next *[*[]]} +r([1]){next *[*[1]]} +r([1,2]){next *[*[1,2]]} + +def r(val); *a = yield(); test_ok(a == val, 2); end +r([nil]){next} +r([nil]){next nil} +r([1]){next 1} +r([]){next []} +r([1]){next [1]} +r([nil]){next [nil]} +r([[]]){next [[]]} +r([1,2]){next [1,2]} +r([]){next [*[]]} +r([1]){next [*[1]]} +r([1,2]){next [*[1,2]]} + +def r(val); *a = *yield(); test_ok(a == val, 2); end +r([[]]){next *[[]]} +r([1,2]){next *[1,2]} +r([1,2]){next *[*[1,2]]} + +def r(val); a,b,*c = yield(); test_ok([a,b,c] == val, 2); end +r([nil,nil,[]]){next} +r([nil,nil,[]]){next nil} +r([1,nil,[]]){next 1} +r([nil,nil,[]]){next []} +r([1,nil,[]]){next [1]} +r([nil,nil,[]]){next [nil]} +r([[],nil,[]]){next [[]]} +r([1,2,[]]){next [1,2]} +r([nil,nil,[]]){next [*[]]} +r([1,nil,[]]){next [*[1]]} +r([1,2,[]]){next [*[1,2]]} + +def r(val); a,b,*c = *yield(); test_ok([a,b,c] == val, 2); end +r([[],nil,[]]){next *[[]]} +r([1,2,[]]){next *[1,2]} +r([1,2,[]]){next *[*[1,2]]} + +test_check "condition" + +$x = '0'; + +$x == $x && test_ok(true) +$x != $x && test_ok(false) +$x == $x || test_ok(false) +$x != $x || test_ok(true) + +# first test to see if we can run the tests. + +test_check "if/unless"; + +$x = 'test'; +test_ok(if $x == $x then true else false end) +$bad = false +unless $x == $x + $bad = true +end +test_ok(!$bad) +test_ok(unless $x != $x then true else false end) + +test_check "case" + +case 5 +when 1, 2, 3, 4, 6, 7, 8 + test_ok(false) +when 5 + test_ok(true) +end + +case 5 +when 5 + test_ok(true) +when 1..10 + test_ok(false) +end + +case 5 +when 1..10 + test_ok(true) +else + test_ok(false) +end + +case 5 +when 5 + test_ok(true) +else + test_ok(false) +end + +case "foobar" +when /^f.*r$/ + test_ok(true) +else + test_ok(false) +end + +test_check "while/until"; + +tmp = open("while_tmp", "w") +tmp.print "tvi925\n"; +tmp.print "tvi920\n"; +tmp.print "vt100\n"; +tmp.print "Amiga\n"; +tmp.print "paper\n"; +tmp.close + +# test break + +tmp = open("while_tmp", "r") +test_ok(tmp.kind_of?(File)) + +while line = tmp.gets() + break if /vt100/ =~ line +end + +test_ok(!tmp.eof? && /vt100/ =~ line) +tmp.close + +# test next +$bad = false +tmp = open("while_tmp", "r") +while line = tmp.gets() + next if /vt100/ =~ line + $bad = 1 if /vt100/ =~ line +end +test_ok(!(!tmp.eof? || /vt100/ =~ line || $bad)) +tmp.close + +# test redo +$bad = false +tmp = open("while_tmp", "r") +while line = tmp.gets() + lastline = line + line = line.gsub(/vt100/, 'VT100') + if lastline != line + line.gsub!('VT100', 'Vt100') + redo + end + $bad = 1 if /vt100/ =~ line + $bad = 1 if /VT100/ =~ line +end +test_ok(tmp.eof? && !$bad) +tmp.close + +sum=0 +for i in 1..10 + sum += i + i -= 1 + if i > 0 + redo + end +end +test_ok(sum == 220) + +# test interval +$bad = false +tmp = open("while_tmp", "r") +while line = tmp.gets() + break if 3 + case line + when /vt100/, /Amiga/, /paper/ + $bad = true + end +end +test_ok(!$bad) +tmp.close + +File.unlink "while_tmp" or `/bin/rm -f "while_tmp"` +test_ok(!File.exist?("while_tmp")) + +i = 0 +until i>4 + i+=1 +end +test_ok(i>4) + + +# exception handling +test_check "exception"; + +begin + raise "this must be handled" + test_ok(false) +rescue + test_ok(true) +end + +$bad = true +begin + raise "this must be handled no.2" +rescue + if $bad + $bad = false + retry + test_ok(false) + end +end +test_ok(true) + +# exception in rescue clause +$string = "this must be handled no.3" +begin + begin + raise "exception in rescue clause" + rescue + raise $string + end + test_ok(false) +rescue + 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} + +test_ok($x[1] == 2) + +test_ok(begin + for k,v in $x + raise if k*2 != v + end + true + rescue + false + end) + +test_ok($x.length == 3) +test_ok($x.has_key?(1)) +test_ok($x.has_value?(4)) +test_ok($x.values_at(2,3) == [4,6]) +test_ok($x == {1=>2, 2=>4, 3=>6}) + +$z = $x.keys.sort.join(":") +test_ok($z == "1:2:3") + +$z = $x.values.sort.join(":") +test_ok($z == "2:4:6") +test_ok($x == $x) + +$x.shift +test_ok($x.length == 2) + +$z = [1,2] +$x[$z] = 256 +test_ok($x[$z] == 256) + +$x = Hash.new(0) +$x[1] = 1 +test_ok($x[1] == 1) +test_ok($x[2] == 0) + +$x = Hash.new([]) +test_ok($x[22] == []) +test_ok($x[22].equal?($x[22])) + +$x = Hash.new{[]} +test_ok($x[22] == []) +test_ok(!$x[22].equal?($x[22])) + +$x = Hash.new{|h,k| $z = k; h[k] = k*2} +$z = 0 +test_ok($x[22] == 44) +test_ok($z == 22) +$z = 0 +test_ok($x[22] == 44) +test_ok($z == 0) +$x.default = 5 +test_ok($x[23] == 5) + +$x = Hash.new +def $x.default(k) + $z = k + self[k] = k*2 +end +$z = 0 +test_ok($x[22] == 44) +test_ok($z == 22) +$z = 0 +test_ok($x[22] == 44) +test_ok($z == 0) + +test_check "iterator" + +test_ok(!iterator?) + +def ttt + test_ok(iterator?) +end +ttt{} + +# yield at top level +test_ok(!defined?(yield)) + +$x = [1, 2, 3, 4] +$y = [] + +# iterator over array +for i in $x + $y.push i +end +test_ok($x == $y) + +# nested iterator +def tt + 1.upto(10) {|i| + yield i + } +end + +i=0 +tt{|i| break if i == 5} +test_ok(i == 0) + +def tt2(dummy) + yield 1 +end + +def tt3(&block) + tt2(raise(ArgumentError,""),&block) +end + +$x = false +begin + tt3{} +rescue ArgumentError + $x = true +rescue Exception +end +test_ok($x) + +def tt4 &block + tt2(raise(ArgumentError,""),&block) +end +$x = false +begin + tt4{} +rescue ArgumentError + $x = true +rescue Exception +end +test_ok($x) + +# iterator break/redo/next/retry +done = true +loop{ + break + done = false # should not reach here +} +test_ok(done) + +done = false +$bad = false +loop { + break if done + done = true + next + $bad = true # should not reach here +} +test_ok(!$bad) + +done = false +$bad = false +loop { + break if done + done = true + redo + $bad = true # should not reach here +} +test_ok(!$bad) + +$x = [] +for i in 1 .. 7 + $x.push i +end +test_ok($x.size == 7) +test_ok($x == [1, 2, 3, 4, 5, 6, 7]) + +# append method to built-in class +class Array + def iter_test1 + collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]} + end + def iter_test2 + a = collect{|e| [e, yield(e)]} + a.sort{|a,b|a[1]<=>b[1]} + end +end +$x = [[1,2],[3,4],[5,6]] +test_ok($x.iter_test1{|x|x} == $x.iter_test2{|x|x}) + +class IterTest + def initialize(e); @body = e; end + + def each0(&block); @body.each(&block); end + def each1(&block); @body.each {|*x| block.call(*x) } end + def each2(&block); @body.each {|*x| block.call(x) } end + def each3(&block); @body.each {|x| block.call(*x) } end + def each4(&block); @body.each {|x| block.call(x) } end + def each5; @body.each {|*x| yield(*x) } end + def each6; @body.each {|*x| yield(x) } end + def each7; @body.each {|x| yield(*x) } end + def each8; @body.each {|x| yield(x) } end + + def f(a) + a + end +end +test_ok(IterTest.new(nil).method(:f).to_proc.call([1]) == [1]) +m = /\w+/.match("abc") +test_ok(IterTest.new(nil).method(:f).to_proc.call([m]) == [m]) + +IterTest.new([0]).each0 {|x| test_ok(x == 0)} +IterTest.new([1]).each1 {|x| test_ok(x == 1)} +IterTest.new([2]).each2 {|x| test_ok(x == [2])} +#IterTest.new([3]).each3 {|x| test_ok(x == 3)} +IterTest.new([4]).each4 {|x| test_ok(x == 4)} +IterTest.new([5]).each5 {|x| test_ok(x == 5)} +IterTest.new([6]).each6 {|x| test_ok(x == [6])} +#IterTest.new([7]).each7 {|x| test_ok(x == 7)} +IterTest.new([8]).each8 {|x| test_ok(x == 8)} + +IterTest.new([[0]]).each0 {|x| test_ok(x == [0])} +IterTest.new([[1]]).each1 {|x| test_ok(x == [1])} +IterTest.new([[2]]).each2 {|x| test_ok(x == [[2]])} +IterTest.new([[3]]).each3 {|x| test_ok(x == 3)} +IterTest.new([[4]]).each4 {|x| test_ok(x == [4])} +IterTest.new([[5]]).each5 {|x| test_ok(x == [5])} +IterTest.new([[6]]).each6 {|x| test_ok(x == [[6]])} +IterTest.new([[7]]).each7 {|x| test_ok(x == 7)} +IterTest.new([[8]]).each8 {|x| test_ok(x == [8])} + +IterTest.new([[0,0]]).each0 {|*x| test_ok(x == [[0,0]])} +IterTest.new([[8,8]]).each8 {|*x| test_ok(x == [[8,8]])} + +def m0(v) + v +end + +def m1 + m0(block_given?) +end +test_ok(m1{p 'test'}) +test_ok(!m1) + +def m + m0(block_given?,&Proc.new{}) +end +test_ok(m1{p 'test'}) +test_ok(!m1) + +class C + include Enumerable + def initialize + @a = [1,2,3] + end + def each(&block) + @a.each(&block) + end +end + +test_ok(C.new.collect{|n| n} == [1,2,3]) + +test_ok(Proc == lambda{}.class) +test_ok(Proc == Proc.new{}.class) +lambda{|a|test_ok(a==1)}.call(1) +def block_test(klass, &block) + test_ok(klass === block) +end + +block_test(NilClass) +block_test(Proc){} + +def call_argument_test(state, proc, *args) + x = state + begin + proc.call(*args) + rescue ArgumentError + x = !x + end + test_ok(x,2) +end + +call_argument_test(true, lambda{||}) +call_argument_test(false, lambda{||}, 1) +call_argument_test(true, lambda{|a,|}, 1) +call_argument_test(false, lambda{|a,|}) +call_argument_test(false, lambda{|a,|}, 1,2) + +call_argument_test(true, Proc.new{||}) +call_argument_test(true, Proc.new{||}, 1) +call_argument_test(true, Proc.new{|a,|}, 1) +call_argument_test(true, Proc.new{|a,|}) +call_argument_test(true, Proc.new{|a,|}, 1,2) + +def block_get(&block) + block +end + +test_ok(Proc == block_get{}.class) +call_argument_test(true, block_get{||}) +call_argument_test(true, block_get{||}, 1) +call_argument_test(true, block_get{|a,|}, 1) +call_argument_test(true, block_get{|a,|}) +call_argument_test(true, block_get{|a,|}, 1,2) + +call_argument_test(true, block_get(&lambda{||})) +call_argument_test(false, block_get(&lambda{||}),1) +call_argument_test(true, block_get(&lambda{|a,|}),1) +call_argument_test(false, block_get(&lambda{|a,|}),1,2) + +blk = block_get{11} +test_ok(blk.class == Proc) +test_ok(blk.to_proc.class == Proc) +test_ok(blk.clone.call == 11) +test_ok(block_get(&blk).class == Proc) + +lmd = lambda{44} +test_ok(lmd.class == Proc) +test_ok(lmd.to_proc.class == Proc) +test_ok(lmd.clone.call == 44) +test_ok(block_get(&lmd).class == Proc) + +test_ok(Proc.new{|a,| a}.yield(1,2,3) == 1) +call_argument_test(true, Proc.new{|a,|}, 1,2) + +test_ok(Proc.new{|&b| b.call(10)}.call {|x| x} == 10) +test_ok(Proc.new{|a,&b| b.call(a)}.call(12) {|x| x} == 12) + +def test_return1 + Proc.new { + return 55 + }.yield + 5 +end +test_ok(test_return1() == 55) +def test_return2 + lambda { + return 55 + }.call + 5 +end +test_ok(test_return2() == 60) + +def proc_call(&b) + b.call +end +def proc_yield() + yield +end +def proc_return1 + lambda{return 42}.call+1 +end +test_ok(proc_return1() == 43) +def proc_return2 + ->{return 42}.call+1 +end +test_ok(proc_return2() == 43) +def proc_return3 + proc_call{return 42}+1 +end +test_ok(proc_return3() == 42) +def proc_return4 + proc_yield{return 42}+1 +end +test_ok(proc_return4() == 42) + +def ljump_test(state, proc, *args) + x = state + begin + proc.call(*args) + rescue LocalJumpError + x = !x + end + test_ok(x,2) +end + +ljump_test(false, block_get{break}) +ljump_test(true, lambda{break}) + +def exit_value_test(&block) + block.call +rescue LocalJumpError + $!.exit_value +end + +test_ok(45 == exit_value_test{break 45}) + +test_ok(55 == begin + block_get{break 55}.call + rescue LocalJumpError + $!.exit_value + end) + +def block_call(&block) + block.call +end + +def test_b1 + block_call{break 11} +end +test_ok(test_b1() == 11) + +def ljump_rescue(r) + begin + yield + rescue LocalJumpError => e + r if /from proc-closure/ =~ e.message + end +end + +def test_b2 + ljump_rescue(22) do + block_get{break 21}.call + end +end +test_ok(test_b2() == 22) + +def test_b3 + ljump_rescue(33) do + Proc.new{break 31}.yield + end +end +test_ok(test_b3() == 33) + +def test_b4 + lambda{break 44}.call +end +test_ok(test_b4() == 44) + +def test_b5 + ljump_rescue(55) do + b = block_get{break 54} + block_call(&b) + end +end +test_ok(test_b5() == 55) + +def test_b6 + b = lambda{break 67} + block_call(&b) + 66 +end +test_ok(test_b6() == 66) + +def util_r7 + block_get{break 78} +end + +def test_b7 + b = util_r7() + ljump_rescue(77) do + block_call(&b) + end +end +test_ok(test_b7() == 77) + +def util_b8(&block) + block_call(&block) +end + +def test_b8 + util_b8{break 88} +end +test_ok(test_b8() == 88) + +def util_b9(&block) + lambda{block.call; 98}.call +end + +def test_b9 + util_b9{break 99} +end +test_ok(test_b9() == 99) + +def util_b10 + util_b9{break 100} +end + +def test_b10 + util_b10() +end +test_ok(test_b10() == 100) + +def test_b11 + ljump_rescue(111) do + loop do + Proc.new{break 110}.yield + break 112 + end + end +end +test_ok(test_b11() == 111) + +def test_b12 + loop do + break lambda{break 122}.call + break 121 + end +end +test_ok(test_b12() == 122) + +def test_b13 + ljump_rescue(133) do + while true + Proc.new{break 130}.yield + break 131 + end + end +end +test_ok(test_b13() == 133) + +def test_b14 + while true + break lambda{break 144}.call + break 143 + end +end +test_ok(test_b14() == 144) + +def test_b15 + [0].each {|c| yield 1 } + 156 +end +test_ok(test_b15{|e| break 155 } == 155) + +def marity_test(m) + method = method(m) + test_ok(method.arity == method.to_proc.arity, 2) +end +marity_test(:test_ok) +marity_test(:marity_test) +marity_test(:p) + +lambda(&method(:test_ok)).call(true) +lambda(&block_get{|a,n| test_ok(a,n)}).call(true, 2) + +class ITER_TEST1 + def a + block_given? + end +end + +class ITER_TEST2 < ITER_TEST1 + def a + test_ok(super) + super + end +end +test_ok(ITER_TEST2.new.a {}) + +class ITER_TEST3 + def foo x + return yield if block_given? + x + end +end + +class ITER_TEST4 < ITER_TEST3 + def foo x + test_ok(super == yield) + test_ok(super(x, &nil) == x) + end +end + +ITER_TEST4.new.foo(44){55} + +class ITER_TEST5 + def tt(aa) + aa + end + + def uu(a) + class << self + define_method(:tt) do |sym| + super(sym) + end + end + end + + def xx(*x) + x.size + end +end + +a = ITER_TEST5.new +a.uu(12) +test_ok(a.tt(1) == 1) + +class ITER_TEST6 < ITER_TEST5 + def xx(*a) + a << 12 + super + end +end + +test_ok(ITER_TEST6.new.xx([24]) == 2) + +test_check "float" +test_ok(2.6.floor == 2) +test_ok((-2.6).floor == -3) +test_ok(2.6.ceil == 3) +test_ok((-2.6).ceil == -2) +test_ok(2.6.truncate == 2) +test_ok((-2.6).truncate == -2) +test_ok(2.6.round == 3) +test_ok((-2.4).truncate == -2) +test_ok((13.4 % 1 - 0.4).abs < 0.0001) +nan = 0.0/0 +def nan_test(x,y) + test_ok(x != y) + test_ok((x < y) == false) + test_ok((x > y) == false) + test_ok((x <= y) == false) + test_ok((x >= y) == false) +end +nan_test(nan, nan) +nan_test(nan, 0) +nan_test(nan, 1) +nan_test(nan, -1) +nan_test(nan, 1000) +nan_test(nan, -1000) +nan_test(nan, 1_000_000_000_000) +nan_test(nan, -1_000_000_000_000) +nan_test(nan, 100.0); +nan_test(nan, -100.0); +nan_test(nan, 0.001); +nan_test(nan, -0.001); +nan_test(nan, 1.0/0); +nan_test(nan, -1.0/0); + +#s = "3.7517675036461267e+17" +#test_ok(s == sprintf("%.16e", s.to_f)) +f = 3.7517675036461267e+17 +test_ok(f == sprintf("%.16e", f).to_f) + + +test_check "bignum" +def fact(n) + return 1 if n == 0 + f = 1 + while n>0 + f *= n + n -= 1 + end + return f +end +$x = fact(40) +test_ok($x == $x) +test_ok($x == fact(40)) +test_ok($x < $x+2) +test_ok($x > $x-2) +test_ok($x == 815915283247897734345611269596115894272000000000) +test_ok($x != 815915283247897734345611269596115894272000000001) +test_ok($x+1 == 815915283247897734345611269596115894272000000001) +test_ok($x/fact(20) == 335367096786357081410764800000) +$x = -$x +test_ok($x == -815915283247897734345611269596115894272000000000) +test_ok(2-(2**32) == -(2**32-2)) +test_ok(2**32 - 5 == (2**32-3)-2) + +$good = true; +for i in 1000..1014 + $good = false if ((1 << i) != (2**i)) +end +test_ok($good) + +$good = true; +n1= 1 << 1000 +for i in 1000..1014 + $good = false if ((1 << i) != n1) + n1 *= 2 +end +test_ok($good) + +$good = true; +n2=n1 +for i in 1..10 + n1 = n1 / 2 + n2 = n2 >> 1 + $good = false if (n1 != n2) +end +test_ok($good) + +$good = true; +for i in 4000..4096 + n1 = 1 << i; + if (n1**2-1) / (n1+1) != (n1-1) + $good = false + end +end +test_ok($good) + +b = 10**80 +a = b * 9 + 7 +test_ok(7 == a.modulo(b)) +test_ok(-b + 7 == a.modulo(-b)) +test_ok(b + -7 == (-a).modulo(b)) +test_ok(-7 == (-a).modulo(-b)) +test_ok(7 == a.remainder(b)) +test_ok(7 == a.remainder(-b)) +test_ok(-7 == (-a).remainder(b)) +test_ok(-7 == (-a).remainder(-b)) + +test_ok(10**40+10**20 == 10000000000000000000100000000000000000000) +test_ok(10**40/10**20 == 100000000000000000000) + +a = 677330545177305025495135714080 +b = 14269972710765292560 +test_ok(a % b == 0) +test_ok(-a % b == 0) + +def shift_test(a) + b = a / (2 ** 32) + c = a >> 32 + test_ok(b == c) + + b = a * (2 ** 32) + c = a << 32 + test_ok(b == c) +end + +shift_test(-4518325415524767873) +shift_test(-0xfffffffffffffffff) + +test_check "string & char" + +test_ok("abcd" == "abcd") +test_ok("abcd" =~ /abcd/) +test_ok("abcd" === "abcd") +# compile time string concatenation +test_ok("ab" "cd" == "abcd") +test_ok("#{22}aa" "cd#{44}" == "22aacd44") +test_ok("#{22}aa" "cd#{44}" "55" "#{66}" == "22aacd445566") +test_ok("abc" !~ /^$/) +test_ok("abc\n" !~ /^$/) +test_ok("abc" !~ /^d*$/) +test_ok(("abc" =~ /d*$/) == 3) +test_ok("" =~ /^$/) +test_ok("\n" =~ /^$/) +test_ok("a\n\n" =~ /^$/) +test_ok("abcabc" =~ /.*a/ && $& == "abca") +test_ok("abcabc" =~ /.*c/ && $& == "abcabc") +test_ok("abcabc" =~ /.*?a/ && $& == "a") +test_ok("abcabc" =~ /.*?c/ && $& == "abc") +test_ok(/(.|\n)*?\n(b|\n)/ =~ "a\nb\n\n" && $& == "a\nb") + +test_ok(/^(ab+)+b/ =~ "ababb" && $& == "ababb") +test_ok(/^(?:ab+)+b/ =~ "ababb" && $& == "ababb") +test_ok(/^(ab+)+/ =~ "ababb" && $& == "ababb") +test_ok(/^(?:ab+)+/ =~ "ababb" && $& == "ababb") + +test_ok(/(\s+\d+){2}/ =~ " 1 2" && $& == " 1 2") +test_ok(/(?:\s+\d+){2}/ =~ " 1 2" && $& == " 1 2") + +$x = <') == "") + +# character constants(assumes ASCII) +test_ok("a"[0] == ?a) +test_ok(?a == ?a) +test_ok(?\C-a == "\1") +test_ok(?\M-a == "\341") +test_ok(?\M-\C-a == "\201") +test_ok("a".upcase![0] == ?A) +test_ok("A".downcase![0] == ?a) +test_ok("abc".tr!("a-z", "A-Z") == "ABC") +test_ok("aabbcccc".tr_s!("a-z", "A-Z") == "ABC") +test_ok("abcc".squeeze!("a-z") == "abc") +test_ok("abcd".delete!("bc") == "ad") + +$x = "abcdef" +$y = [ ?a, ?b, ?c, ?d, ?e, ?f ] +$bad = false +$x.each_byte {|i| + if i.chr != $y.shift + $bad = true + break + end +} +test_ok(!$bad) + +s = "a string" +s[0..s.size]="another string" +test_ok(s == "another string") + +s = < Object) == -1) +test_ok((Object <=> String) == 1) +test_ok((Array <=> String) == nil) + +test_check "clone" +foo = Object.new +def foo.test + "test" +end +bar = foo.clone +def bar.test2 + "test2" +end + +test_ok(bar.test2 == "test2") +test_ok(bar.test == "test") +test_ok(foo.test == "test") + +begin + foo.test2 + test_ok false +rescue NoMethodError + test_ok true +end + +module M001; end +module M002; end +module M003; include M002; end +module M002; include M001; end +module M003; include M002; end + +test_ok(M003.ancestors == [M003, M002, M001]) + +test_check "marshal" +$x = [1,2,3,[4,5,"foo"],{1=>"bar"},2.5,fact(30)] +$y = Marshal.dump($x) +test_ok($x == Marshal.load($y)) + +StrClone=String.clone; +test_ok(Marshal.load(Marshal.dump(StrClone.new("abc"))).class == StrClone) + +[[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z| + a = (x.to_f + y.to_f / z.to_f) * Math.exp(w.to_f / (x.to_f + y.to_f / z.to_f)) + ma = Marshal.dump(a) + b = Marshal.load(ma) + test_ok(a == b) +} + +test_check "pack" + +$format = "c2x5CCxsdils_l_a6"; +# Need the expression in here to force ary[5] to be numeric. This avoids +# test2 failing because ary2 goes str->numeric->str and ary does not. +ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,-32767,-123456,"abcdef"] +$x = ary.pack($format) +ary2 = $x.unpack($format) + +test_ok(ary.length == ary2.length) +test_ok(ary.join(':') == ary2.join(':')) +test_ok($x =~ /def/) + +$x = [-1073741825] +test_ok($x.pack("q").unpack("q") == $x) + +test_check "math" +test_ok(Math.sqrt(4) == 2) + +include Math +test_ok(sqrt(4) == 2) + +test_check "struct" +struct_test = Struct.new("Test", :foo, :bar) +test_ok(struct_test == Struct::Test) + +test = struct_test.new(1, 2) +test_ok(test.foo == 1 && test.bar == 2) +test_ok(test[0] == 1 && test[1] == 2) + +a, b = test.to_a +test_ok(a == 1 && b == 2) + +test[0] = 22 +test_ok(test.foo == 22) + +test.bar = 47 +test_ok(test.bar == 47) + +test_check "variable" +test_ok($$.instance_of?(Fixnum)) + +# read-only variable +begin + $$ = 5 + test_ok false +rescue NameError + test_ok true +end + +foobar = "foobar" +$_ = foobar +test_ok($_ == foobar) + +class Gods + @@rule = "Uranus" # private to Gods + def ruler0 + @@rule + end + + def self.ruler1 # <= per method definition style + @@rule + end + class << self # <= multiple method definition style + def ruler2 + @@rule + end + end +end + +module Olympians + @@rule ="Zeus" + def ruler3 + @@rule + end +end + +class Titans < Gods + @@rule = "Cronus" # do not affect @@rule in Gods + include Olympians + def ruler4 + @@rule + end +end + +test_ok(Gods.new.ruler0 == "Cronus") +test_ok(Gods.ruler1 == "Cronus") +test_ok(Gods.ruler2 == "Cronus") +test_ok(Titans.ruler1 == "Cronus") +test_ok(Titans.ruler2 == "Cronus") +atlas = Titans.new +test_ok(atlas.ruler0 == "Cronus") +test_ok(atlas.ruler3 == "Zeus") +test_ok(atlas.ruler4 == "Cronus") + +test_check "trace" +$x = 1234 +$y = 0 +trace_var :$x, Proc.new{$y = $x} +$x = 40414 +test_ok($y == $x) + +untrace_var :$x +$x = 19660208 +test_ok($y != $x) + +trace_var :$x, Proc.new{$x *= 2} +$x = 5 +test_ok($x == 10) + +untrace_var :$x + +test_check "defined?" + +test_ok(defined?($x)) # global variable +test_ok(defined?($x) == 'global-variable')# returns description + +foo=5 +test_ok(defined?(foo)) # local variable + +test_ok(defined?(Array)) # constant +test_ok(defined?(Object.new)) # method +test_ok(!defined?(Object.print))# private method +test_ok(defined?(1 == 2)) # operator expression + +class Foo + def foo + p :foo + end + protected :foo + def bar(f) + test_ok(defined?(self.foo)) + test_ok(defined?(f.foo)) + end +end +f = Foo.new +test_ok(defined?(f.foo) == nil) +f.bar(f) + +def defined_test + return !defined?(yield) +end + +test_ok(defined_test) # not iterator +test_ok(!defined_test{}) # called as iterator + +test_check "alias" +class Alias0 + def foo; "foo" end +end +class Alias1 0 + printf "not ok/test: %d failed %d\n", $ntest, $failed +else + printf "end of test(test: %d)\n", $ntest +end diff --git a/trunk/sample/testunit/adder.rb b/trunk/sample/testunit/adder.rb new file mode 100644 index 0000000000..aa5c88cc7b --- /dev/null +++ b/trunk/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/trunk/sample/testunit/subtracter.rb b/trunk/sample/testunit/subtracter.rb new file mode 100644 index 0000000000..2c08247805 --- /dev/null +++ b/trunk/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/trunk/sample/testunit/tc_adder.rb b/trunk/sample/testunit/tc_adder.rb new file mode 100644 index 0000000000..8453beb20a --- /dev/null +++ b/trunk/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/trunk/sample/testunit/tc_subtracter.rb b/trunk/sample/testunit/tc_subtracter.rb new file mode 100644 index 0000000000..d2c8313350 --- /dev/null +++ b/trunk/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/trunk/sample/testunit/ts_examples.rb b/trunk/sample/testunit/ts_examples.rb new file mode 100644 index 0000000000..3d24dd6522 --- /dev/null +++ b/trunk/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/trunk/sample/time.rb b/trunk/sample/time.rb new file mode 100644 index 0000000000..e16912052e --- /dev/null +++ b/trunk/sample/time.rb @@ -0,0 +1,12 @@ +#! /usr/bin/env ruby + +b = Time.now +system(*ARGV) +e = Time.now + +tms = Process.times +real = e - b +user = tms.cutime +sys = tms.cstime + +STDERR.printf("%11.1f real %11.1f user %11.1f sys\n", real, user, sys) diff --git a/trunk/sample/trojan.rb b/trunk/sample/trojan.rb new file mode 100644 index 0000000000..3a35ac21c2 --- /dev/null +++ b/trunk/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/trunk/sample/tsvr.rb b/trunk/sample/tsvr.rb new file mode 100644 index 0000000000..52cdd32dce --- /dev/null +++ b/trunk/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/trunk/sample/uumerge.rb b/trunk/sample/uumerge.rb new file mode 100644 index 0000000000..2576bcb864 --- /dev/null +++ b/trunk/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/trunk/sample/webrick/demo-app.rb b/trunk/sample/webrick/demo-app.rb new file mode 100644 index 0000000000..c7a2a0a6a4 --- /dev/null +++ b/trunk/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_ + +
+ text:
+ file:
+ check: + a, + b, + c, +
+ +
+ + _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_ + +

Query Parameters

+ #{display_query(req.query)} + return +

Request

+
#{WEBrick::HTMLUtils::escape(PP::pp(req, "", 80))}
+

Response

+
#{WEBrick::HTMLUtils::escape(PP::pp(res, "", 80))}
+ + _end_of_html_ + res['content-type'] = 'text/html; charset=iso-8859-1' + end + + private + + def display_query(q) + ret = "" + q.each{|key, val| + ret << "

#{WEBrick::HTMLUtils::escape(key)}

" + ret << "" + 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 << "
" + } + ret + end + + def make_tr(arg0, arg1) + "#{arg0}#{WEBrick::HTMLUtils::escape(arg1)}" + end +end diff --git a/trunk/sample/webrick/demo-multipart.cgi b/trunk/sample/webrick/demo-multipart.cgi new file mode 100644 index 0000000000..0893fadadf --- /dev/null +++ b/trunk/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/trunk/sample/webrick/demo-servlet.rb b/trunk/sample/webrick/demo-servlet.rb new file mode 100644 index 0000000000..9c18cc65d1 --- /dev/null +++ b/trunk/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/trunk/sample/webrick/demo-urlencoded.cgi b/trunk/sample/webrick/demo-urlencoded.cgi new file mode 100644 index 0000000000..e4706f8b59 --- /dev/null +++ b/trunk/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/trunk/sample/webrick/hello.cgi b/trunk/sample/webrick/hello.cgi new file mode 100644 index 0000000000..35d2240df0 --- /dev/null +++ b/trunk/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/trunk/sample/webrick/hello.rb b/trunk/sample/webrick/hello.rb new file mode 100644 index 0000000000..4d02676818 --- /dev/null +++ b/trunk/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/trunk/sample/webrick/httpd.rb b/trunk/sample/webrick/httpd.rb new file mode 100644 index 0000000000..b0edf47582 --- /dev/null +++ b/trunk/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/trunk/sample/webrick/httpproxy.rb b/trunk/sample/webrick/httpproxy.rb new file mode 100644 index 0000000000..bca0cc4626 --- /dev/null +++ b/trunk/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/trunk/sample/webrick/httpsd.rb b/trunk/sample/webrick/httpsd.rb new file mode 100644 index 0000000000..a120782c3c --- /dev/null +++ b/trunk/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 -- cgit v1.2.3