[macruby-changes] [247] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jun 5 01:12:02 PDT 2008
Revision: 247
http://trac.macosforge.org/projects/ruby/changeset/247
Author: lsansonetti at apple.com
Date: 2008-06-05 01:11:58 -0700 (Thu, 05 Jun 2008)
Log Message:
-----------
merge with ruby trunk r16762 + better/faster objc-like dispatcher
Modified Paths:
--------------
MacRuby/trunk/ChangeLog
MacRuby/trunk/Makefile.in
MacRuby/trunk/README
MacRuby/trunk/README.ja
MacRuby/trunk/array.c
MacRuby/trunk/benchmark/bmx_temp.rb
MacRuby/trunk/bin/gem
MacRuby/trunk/blockinlining.c
MacRuby/trunk/bootstraptest/test_eval.rb
MacRuby/trunk/bootstraptest/test_jump.rb
MacRuby/trunk/bootstraptest/test_knownbug.rb
MacRuby/trunk/bootstraptest/test_literal.rb
MacRuby/trunk/bootstraptest/test_syntax.rb
MacRuby/trunk/bootstraptest/test_thread.rb
MacRuby/trunk/bs.c
MacRuby/trunk/class.c
MacRuby/trunk/common.mk
MacRuby/trunk/compile.c
MacRuby/trunk/configure.in
MacRuby/trunk/cont.c
MacRuby/trunk/dir.c
MacRuby/trunk/doc/NEWS
MacRuby/trunk/encoding.c
MacRuby/trunk/enum.c
MacRuby/trunk/enumerator.c
MacRuby/trunk/error.c
MacRuby/trunk/eval.c
MacRuby/trunk/eval_error.c
MacRuby/trunk/eval_intern.h
MacRuby/trunk/eval_jump.c
MacRuby/trunk/ext/nkf/nkf-utf8/nkf.c
MacRuby/trunk/ext/nkf/nkf.c
MacRuby/trunk/ext/openssl/ossl_bn.c
MacRuby/trunk/ext/openssl/ossl_pkcs5.c
MacRuby/trunk/ext/openssl/ossl_pkey_dh.c
MacRuby/trunk/ext/openssl/ossl_pkey_dsa.c
MacRuby/trunk/ext/openssl/ossl_rand.c
MacRuby/trunk/ext/openssl/ossl_x509store.c
MacRuby/trunk/ext/purelib.rb
MacRuby/trunk/ext/stringio/stringio.c
MacRuby/trunk/ext/zlib/extconf.rb
MacRuby/trunk/file.c
MacRuby/trunk/gc.c
MacRuby/trunk/hash.c
MacRuby/trunk/id.c
MacRuby/trunk/id.h
MacRuby/trunk/include/ruby/defines.h
MacRuby/trunk/include/ruby/encoding.h
MacRuby/trunk/include/ruby/intern.h
MacRuby/trunk/include/ruby/node.h
MacRuby/trunk/include/ruby/ruby.h
MacRuby/trunk/include/ruby/win32.h
MacRuby/trunk/include/ruby.h
MacRuby/trunk/insns.def
MacRuby/trunk/io.c
MacRuby/trunk/iseq.c
MacRuby/trunk/keywords
MacRuby/trunk/lex.c.blt
MacRuby/trunk/lex.c.src
MacRuby/trunk/lib/delegate.rb
MacRuby/trunk/lib/erb.rb
MacRuby/trunk/lib/net/imap.rb
MacRuby/trunk/lib/singleton.rb
MacRuby/trunk/lib/un.rb
MacRuby/trunk/lib/webrick/httpservlet/abstract.rb
MacRuby/trunk/lib/webrick/httpservlet/cgi_runner.rb
MacRuby/trunk/lib/webrick/httpservlet/cgihandler.rb
MacRuby/trunk/lib/webrick/httpservlet/filehandler.rb
MacRuby/trunk/load.c
MacRuby/trunk/main.c
MacRuby/trunk/marshal.c
MacRuby/trunk/math.c
MacRuby/trunk/misc/ruby-mode.el
MacRuby/trunk/missing/crypt.c
MacRuby/trunk/missing/vsnprintf.c
MacRuby/trunk/mkconfig.rb
MacRuby/trunk/numeric.c
MacRuby/trunk/objc.m
MacRuby/trunk/object.c
MacRuby/trunk/pack.c
MacRuby/trunk/parse.y
MacRuby/trunk/proc.c
MacRuby/trunk/process.c
MacRuby/trunk/rational.c
MacRuby/trunk/re.c
MacRuby/trunk/regenc.h
MacRuby/trunk/regerror.c
MacRuby/trunk/regexec.c
MacRuby/trunk/ruby.c
MacRuby/trunk/sample-macruby/CircleView/CircleView.rb
MacRuby/trunk/sample-macruby/CircleView/main.m
MacRuby/trunk/signal.c
MacRuby/trunk/sprintf.c
MacRuby/trunk/string.c
MacRuby/trunk/struct.c
MacRuby/trunk/template/insns.inc.tmpl
MacRuby/trunk/test/erb/test_erb.rb
MacRuby/trunk/test/net/imap/test_imap.rb
MacRuby/trunk/test/ruby/envutil.rb
MacRuby/trunk/test/ruby/test_array.rb
MacRuby/trunk/test/ruby/test_class.rb
MacRuby/trunk/test/ruby/test_continuation.rb
MacRuby/trunk/test/ruby/test_enum.rb
MacRuby/trunk/test/ruby/test_eval.rb
MacRuby/trunk/test/ruby/test_file.rb
MacRuby/trunk/test/ruby/test_file_exhaustive.rb
MacRuby/trunk/test/ruby/test_io.rb
MacRuby/trunk/test/ruby/test_m17n.rb
MacRuby/trunk/test/ruby/test_method.rb
MacRuby/trunk/test/ruby/test_module.rb
MacRuby/trunk/test/ruby/test_numeric.rb
MacRuby/trunk/test/ruby/test_objectspace.rb
MacRuby/trunk/test/ruby/test_pack.rb
MacRuby/trunk/test/ruby/test_proc.rb
MacRuby/trunk/test/ruby/test_process.rb
MacRuby/trunk/test/ruby/test_regexp.rb
MacRuby/trunk/test/ruby/test_rubyoptions.rb
MacRuby/trunk/test/ruby/test_signal.rb
MacRuby/trunk/test/ruby/test_sprintf.rb
MacRuby/trunk/test/ruby/test_string.rb
MacRuby/trunk/test/ruby/test_struct.rb
MacRuby/trunk/test/ruby/test_thread.rb
MacRuby/trunk/test/ruby/test_utf16.rb
MacRuby/trunk/test/ruby/test_utf32.rb
MacRuby/trunk/test/test_delegate.rb
MacRuby/trunk/test/webrick/test_cgi.rb
MacRuby/trunk/test/webrick/test_filehandler.rb
MacRuby/trunk/test/webrick/utils.rb
MacRuby/trunk/thread.c
MacRuby/trunk/thread_pthread.c
MacRuby/trunk/thread_win32.c
MacRuby/trunk/time.c
MacRuby/trunk/tool/instruction.rb
MacRuby/trunk/transcode.c
MacRuby/trunk/util.c
MacRuby/trunk/variable.c
MacRuby/trunk/version.h
MacRuby/trunk/vm.c
MacRuby/trunk/vm.h
MacRuby/trunk/vm_core.h
MacRuby/trunk/vm_dump.c
MacRuby/trunk/vm_evalbody.c
MacRuby/trunk/vm_insnhelper.c
MacRuby/trunk/vm_opts.h
Added Paths:
-----------
MacRuby/trunk/include/ruby/mvm.h
MacRuby/trunk/lib/cmath.rb
MacRuby/trunk/test/ruby/test_argf.rb
MacRuby/trunk/test/ruby/test_big5.rb
MacRuby/trunk/test/ruby/test_cp949.rb
MacRuby/trunk/test/ruby/test_euc_jp.rb
MacRuby/trunk/test/ruby/test_euc_kr.rb
MacRuby/trunk/test/ruby/test_euc_tw.rb
MacRuby/trunk/test/ruby/test_gb18030.rb
MacRuby/trunk/test/ruby/test_gbk.rb
MacRuby/trunk/test/ruby/test_iso_8859.rb
MacRuby/trunk/test/ruby/test_koi8.rb
MacRuby/trunk/test/ruby/test_require.rb
MacRuby/trunk/test/ruby/test_shift_jis.rb
MacRuby/trunk/test/ruby/test_windows_1251.rb
MacRuby/trunk/test/webrick/.htaccess
MacRuby/trunk/test/webrick/webrick_long_filename.cgi
MacRuby/trunk/vm_eval.c
MacRuby/trunk/vm_method.c
Removed Paths:
-------------
MacRuby/trunk/eval_method.c
MacRuby/trunk/ext/tk/
MacRuby/trunk/ext/win32ole/
MacRuby/trunk/lib/generator.rb
MacRuby/trunk/lib/require_relative.rb
MacRuby/trunk/lib/rubygems/gem_open_uri.rb
MacRuby/trunk/lib/rubygems/open-uri.rb
Modified: MacRuby/trunk/ChangeLog
===================================================================
--- MacRuby/trunk/ChangeLog 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ChangeLog 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,3 +1,897 @@
+Tue Jun 3 01:21:51 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_method.rb: add a test.
+
+Tue Jun 3 00:26:48 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * marshal.c (w_object): add a check for modification of array during
+ its dump.
+
+Mon Jun 2 22:27:57 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * enc/iso_8859_5.c: Large omicron should lowercase to small omicron.
+
+ * test/ruby/test_big5.rb, test/ruby/test_cp949.rb,
+ test/ruby/test_euc_jp.rb, test/ruby/test_euc_kr.rb,
+ test/ruby/test_euc_tw.rb, test/ruby/test_gb18030.rb,
+ test/ruby/test_gbk.rb, test/ruby/test_iso_8859.rb,
+ test/ruby/test_koi8.rb, test/ruby/test_shift_jis.rb,
+ test/ruby/test_windows_1251.rb: new tests for encoding.
+
+ * test/ruby/test_utf16.rb, test/ruby/test_utf32.rb,
+ test/ruby/test_regexp.rb: add tests.
+
+Mon Jun 2 21:56:47 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_file.rb: add tests for uninitialized object.
+
+ * test/ruby/test_class.rb: ditto.
+
+ * test/ruby/test_thread.rb: ditto.
+
+Mon Jun 2 21:44:15 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * re.c: fix SEGV by Regexp.allocate.names, Match.allocate.names, etc.
+
+ * test/ruby/test_regexp.rb: add tests for above.
+
+ * io.c: fix SEGV by IO.allocate.print, etc.
+
+ * test/ruby/test_io.rb: add tests for above.
+
+Mon Jun 2 19:17:47 2008 Tanaka Akira <akr at fsij.org>
+
+ * test/ruby/test_argf.rb (teardown): remove renamed temporary files.
+
+Mon Jun 2 18:51:15 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * lib/un.rb (wait_writable): wait until target files can be
+ written actually.
+
+ * win32/Makefile.sub (LDSHARED_0, LINK_SO): get rid of failure of
+ mt.exe.
+
+Mon Jun 2 16:26:17 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * lib/delegate.rb (Delegator::MethodDelegation#respond_to):
+ respond_to? should now take optional second argument; submitted
+ by Jeremy Kemper <jeremy at bitsweat.net> in [ruby-core:17045].
+
+Mon Jun 2 16:14:18 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * lib/erb.rb (ERB::Compiler::TrimScanner#scan_line): Oops. This
+ change did not apply to trunk. Backed out.
+
+Mon Jun 2 16:08:24 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * lib/erb.rb (ERB::Compiler::TrimScanner#scan_line): Fix a bug
+ where tokens are not yilelded one by one.
+
+ * test/erb/test_erb.rb (TestERBCore#_test_01)
+ (TestERBCore#test_02_safe_04): The expected value should come
+ first for assert_equal().
+
+Mon Jun 2 13:06:38 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * mkconfig.rb: hide build path from rbconfig.rb.
+
+Mon Jun 2 08:46:52 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * util.c (ruby_strtod, dtoa): initialize more variables for error
+ handling.
+
+Mon Jun 2 04:55:05 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * suppress warnings on cygwin, mingw and mswin.
+
+Mon Jun 2 04:35:32 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * enc/gb18030.c (gb18030_code_to_mbc): add 0x80000000
+ for 4bytes character.
+
+Mon Jun 2 03:52:04 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * ruby.c (set_arg0): reverted used variable definition.
+
+Mon Jun 2 03:23:25 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * enc/gb18030.c (gb18030_mbc_to_code): mask by 0x7FFFFFFF
+ because OnigCodePoint will be used as 32bit signed int.
+ Masking by 0x7FFFFFFF is ok on GB18030;
+ Minumum 4bytes character is 0x81308130.
+
+Sun Jun 1 22:29:35 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * rational.c (string_to_r_internal): use rb_isdigit.
+
+ * marshal.c (long_toobig): use %zd.
+
+ * ruby.c (set_arg0): move unused variable definition.
+
+Sun Jun 1 12:18:12 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * insns.def (DEFINE_INSN): subtract of pointers is ptrdiff_t.
+ this is not int on 64bit system.
+
+ * vm_dump.c (control_frame_dump): ditto.
+
+ * vm_dump.c (stack_dump_each): ditto.
+
+ * vm_dump.c (debug_print_register): ditto.
+
+ * vm_dump.c (debug_print_pre): ditto.
+
+ * transcode.c (str_transcode): ditto.
+
+Sun Jun 1 10:32:18 2008 Tanaka Akira <akr at fsij.org>
+
+ * test/ruby/envutil.rb (assert_normal_exit): show coredump status.
+
+Sat May 31 23:33:34 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * README, README.ja: Add a note about default C flags.
+
+Sat May 31 23:02:00 2008 Tanaka Akira <akr at fsij.org>
+
+ * gc.c (count_objects): clear given hash.
+
+Sat May 31 20:28:10 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_regexp.rb: add tests.
+
+Sat May 31 19:11:39 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * enc/utf_16{be,le}.c (utf16{be,le}_code_to_mbc):
+ fix codepoint to bytes.
+
+Sat May 31 18:28:17 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * suppress warnings with -Wwrite-string.
+
+Sat May 31 18:26:33 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * array.c (rb_ary_delete_if): should return enumerator if no block
+ is given. [ruby-dev:34901]
+
+Sat May 31 15:58:08 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * Makefile.in, configure.in (warnflags): defaulted to -Wall
+ -Wno-parentheses with gcc. [ruby-dev:34810]
+
+Sat May 31 15:17:36 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * include/ruby/mvm.h: new header file for MVM, and moved rb_vm_t and
+ rb_thread_t from vm_core.h.
+
+Sat May 31 12:02:23 2008 Tanaka Akira <akr at fsij.org>
+
+ * test/ruby/envutil.rb (assert_normal_exit): show pid when fail.
+
+Fri May 30 23:55:56 2008 Kazuhiro NISHIYAMA <zn at mbf.nifty.com>
+
+ * test/ruby/test_rubyoptions.rb: add a test of RUBY_DESCRIPTION.
+
+Fri May 30 22:47:17 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_regexp.rb: add tests.
+
+Fri May 30 22:40:53 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_signal.rb: add tests to achieve over 80% test
+ coverage of signal.c.
+
+Fri May 30 22:28:03 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * signal.c (esignal_signo): fix SignalException#signo which returned
+ nil absolutely.
+
+ * signal.c (esignal_init): always prepend "SIG" to a string that is
+ returned by SignalException#signm.
+
+Fri May 30 22:17:39 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_argf.rb: rename a conflicting method name.
+
+ * test/ruby/test_string.rb: ditto.
+
+ * test/ruby/test_io.rb: ditto.
+
+Fri May 30 22:14:37 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * compile.c (defined_expr): fix SEGV by defined?([1]).
+
+Fri May 30 12:18:43 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * common.mk (prelude.c): simply depends on PREP. [ruby-dev:34877]
+
+ * enc/make_encdb.rb, enc/trans/make_transdb.rb: ditto.
+
+Fri May 30 10:55:42 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * vm_core.h (struct rb_unblock_callback), thread.c
+ (set_unblock_function), thread_{pthread,win32}.c (native_sleep):
+ extracted from struct rb_thread_struct.
+
+ * thread.c (reset_unblock_function): not check interrupts at leaving
+ blocking region. [ruby-dev:34874]
+
+Fri May 30 06:09:31 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * enc/utf_8.c: add UTF8-MAC (UTF-8-MAC).
+
+Fri May 30 04:17:13 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * enum.c (enum_count, count_all_i, Init_Enumerable),
+ array.c (rb_ary_count): If no argument or block is given, count
+ the number of all elements.
+
+Fri May 30 03:12:18 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * ext/openssl/ossl_bn.c (ossl_bn_s_rand, ossl_bn_s_pseudo_rand):
+ Int should be enough here.
+
+Fri May 30 02:35:00 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * ext/openssl/ossl_bn.c (ossl_bn_s_rand, ossl_bn_s_pseudo_rand),
+ ext/openssl/ossl_pkey_dh.c (ossl_dh_s_generate)
+ (ossl_dh_initialize),
+ ext/openssl/ossl_pkey_dsa.c (ossl_dsa_s_generate),
+ ext/openssl/ossl_rand.c (ossl_rand_bytes)
+ (ossl_rand_pseudo_bytes, ossl_rand_egd_bytes),
+ ext/openssl/ossl_x509store.c (ossl_x509stctx_set_error): Do not
+ use FIX2INT() without checking the value type. Use NUM2INT()
+ instead; found by akr in [ruby-dev:34890].
+
+Fri May 30 02:08:20 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * signal.c (esignal_init): handle a non-integer argument correctly,
+ allowing SignalException.new(:INT).
+
+Fri May 30 00:59:47 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_regexp.rb: add tests.
+
+Thu May 29 22:51:05 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_require.rb: add a test for load with wrap flag, to
+ achieve 100% test coverage of eval_jump.c.
+
+Thu May 29 22:47:53 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_argf.rb: new tests for ARGF, to achieve over 85% test
+ coverage of file.c.
+
+ * test/ruby/test_io.rb: add tests.
+
+Thu May 29 22:41:48 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * io.c (argf_readchar): raise EOFError, synchronizing IO#readchar.
+
+Thu May 29 22:29:39 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * io.c (argf_external_encoding, argf_internal_encoding): fix SEGV by
+ ARGF.external_encoding.
+
+Thu May 29 17:52:31 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * ext/zlib/extconf.rb: search zlib1, and regard mswin32 later than VC6
+ as WIN32. [ruby-core:16984]
+
+Wed May 28 18:05:28 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * array.c (rb_ary_nitems, Init_Array): Axe Array#nitems().
+ cf. [ruby-dev:34676]-[ruby-dev:34713]
+
+Wed May 28 17:50:32 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * win32/mkexports.rb (Exports#objdump, Exports#each_line): extracted.
+
+Wed May 28 17:41:43 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * Makefile.in (MKPREP): appended $(RBCONFIG).
+
+ * common.mk (enc.mk, prelude.c): not depend on $(RBCONFIG) on mswin32
+ to get of compiling twice each time.
+
+ * win32/Makefile.sub (prelude.c): not depend on $(PREP).
+
+Wed May 28 17:37:07 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * win32/mkexports.rb (Exports::Mswin#each_export): speed up.
+
+Wed May 28 16:41:59 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * array.c (rb_ary_slice_bang): Call rb_ary_modify_check() at the
+ beginning. [rubyspec]
+
+Wed May 28 16:12:44 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * lib/webrick/httpservlet/cgihandler.rb (WEBrick::HTTPServlet::CGIHandler#do_GET):
+ Set the HTTP status code to 302 if a Location header field is
+ present and the status code is not valid as a client
+ redirection. cf. RFC 3875 6.2.3, 6.2.4.
+
+Wed May 28 15:53:52 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * enc/trans/japanese.c (to_SHIFT_JIS_EF_infos): typo.
+
+Wed May 28 15:18:16 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * lib/singleton.rb (SingletonClassMethods): _load should be public.
+
+Wed May 28 13:30:43 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * enc/trans/japanese.c: add workarround for Unicode to CP932.
+ U+2015->0x815C, U+2225->0x8161, U+FF0D->0x817C, U+FF3C->0x815F,
+ U+FF5E->0x8160, U+FFE0->0x8191, U+FFE1->0x8192, U+FFE2->0x81CA
+
+Wed May 28 12:52:41 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * marshal.c (w_object, marshal_dump, r_object0, marshal_load): search
+ private methods too. [ruby-dev:34671]
+
+ * object.c (convert_type): ditto.
+
+Wed May 28 08:42:51 2008 Tanaka Akira <akr at fsij.org>
+
+ * numeric.c: "%" is required before PRI?VALUE.
+
+Tue May 27 22:10:44 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * eval_error.c (error_handle): SystemExit and SignalException throws
+ TAG_RAISE but not TAG_FATAL.
+
+ * thread.c (rb_thread_execute_interrupts): delay interrupts during
+ raising exceptions. [ruby-dev:34855]
+
+Tue May 27 20:18:30 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * array.c (rb_ary_slice_bang): Return an empty array instead of
+ nil when pos is valid and len is adjusted from a valid value to
+ zero; caught by RubySpec.
+
+Tue May 27 19:12:37 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * Makefile.in (MKPREP), common.mk, win32/Makefile.sub (prelude.c): get
+ rid of depending PREP with nmake.
+
+ * common.mk (encs): depends on libruby.
+
+Tue May 27 19:00:22 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * ext/stringio/stringio.c (strio_each_char, Init_stringio): Add
+ StringIO#{each_char,chars}.
+ (Init_stringio): Fix StringIO#bytes.
+
+Tue May 27 17:54:35 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * ext/stringio/stringio.c (strio_each_byte): Return self instead
+ of nil as the rdoc says.
+
+Tue May 27 15:36:27 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * numeric.c (check_int): use PRIxVALUE format specifier.
+
+ * numeric.c (check_uint, rb_num2fix, int_chr): ditto.
+
+ * numeric.c (num_fdiv): fallback to_f should always return float
+ result. should not use #quo that may return rational.
+
+ * numeric.c (num_div): should raise ZeroDivisionError.
+
+ * numeric.c (fix_divide): ditto.
+
+ * test/ruby/test_numeric.rb (TestNumeric::test_divmod): avoid
+ ZeroDivisionError in tests.
+
+Tue May 27 13:14:53 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * enum.c (enum_to_a): Pass arguments through to #each().
+ (enum_sort): Follow the enum_to_a signature change.
+ (enum_reverse_each): Add #reverse_each().
+
+Tue May 27 13:12:37 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * io.c (Init_IO): Define ARGF.{lines,bytes,chars}.
+
+Tue May 27 12:06:37 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * file.c (BUFCHECK): wrong condition. [ruby-core:16921]
+
+ * file.c (file_expand_buf): shouldn't use buflen for length of string.
+
+Mon May 26 18:24:48 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * file.c (BUFCHECK): no resize if enough room.
+
+ * file.c (file_expand_path): use BUFCHECK.
+
+Mon May 26 17:48:42 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * enumerator.c (struct enumerator, enumerator_init)
+ (enumerator_init_copy, enumerator_each): Eliminate iter.
+ (enumerator_ptr): Do not hardcode the class name.
+ (enumerator_with_index): Delay variable initialization after
+ RETURN_ENUMERATOR().
+
+Mon May 26 17:23:49 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * file.c (file_expand_path): add more space for '/'.
+
+ * file.c (file_expand_path): should reset address of p after calling
+ rb_str_resize(). [ruby-dev:34800]
+
+Mon May 26 16:49:55 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * misc/ruby-mode.el (ruby-mode): use run-hooks if run-mode-hook is
+ not available. a patch from Kazuhiro NISHIYAMA <zn at mbf.nifty.com>
+ in [ruby-dev:34853].
+
+Mon May 26 16:41:35 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * file.c (ntfs_tail): filename which starts with '.' is valid.
+
+ * file.c (file_expand_path): cygwin symlink support.
+
+Mon May 26 07:15:52 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * vm_dump.c (rb_vm_bugreport): rb_make_backtrace has no arguments.
+
+Mon May 26 01:17:54 2008 Tanaka Akira <akr at fsij.org>
+
+ * test/ruby/envutil.rb (assert_normal_exit): signal description
+ refined.
+
+Mon May 26 00:52:52 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * hash.c (env_each_key, env_each_value, env_reject_bang)
+ (rb_env_clear, env_replace): Omit duplicated secure level check.
+
+Mon May 26 00:37:16 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * hash.c (env_each_value): Do not call env_values() twice.
+
+Sun May 25 17:54:36 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * compile.c (iseq_compile): set local_table for
+ ISEQ_TYPE_DEFINED_GUARD.
+
+Sun May 25 17:52:25 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * compile.c (iseq_build_body): remove side effect from
+ VM::InstructionSequence.load.
+
+Sun May 25 04:30:45 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_modules.rb (remove_json_mixins): change judgment
+ condition.
+
+Sun May 25 03:54:39 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_modules.rb (test_ancestors, test_included_modules):
+ ignore json mixins.
+
+Sun May 25 02:37:25 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * eval_method.c: renamed from vm_method.c. "vm_method.c" is included
+ by "vm.c".
+
+ * vm_eval.c: added. Some codes are moved from "eval.c"
+
+ * common.mk: fix for above changes.
+
+ * compile.c: make a vm_eval(0)
+
+ * eval.c, eval_error.c, eval_intern.h, eval_jump.c, proc.c, vm.c,
+ id.c, id.h, vm_core.h, vm_dump.c, vm_evalbody.c, vm_insnhelper.c,
+ blockinlining.c: fix for above changes. and do some refactoring.
+ this changes improve rb_yield() performance.
+
+Sat May 24 22:32:49 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * util.c (ruby_strtod): clear errno at the top of our own
+ impelementation of strtod(3). [ruby-dev:34834] [ruby-dev:34839]
+
+Sat May 24 15:26:16 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * compile.c (iseq_set_exception_table, NODE_WHILE, NODE_NEXT): remove
+ special handling that decrements sp in CATCH_TYPE_NEXT for NODE_WHILE.
+
+ * vm.c (vm_eval_body), vm_insnhelper.c (vm_throw): remove unused code.
+
+Sat May 24 08:13:34 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * transcode.c (rb_str_transcode): argc is 1, and argv is &to.
+
+Fri May 23 17:55:11 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * array.c (rb_ary_slice_bang): Be consistent with Array#slice()
+ and String#slice!(). Just return nil when a negative length or
+ out of boundary index is given instead of raising an exception
+ via internal functions.
+
+Fri May 23 16:44:34 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * enumerator.c (Init_Enumerator): Override
+ Enumerable::Enumerator#each_with_index with #with_index.
+
+Fri May 23 12:23:05 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * vm_core.h (rb_num_t): moved form vm.h.
+
+ * tool/instruction.rb (RubyVM::Instruction#sp_increase_c_expr),
+ tool/instruction.rb (RubyVM::VmBodyGenerator#make_header_operands):
+ omit unused variables.
+
+Fri May 23 08:47:02 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * error.c (exc_equal): == operator should be transitional.
+ [ruby-dev:34808]
+
+ * error.c (syserr_eqq): === should be able to handle delegated
+ objects as well.
+
+Fri May 23 06:15:20 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * iseq.c (rb_iseq_compile_with_option): get rid of segv.
+
+Fri May 23 02:29:14 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * insns.def (opt_gt|ge|lt|le): use values directly to compare.
+
+Fri May 23 01:15:09 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * eval.c, eval_intern.h, include/ruby/intern.h, include/ruby/ruby.h,
+ vm.c, vm_core.h, vm_insnhelper.c: remove pointless "const".
+
+Thu May 22 23:45:17 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * compile.c (get_destination_insn, get_next_insn, get_prev_insn):
+ peephole optimization should not ignore ISEQ_ELEMENT_ADJUST.
+
+Thu May 22 20:20:54 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * marshal.c (check_dump_arg, check_load_arg): check if reentered.
+ [ruby-dev:34802]
+
+Thu May 22 20:14:28 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * iseq.c (iseq_load, iseq_data_to_ary): support
+ ISEQ_TYPE_DEFINED_GUARD.
+
+Thu May 22 19:01:29 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * vm.c (vm_get_ruby_level_cfp): moved from eval_intern.h.
+
+ * vm.c (sdr, nsdr): define methods only if VMDEBUG is defined.
+
+Thu May 22 17:18:35 2008 Tanaka Akira <akr at fsij.org>
+
+ * array.c (rb_ary_compact_bang): fix reallocation size.
+
+Thu May 22 15:20:20 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * eval_intern.h, vm_core.h, include/ruby/intern.h, include/ruby/ruby.h,
+ vm.c: need to add const to prototypes, of course.
+
+Thu May 22 13:24:43 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * eval.c, vm.c, vm_core.h, vm_insnhelper.c: specify "const".
+
+ * vm_opts.h: add a OPT_TOKEN_THREADED_CODE macro.
+
+Thu May 22 12:51:41 2008 Tanaka Akira <akr at fsij.org>
+
+ * insns.def (newhash): fix a variable definition: "const k".
+
+Thu May 22 12:40:54 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * array.c (flatten): check if reentered. [ruby-dev:34798]
+
+Thu May 22 11:39:59 2008 Tanaka Akira <akr at fsij.org>
+
+ * test/ruby/envutil.rb (assert_normal_exit): capture stdout and stderr
+ of the child process.
+
+Thu May 22 08:28:49 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * array.c (flatten): free memo hash table before raising exception.
+ [ruby-dev:34789]
+
+Thu May 22 06:30:10 2008 Hidetoshi NAGAI <nagai at ai.kyutech.ac.jp>
+
+ * array.c (flatten): fix memory leak.
+
+Thu May 22 06:21:34 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * ext/nkf/nkf-utf8/nkf.c (nkf_str_caseeql): added.
+
+ * ext/nkf/nkf-utf8/nkf.c (nkf_enc_find_index): use nkf_str_caseeql.
+
+Thu May 22 05:45:30 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * proc.c (proc_dup): should copy safe_level from src proc
+ properly. a patch from Keita Yamaguchi
+ <keita.yamaguchi at gmail.com>
+
+Thu May 22 02:46:08 2008 Shugo Maeda <shugo at ruby-lang.org>
+
+ * lib/net/imap.rb: do not use Thread#raise. [ruby-dev:34739]
+
+Thu May 22 00:30:06 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_require.rb: new tests for library requiring, to
+ achieve over 90% test coverage of dln.c.
+
+ * test/ruby/test_class.rb: add tests to achieve over 90% test coverage
+ of class.c.
+
+ * test/ruby/test_module.rb: ditto.
+
+Thu May 22 00:15:44 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * insns.def, vm_insnhelper.c: specify "const".
+
+Wed May 21 23:20:21 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * bootstraptest/test_eval.rb: fix syntax.
+
+Wed May 21 17:46:17 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * ext/nkf/nkf-utf8/nkf.c (nkf_enc_find_index):
+ use strcasecmp. [ruby-dev:34787]
+
+Wed May 21 16:48:22 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * array.c (rb_ary_compact_bang): avoid forceful realloc.
+
+Wed May 21 07:42:28 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * string.c (rb_usascii_str_new): use rb_str_new.
+
+ * string.c (rb_enc_str_new): ditto.
+
+ * string.c (rb_usascii_str_new2): use rb_str_new2.
+
+Wed May 21 07:22:01 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * encoding.c, include/ruby/encoding.h
+ (rb_enc_associate, rb_enc_associate_index):
+ returns obj. [ruby-dev:34778]
+
+Wed May 21 04:20:20 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * encoding.c (rb_ascii8bit_encoding): use ENCINDEX_ASCII.
+
+ * encoding.c, include/ruby/encoding.h (rb_ascii8bit_encindex):
+ added.
+
+ * encoding.c (rb_locale_encoding): use rb_usascii_encoding().
+
+Wed May 21 01:45:58 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * test/ruby/test_file_exhaustive.rb (setup): workaround for Windows
+ Vista.
+
+ * test/ruby/envutil.rb (rubyexec): now Open3.open3 is supported on
+ Windows.
+
+ * test/ruby/test_process.rb: use ``||'' instead of ``;'' because
+ cmd.exe not support it.
+
+Wed May 21 01:28:47 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * transcode.c, include/ruby/encodng.h (rb_str_transcode):
+ C API of encoding conversion for Ruby object.
+ VALUE rb_str_transcode(VALUE str, VALUE to).
+
+ * transcode.c (str_encode, str_encode_bang):
+ rename from rb_tr_transcode or rb_str_transcode_bang.
+
+Tue May 20 23:26:05 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * test/ruby/test_array.rb: fix tests for 64bit CPU.
+
+Tue May 20 20:59:56 2008 NARUSE, Yui <naruse at ruby-lang.org>
+
+ * ext/nkf/nkf-utf8/nkf.c (rb_nkf_convert) (nkf_enc_without_bom):
+ reverted. nkf-utf8/nkf.c should be independent of ruby.
+
+ * ext/nkf/nkf.c (options):
+ moved from nkf-utf8/nkf.c.
+ override nkf's original settings for Unicode BOM.
+
+Tue May 20 13:20:51 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * ext/nkf/nkf.c (rb_nkf_convert), ext/nkf/nkf-utf8/nkf.c
+ (nkf_enc_without_bom): BOM is not a part of encodings.
+
+ * ext/nkf/nkf.c (Init_nkf), ext/nkf/nkf-utf8/nkf.c (options):
+ UTF-{16,32} without endian have no sense.
+
+Tue May 20 12:13:50 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * ruby.c (proc_options, process_options): --dump option.
+
+Tue May 20 11:36:06 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * include/ruby/ruby.h (PRI[diouxX]VALUE): printf format for VALUE.
+
+ * gc.c (assign_heap_slot): suppress a warning.
+
+Tue May 20 03:42:43 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * eval.c, vm_insnhelper.c: fix cref in instance_eval
+ and cvar_base search protocol.
+
+ * bootstraptest/test_knownbug.rb, test_eval.rb: move soleved test
+ and add new tests.
+
+ * test/ruby/test_eval.rb: fix tests for spec.
+
+Tue May 20 01:43:44 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * bootstraptest/test_knownbug.rb: fix a test.
+ "block_given?" returns true if "yield" can be used.
+
+Tue May 20 01:07:19 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * parse.y (assignable_gen): when "self = 1" was evalueted, unnecessary
+ error message was output, which might cause null pointer access.
+
+Tue May 20 08:38:56 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * string.c (rb_enc_strlen_cr): need to set ENC_CODERANGE_7BIT if
+ search_nonascii() fails. [ruby-dev:34751]
+
+ * string.c (rb_str_reverse): preserve coderange info if the
+ receiver is 7bit string.
+
+ * string.c (rb_str_reverse_bang): ditto.
+
+ * string.c (rb_str_reverse_bang): should have called
+ single_byte_optimizable before rb_str_modify() that clears
+ coderange info.
+
+ * string.c (tr_trans): handle single bytes more eagerly.
+
+Mon May 19 23:32:12 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * vm.c (invoke_block_from_c): fix call flow.
+
+Mon May 19 23:19:35 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * regexec.c (slow_search): check the case when the length is 1.
+ The behavior of memcmp is undefined if the third argument is 0.
+
+Mon May 19 21:07:48 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * thread_pthread.c (native_thread_apply_priority):
+ fix argument range check. [ruby-dev:33124]
+
+Mon May 19 18:22:35 2008 Akinori MUSHA <knu at iDaemons.org>
+
+ * ext/openssl/ossl_pkcs5.c (ossl_pkcs5_pbkdf2_hmac): Fix the type
+ of md; pointed out by Takahiro Kambe <taca at back-street.net>
+ in [ruby-dev:34748].
+
+Mon May 19 17:23:55 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
+
+ * regparse.c (PINC): use optimized enclen() instead of
+ ONIGENC_MBC_ENC_LEN().
+
+ * regparse.c (PFETCH): ditto.
+
+ * regparse.c (PFETCH): small optimization.
+
+ * regexec.c (slow_search): single byte encoding optimization.
+
+ * regenc.h (enclen): avoid calling function when encoding's
+ min_len == max_len.
+
+ * re.c (rb_reg_regsub): rb_enc_ascget() optimization for single
+ byte encoding.
+
+ * re.c (rb_reg_search): avoid allocating new re_registers if we
+ already have MatchData.
+
+ * re.c (match_init_copy): avoid unnecessary onig_region_free()
+ before onig_region_copy.
+
+ * encoding.c (rb_enc_get_index): remove implicit enc_capable check
+ each time.
+
+ * encoding.c (rb_enc_set_index): ditto.
+
+ * encoding.c (enc_compatible_p): small refactoring.
+
+ * include/ruby/encoding.h (rb_enc_dummy_p): inline
+ rb_enc_dummy_p() and export related code.
+
+Mon May 19 14:32:03 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * version.h: fix strange change by version.h update tool.
+
+Mon May 19 14:18:13 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * bootstraptest/test_knownbug.rb: move solved tests.
+
+ * bootstraptest/test_eval.rb, test_literal.rb, test_syntax.rb,
+ test_thread.rb: ditto.
+
+ * test/ruby/test_m17n.rb, test_proc.rb, test_sprintf.rb,
+ test_string.rb, test/ruby/test_struct.rb: ditto.
+
+Mon May 19 13:23:03 2008 NAKAMURA Usaku <usa at ruby-lang.org>
+
+ * process.c (rb_spawn_internal): set last_status when status == -1
+ because there is no path to set it on win32. this patch is derived
+ from [ruby-core:16787], submitted by Luis Lavena <luislavena at
+ gmail.com>
+
+Mon May 19 11:32:47 2008 Koichi Sasada <ko1 at atdot.net>
+
+ * vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
+ VM value stack frame of block contains cref information.
+ (dfp[-1] points CREF)
+
+ * compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
+ vm_dump.h, vm_core.h: ditto.
+
+ * include/ruby/ruby.h, gc.c: remove T_VALUES because of above
+ changes.
+
+ * bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
+
+Sun May 18 22:26:51 2008 GOTOU Yuuzou <gotoyuzo at notwork.org>
+
+ * lib/webrick/httpservlet/filehandler.rb: should normalize path
+ name in path_info to prevent script disclosure vulnerability on
+ DOSISH filesystems. (fix: CVE-2008-1891)
+ Note: NTFS/FAT filesystem should not be published by the platforms
+ other than Windows. Pathname interpretation (including short
+ filename) is less than perfect.
+
+ * lib/webrick/httpservlet/abstract.rb
+ (WEBrick::HTTPServlet::AbstracServlet#redirect_to_directory_uri):
+ should escape the value of Location: header.
+
+ * lib/webrick/httpservlet/cgi_runner.rb: accept interpreter
+ command line arguments.
+
+Sun May 18 02:54:46 2008 Yusuke Endoh <mame at tsg.ne.jp>
+
+ * pack.c (pack_pack): check errno to detect error of ruby_strtoul.
+
+ * pack.c (pack_unpack): ditto.
+
+ * test/ruby/test_pack.rb: add a test for above.
+
+Sat May 17 23:53:57 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * file.c (file_expand_path): fix for short file name on Cygwin.
+
+Sat May 17 18:03:52 2008 Yuki Sonoda (Yugui) <yugui at yugui.jp>
+
+ * vm.c (Init_VM): removed the definition of Thread#initialize,
+ which is overwritten in Init_Thread and is never used.
+
+Sat May 17 14:01:50 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * array.c (rb_ary_sort_bang): should not free shared pointer, and set
+ shared. [ruby-dev:34732]
+
+Sat May 17 12:34:54 2008 Yuki Sonoda (Yugui) <yugui at yugui.jp>
+
+ * thread_pthread.c (Init_native_thread): Kernel#.sleep used never to
+ sleep on Mac OS X. Reported by arton <artonx AT yahoo.co.jp>.
+
+ * thread_pthread.c (native_sleep): added error checks.
+
+Sat May 17 11:29:11 2008 Nobuyoshi Nakada <nobu at ruby-lang.org>
+
+ * file.c (rb_file_s_extname): first dot is not an extension name.
+
Sat May 17 03:21:29 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
* array.c (rb_ary_sort_bang): stop memory leak. [ruby-dev:34726]
@@ -68,7 +962,7 @@
Thu May 15 12:19:42 2008 Yukihiro Matsumoto <matz at ruby-lang.org>
- * ext/openssl/openssl_missing.c (HMAC_CTX_copy): adopted to
+ * ext/openssl/openssl_missing.c (HMAC_CTX_copy): adopted
prototype change in openssl bundled with newer OpenBSD.
a patch from Takahiro Kambe <taca at back-street.net> in
[ruby-dev:34691].
@@ -165,7 +1059,7 @@
Tue May 13 08:25:31 2008 Tanaka Akira <akr at fsij.org>
- * io.c (rb_f_gets.): re-enable rdoc.
+ * io.c (rb_f_gets): re-enable rdoc.
(rb_f_readline): ditto.
(rb_f_readlines): ditto.
@@ -21629,7 +22523,7 @@
Mon Jul 18 00:43:05 2006 Nobuyoshi Nakada <nobu at ruby-lang.org>
* util.c (ruby_strtod): stop at dot not followed by digits.
- fixed: [ruby-dev:29035]
+ fixed: [ruby-dev:29036]
Tue Jul 18 00:01:27 2006 Nobuyoshi Nakada <nobu at ruby-lang.org>
Modified: MacRuby/trunk/Makefile.in
===================================================================
--- MacRuby/trunk/Makefile.in 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/Makefile.in 2008-06-05 08:11:58 UTC (rev 247)
@@ -42,6 +42,7 @@
cflags = @cflags@
optflags = @optflags@
debugflags = @debugflags@
+warnflags = @warnflags@
XCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) @XCFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
@@ -96,7 +97,7 @@
AS = @AS@
ASFLAGS = @ASFLAGS@
IFCHANGE = $(srcdir)/tool/ifchange
-SET_LC_MESSAGES = LC_MESSAGES=C
+SET_LC_MESSAGES = env LC_MESSAGES=C
OBJEXT = @OBJEXT@
ASMEXT = S
Modified: MacRuby/trunk/README
===================================================================
--- MacRuby/trunk/README 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/README 2008-06-05 08:11:58 UTC (rev 247)
@@ -65,6 +65,10 @@
2. Run ./configure, which will generate config.h and Makefile.
+ Some C compiler flags may be added by default depending on your
+ environment. Specify optflags=.. and warnflags=.. as necessary
+ to override them.
+
3. Edit defines.h if you need. Usually this step will not be needed.
4. Remove comment mark(#) before the module names from ext/Setup (or
Modified: MacRuby/trunk/README.ja
===================================================================
--- MacRuby/trunk/README.ja 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/README.ja 2008-06-05 08:11:58 UTC (rev 247)
@@ -88,6 +88,10 @@
2. configure\xA4\xF2\xBC¹Ԥ\xB7\xA4\xC6Makefile\xA4ʤɤ\xF2\xC0\xB8\xC0\xAE\xA4\xB9\xA4\xEB
+ \xB4Ķ\xAD\xA4ˤ\xE8\xA4äƤϥǥե\xA9\xA5\xEB\xA5Ȥ\xCEC\xA5\xB3\xA5\xF3\xA5ѥ\xA4\xA5\xE9\xCDѥ\xAA\xA5ץ\xB7\xA5\xE7\xA5\xF3\xA4\xAC\xC9դ\xAD
+ \xA4ޤ\xB9\xA1\xA5configure\xA5\xAA\xA5ץ\xB7\xA5\xE7\xA5\xF3\xA4\xC7 optflags=.. warnflags=.. \xC5\xF9
+ \xA4Ǿ\xE5\xBDǤ\xAD\xA4ޤ\xB9\xA1\xA5
+
3. (ɬ\xCDפʤ\xE9\xA4\xD0)defines.h\xA4\xF2\xCAԽ\xB8\xA4\xB9\xA4\xEB
¿ʬ\xA1\xA4ɬ\xCD\xD7̵\xA4\xA4\xA4Ȼפ\xA4\xA4ޤ\xB9\xA1\xA5
Modified: MacRuby/trunk/array.c
===================================================================
--- MacRuby/trunk/array.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/array.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -44,7 +44,6 @@
#if WITH_OBJC
/* TODO optimize this */
struct rb_objc_ary_struct {
- bool named_args;
void *cptr;
};
@@ -66,7 +65,6 @@
if (s == NULL) {
s = xmalloc(sizeof(struct rb_objc_ary_struct));
rb_objc_set_associative_ref((void *)ary, &rb_objc_ary_assoc_key, s);
- s->named_args = false;
s->cptr = NULL;
}
return s;
@@ -93,7 +91,7 @@
rb_ary_modify_check(VALUE ary)
{
long mask;
- mask = rb_objc_flag_get_mask(ary);
+ mask = rb_objc_flag_get_mask((void *)ary);
if (mask == 0) {
bool _CFArrayIsMutable(void *);
if (!_CFArrayIsMutable((void *)ary))
@@ -413,7 +411,7 @@
VALUE size, val;
rb_ary_modify(ary);
- if (rb_scan_args(argc, argv, "02", &size, &val) == 0) {
+ if (argc == 0) {
#if !WITH_OBJC
if (RARRAY_PTR(ary) && !ARY_SHARED_P(ary)) {
free(RARRAY(ary)->ptr);
@@ -425,7 +423,7 @@
}
return ary;
}
-
+ rb_scan_args(argc, argv, "02", &size, &val);
if (argc == 1 && !FIXNUM_P(size)) {
val = rb_check_array_type(size);
if (!NIL_P(val)) {
@@ -452,7 +450,7 @@
rb_warn("block supersedes default value argument");
}
for (i=0; i<len; i++) {
- rb_ary_insert(ary, i, rb_yield(LONG2NUM(i)));
+ rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
#if !WITH_OBJC
RARRAY(ary)->len = i + 1;
#endif
@@ -795,7 +793,6 @@
rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
{
VALUE result;
- long n;
if (argc == 0) {
return rb_ary_shift(ary);
@@ -833,8 +830,6 @@
static VALUE
rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
{
- long len;
-
if (argc == 0) return ary;
rb_ary_modify(ary);
#if WITH_OBJC
@@ -1231,7 +1226,7 @@
i = n = RARRAY_LEN(ary);
- if (rb_scan_args(argc, argv, "01", &val) == 0) {
+ if (argc == 0) {
RETURN_ENUMERATOR(ary, 0, 0);
while (i--) {
if (RTEST(rb_yield(RARRAY_AT(ary, i))))
@@ -1242,6 +1237,7 @@
}
}
else {
+ rb_scan_args(argc, argv, "01", &val);
#if WITH_OBJC
i = CFArrayGetLastIndexOfValue((CFArrayRef)ary, CFRangeMake(0, n),
(const void *)val);
@@ -1586,9 +1582,6 @@
{
#if WITH_OBJC
VALUE dup = rb_ary_dup2(ary);
- /* copy the named_args flag, but not other flags */
- if (rb_ary_is_named_args(ary))
- rb_ary_set_named_args(dup, true);
#else
VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
@@ -1614,7 +1607,7 @@
VALUE
rb_ary_join(VALUE ary, VALUE sep)
{
- long len = 1, i, count;
+ long i, count;
int taint = Qfalse;
VALUE result, tmp;
@@ -1883,18 +1876,39 @@
* a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
*/
+#if WITH_OBJC
+static void
+rb_ary_sort_bang1(VALUE ary, bool is_dup)
+{
+ long n = RARRAY_LEN(ary);
+ if (n > 1) {
+ if (rb_block_given_p()) {
+ VALUE tmp = is_dup ? ary : rb_ary_dup(ary);
+ CFArraySortValues((CFMutableArrayRef)tmp,
+ CFRangeMake(0, n),
+ (CFComparatorFunction)sort_1,
+ NULL);
+ if (!is_dup)
+ rb_ary_replace(ary, tmp);
+ }
+ else {
+ CFArraySortValues((CFMutableArrayRef)ary,
+ CFRangeMake(0, n),
+ (CFComparatorFunction)sort_2,
+ NULL);
+ }
+ }
+}
+#endif
+
VALUE
rb_ary_sort_bang(VALUE ary)
{
- long n = RARRAY_LEN(ary);
rb_ary_modify(ary);
- if (n > 1) {
#if WITH_OBJC
- CFArraySortValues((CFMutableArrayRef)ary,
- CFRangeMake(0, n),
- (CFComparatorFunction)(rb_block_given_p() ? sort_1 : sort_2),
- NULL);
+ rb_ary_sort_bang1(ary, false);
#else
+ if (RARRAY_LEN(ary) > 1) {
VALUE tmp = ary_make_shared(ary);
RBASIC(tmp)->klass = 0;
@@ -1911,8 +1925,8 @@
RARRAY(tmp)->len = 0;
RARRAY(tmp)->aux.capa = 0;
RBASIC(tmp)->klass = RBASIC(ary)->klass;
+ }
#endif
- }
return ary;
}
@@ -1936,7 +1950,7 @@
rb_ary_sort(VALUE ary)
{
ary = rb_ary_dup(ary);
- rb_ary_sort_bang(ary);
+ rb_ary_sort_bang1(ary, true);
return ary;
}
@@ -2221,6 +2235,7 @@
long pos, len;
long alen;
+ rb_ary_modify_check(ary);
alen = RARRAY_LEN(ary);
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
pos = NUM2LONG(arg1);
@@ -2338,6 +2353,7 @@
static VALUE
rb_ary_delete_if(VALUE ary)
{
+ RETURN_ENUMERATOR(ary, 0, 0);
rb_ary_reject_bang(ary);
return ary;
}
@@ -2473,9 +2489,6 @@
VALUE
rb_ary_replace(VALUE copy, VALUE orig)
{
- VALUE shared;
- VALUE *ptr;
-
orig = to_ary(orig);
rb_ary_modify_check(copy);
if (copy == orig) return copy;
@@ -2553,7 +2566,6 @@
{
VALUE item, arg1, arg2;
long beg = 0, end = 0, len = 0, n;
- VALUE *p, *pend;
int block_p = Qfalse;
n = RARRAY_LEN(ary);
@@ -2644,7 +2656,6 @@
rb_ary_plus(VALUE x, VALUE y)
{
VALUE z;
- long len;
#if WITH_OBJC
y = to_ary(y);
@@ -3299,45 +3310,60 @@
/*
* call-seq:
- * array.nitems -> int
- * array.nitems { |item| block } -> int
+ * array.count -> int
+ * array.count(obj) -> int
+ * array.count { |item| block } -> int
*
- * Returns the number of non-<code>nil</code> elements in _self_.
- * If a block is given, the elements yielding a true value are
- * counted.
+ * Returns the number of elements. If an argument is given, counts
+ * the number of elements which equals to <i>obj</i>. If a block is
+ * given, counts the number of elements yielding a true value.
*
- * May be zero.
- *
- * [ 1, nil, 3, nil, 5 ].nitems #=> 3
- * [5,6,7,8,9].nitems { |x| x % 2 != 0 } #=> 3
+ * ary = [1, 2, 4, 2]
+ * ary.count # => 4
+ * ary.count(2) # => 2
+ * ary.count{|x|x%2==0} # => 3
+ *
*/
static VALUE
-rb_ary_nitems(VALUE ary)
+rb_ary_count(int argc, VALUE *argv, VALUE ary)
{
long n = 0;
- if (rb_block_given_p()) {
- long i;
+ if (argc == 0) {
+ long i, count = RARRAY_LEN(ary);
- for (i=0; i<RARRAY_LEN(ary); i++) {
- VALUE v = RARRAY_AT(ary, i);
- if (RTEST(rb_yield(v))) n++;
- }
+ if (!rb_block_given_p())
+ return LONG2NUM(count);
+
+#if WITH_OBJC
+ for (i = 0; i < count; i++) {
+ if (RTEST(rb_yield(RARRAY_AT(ary, i))))
+ n++;
+ }
+#else
+ for (p = RARRAY_PTR(ary), pend = p + RARRAY_LEN(ary); p < pend; p++) {
+ if (RTEST(rb_yield(*p))) n++;
+ }
+#endif
}
else {
+ VALUE obj;
+ long i, count = RARRAY_LEN(ary);
+
+ rb_scan_args(argc, argv, "1", &obj);
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
#if WITH_OBJC
- long total = RARRAY_LEN(ary);
- n = total - CFArrayGetCountOfValue((CFArrayRef)ary,
- CFRangeMake(0, total), (const void *)Qnil);
+ for (i = 0; i < count; i++) {
+ if (rb_equal(RARRAY_AT(ary, i), obj))
+ n++;
+ }
#else
- VALUE *p = RARRAY_PTR(ary);
- VALUE *pend = p + RARRAY_LEN(ary);
-
- while (p < pend) {
- if (!NIL_P(*p)) n++;
- p++;
- }
+ for (p = RARRAY_PTR(ary), pend = p + RARRAY_LEN(ary); p < pend; p++) {
+ if (rb_equal(*p, obj)) n++;
+ }
#endif
}
@@ -3362,6 +3388,11 @@
while (i < RARRAY_LEN(ary)) {
elt = RARRAY_AT(ary, i++);
tmp = rb_check_array_type(elt);
+#if !WITH_OBJC
+ if (RBASIC(result)->klass) {
+ rb_raise(rb_eRuntimeError, "flatten reentered");
+ }
+#endif
if (NIL_P(tmp) || (level >= 0 && RARRAY_LEN(stack) / 2 >= level)) {
rb_ary_push(result, elt);
}
@@ -3369,6 +3400,7 @@
*modified = 1;
id = (st_data_t)tmp;
if (st_lookup(memo, id, 0)) {
+ st_free_table(memo);
rb_raise(rb_eArgError, "tried to flatten recursive array");
}
st_insert(memo, id, (st_data_t)Qtrue);
@@ -3388,6 +3420,11 @@
ary = rb_ary_pop(stack);
}
+ st_free_table(memo);
+
+#if !WITH_OBJC
+ RBASIC(result)->klass = rb_class_of(ary);
+#endif
return result;
}
@@ -3648,8 +3685,8 @@
VALUE num;
long r, n, i;
+ n = RARRAY_LEN(ary); /* Array length */
RETURN_ENUMERATOR(ary, argc, argv); /* Return enumerator if no block */
- n = RARRAY_LEN(ary); /* Array length */
rb_scan_args(argc, argv, "01", &num);
r = NIL_P(num) ? n : NUM2LONG(num); /* Permutation size from argument */
@@ -3735,7 +3772,6 @@
{
long n, i, len;
- RETURN_ENUMERATOR(ary, 1, &num);
n = NUM2LONG(num);
RETURN_ENUMERATOR(ary, 1, &num);
len = RARRAY_LEN(ary);
@@ -4082,18 +4118,6 @@
#undef INSTALL_METHOD
}
-void
-rb_ary_set_named_args(VALUE ary, bool flag)
-{
- rb_objc_ary_get_struct2(ary)->named_args = flag;
-}
-
-bool
-rb_ary_is_named_args(VALUE ary)
-{
- struct rb_objc_ary_struct *s = rb_objc_ary_get_struct(ary);
- return s != NULL && s->named_args;
-}
#endif
/* Arrays are ordered, integer-indexed collections of any object.
@@ -4199,7 +4223,7 @@
rb_define_method(rb_cArray, "compact!", rb_ary_compact_bang, 0);
rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
- rb_define_method(rb_cArray, "nitems", rb_ary_nitems, 0);
+ rb_define_method(rb_cArray, "_count", rb_ary_count, -1);
rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
rb_define_method(rb_cArray, "choice", rb_ary_choice, 0);
Modified: MacRuby/trunk/benchmark/bmx_temp.rb
===================================================================
--- MacRuby/trunk/benchmark/bmx_temp.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/benchmark/bmx_temp.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,9 @@
+def m
+ nil
+end
+
+i=0
+while i<800000 # benchmark loop 2
+ i+=1
+ m; m; m; m; m; m; m; m;
+end
Modified: MacRuby/trunk/bin/gem
===================================================================
--- MacRuby/trunk/bin/gem 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/bin/gem 2008-06-05 08:11:58 UTC (rev 247)
@@ -7,11 +7,12 @@
require 'rubygems'
require 'rubygems/gem_runner'
+require 'rubygems/exceptions'
-required_version = Gem::Requirement.new ">= 1.8.3"
+required_version = Gem::Requirement.new "> 1.8.3"
-unless required_version.satisfied_by? Gem::Version.new(RUBY_VERSION) then
- abort "Expected Ruby Version #{required_version}, was #{RUBY_VERSION}"
+unless required_version.satisfied_by? Gem.ruby_version then
+ abort "Expected Ruby Version #{required_version}, was #{Gem.ruby_version}"
end
# We need to preserve the original ARGV to use for passing gem options
@@ -19,5 +20,9 @@
# it...its for the source building process.
args = !ARGV.include?("--") ? ARGV.clone : ARGV[0...ARGV.index("--")]
-Gem::GemRunner.new.run args
+begin
+ Gem::GemRunner.new.run args
+rescue Gem::SystemExitException => e
+ exit e.exit_code
+end
Modified: MacRuby/trunk/blockinlining.c
===================================================================
--- MacRuby/trunk/blockinlining.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/blockinlining.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,13 +2,16 @@
blockinlining.c -
- $Author: akr $
+ $Author: ko1 $
Copyright (C) 2004-2007 Koichi Sasada
**********************************************************************/
#include "ruby/ruby.h"
+#if WITH_OBJC
+# define process_named_args(x) (x)
+#endif
#include "ruby/node.h"
#include "vm_core.h"
@@ -195,7 +198,7 @@
th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
argv[0] = INT2FIX(0);
argv[1] = num;
- val = vm_yield(th, 2, argv);
+ val = rb_yield_values(2, argv);
if (val == Qundef) {
return num;
}
@@ -314,7 +317,7 @@
th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
argv[0] = beg;
argv[1] = end;
- val = vm_yield(th, 2, argv);
+ val = rb_yield_values(2, argv);
if (val == Qundef) {
return range;
}
@@ -444,7 +447,7 @@
th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
argv[0] = 0;
argv[1] = ary;
- val = vm_yield(th, 2, argv);
+ val = rb_yield_values(2, argv);
if (val == Qundef) {
return ary;
}
Modified: MacRuby/trunk/bootstraptest/test_eval.rb
===================================================================
--- MacRuby/trunk/bootstraptest/test_eval.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/bootstraptest/test_eval.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -208,3 +208,77 @@
end
Foo.add_method
}, '[ruby-core:14556] reported by Frederick Cheung'
+
+assert_equal 'ok', %q{
+ class Module
+ def my_module_eval(&block)
+ module_eval(&block)
+ end
+ end
+ class String
+ Integer.my_module_eval do
+ def hoge; end
+ end
+ end
+ if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) &&
+ !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge)
+ :ok
+ else
+ :ng
+ end
+}, "[ruby-dev:34236]"
+
+assert_equal 'ok', %q{
+ begin
+ eval("class nil::Foo; end")
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+
+assert_equal 'ok', %q{
+ begin
+ 0.instance_eval { def m() :m end }
+ 1.m
+ :ng
+ rescue Exception
+ :ok
+ end
+}, '[ruby-dev:34579]'
+
+assert_equal 'ok', %q{
+ begin
+ 12.instance_eval { @@a }
+ rescue NameError
+ :ok
+ end
+}, '[ruby-core:16794]'
+
+assert_equal 'ok', %q{
+ begin
+ 12.instance_exec { @@a }
+ rescue NameError
+ :ok
+ end
+}, '[ruby-core:16794]'
+
+assert_equal 'ok', %q{
+ begin
+ nil.instance_eval {
+ def a() :a end
+ }
+ rescue TypeError
+ :ok
+ end
+}, '[ruby-core:16796]'
+
+assert_equal 'ok', %q{
+ begin
+ nil.instance_exec {
+ def a() :a end
+ }
+ rescue TypeError
+ :ok
+ end
+}, '[ruby-core:16796]'
Modified: MacRuby/trunk/bootstraptest/test_jump.rb
===================================================================
--- MacRuby/trunk/bootstraptest/test_jump.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/bootstraptest/test_jump.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -248,3 +248,14 @@
end
end
}, "[ruby-dev:31698]"
+
+assert_normal_exit %q{
+ f = 0
+ 1.times do
+ begin
+ f += 1
+ ensure
+ redo unless f > 2
+ end
+ end
+}
Modified: MacRuby/trunk/bootstraptest/test_knownbug.rb
===================================================================
--- MacRuby/trunk/bootstraptest/test_knownbug.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/bootstraptest/test_knownbug.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -7,9 +7,9 @@
class C
define_method(:foo) {
if block_given?
- :ok
- else
:ng
+ else
+ :ok
end
}
end
@@ -30,28 +30,6 @@
}, '[ruby-core:14813]'
assert_equal 'ok', %q{
- class X < RuntimeError;end
- x = [X]
- begin
- raise X
- rescue *x
- :ok
- end
-}, '[ruby-core:14537]'
-
-assert_normal_exit %q{
- "abc".gsub(/./, "a" => "z")
-}
-
-assert_normal_exit %q{
- Encoding.compatible?("",0)
-}
-
-assert_normal_exit %q{
- "".center(1, "\x80".force_encoding("utf-8"))
-}, '[ruby-dev:33807]'
-
-assert_equal 'ok', %q{
a = lambda {|x, y, &b| b }
b = a.curry[1]
if b.call(2){} == nil
@@ -62,10 +40,6 @@
}, '[ruby-core:15551]'
assert_normal_exit %q{
- sprintf("% 0e", 1.0/0.0)
-}
-
-assert_normal_exit %q{
g = Module.enum_for(:new)
loop { g.next }
}, '[ruby-dev:34128]'
@@ -111,134 +85,23 @@
}, "[ ruby-Bugs-19304 ]"
assert_equal 'ok', %q{
- def a() end
- begin
- if defined?(a(1).a)
- :ng
- else
- :ok
- end
- rescue
+ lambda {
+ break :ok
:ng
- end
-}, '[ruby-core:16010]'
+ }.call
+}, '[ruby-dev:34646]'
-assert_equal 'ok', %q{
- def a() end
- begin
- if defined?(a::B)
- :ng
- else
- :ok
- end
- rescue
- :ng
- end
-}, '[ruby-core:16010]'
-
-
-assert_equal 'ok', %q{
- class Module
- def my_module_eval(&block)
- module_eval(&block)
- end
- end
- class String
- Integer.my_module_eval do
- def hoge; end
- end
- end
- if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) &&
- !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge)
- :ok
- else
- :ng
- end
-}, "[ruby-dev:34236]"
-
-assert_equal 'ok', %q{
- def m
- t = Thread.new { while true do // =~ "" end }
- sleep 0.1
- 10.times {
- if /((ab)*(ab)*)*(b)/ =~ "ab"*7
- return :ng if !$4
- return :ng if $~.size != 5
- end
- }
- :ok
- ensure
- Thread.kill t
- end
- m
-}, '[ruby-dev:34492]'
-
assert_normal_exit %q{
- begin
- r = 0**-1
- r + r
- rescue
- end
-}, '[ruby-dev:34524]'
-
-assert_normal_exit %q{
- begin
- r = Marshal.load("\x04\bU:\rRational[\ai\x06i\x05")
- r + r
- rescue
- end
-}, '[ruby-dev:34536]'
-
-assert_normal_exit %q{
- begin
- Struct.new(0)
- rescue
- end
+ eval("", method(:proc).call {}.binding)
}
assert_normal_exit %q{
- defined? C && 0
+ a = []
+ 100.times {|i| a << i << nil << nil }
+ p a.compact!
}
-assert_normal_exit %q{
- class C
- def m
- defined?(super())
- end
- end
- C.new.m
-}
-
-assert_normal_exit %q{
- [1,2,3].slice!(1,10000).inspect
-}
-
assert_equal 'ok', %q{
- begin
- eval("class nil::Foo; end")
- :ng
- rescue Exception
- :ok
- end
-}
-
-assert_normal_exit %q{
- at_exit { Fiber.new{}.resume }
-}
-
-assert_equal 'ok', %q{
- lambda {
- break :ok
- :ng
- }.call
-}, '[ruby-dev:34646]'
-
-assert_equal 'ok', %q{
- begin
- 0.instance_eval { def m() :m end }
- 1.m
- :ng
- rescue Exception
- :ok
- end
-}, '[ruby-dev:34579]'
+ a = [false]
+ (a[0] &&= true) == false ? :ok : :ng
+}, '[ruby-dev:34679]'
Modified: MacRuby/trunk/bootstraptest/test_literal.rb
===================================================================
--- MacRuby/trunk/bootstraptest/test_literal.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/bootstraptest/test_literal.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -176,3 +176,19 @@
ObjectSpace.each_object(Module) {|m| m.name.inspect }
:ok
}
+
+assert_normal_exit %q{
+ begin
+ r = 0**-1
+ r + r
+ rescue
+ end
+}, '[ruby-dev:34524]'
+
+assert_normal_exit %q{
+ begin
+ r = Marshal.load("\x04\bU:\rRational[\ai\x06i\x05")
+ r + r
+ rescue
+ end
+}, '[ruby-dev:34536]'
Modified: MacRuby/trunk/bootstraptest/test_syntax.rb
===================================================================
--- MacRuby/trunk/bootstraptest/test_syntax.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/bootstraptest/test_syntax.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -767,3 +767,53 @@
}
assert_valid_syntax('1.times {|i|print (42),1;}', '[ruby-list:44479]')
+
+assert_equal 'ok', %q{
+ def a() end
+ begin
+ if defined?(a(1).a)
+ :ng
+ else
+ :ok
+ end
+ rescue
+ :ng
+ end
+}, '[ruby-core:16010]'
+
+assert_equal 'ok', %q{
+ def a() end
+ begin
+ if defined?(a::B)
+ :ng
+ else
+ :ok
+ end
+ rescue
+ :ng
+ end
+}, '[ruby-core:16010]'
+
+assert_normal_exit %q{
+ defined? C && 0
+}
+
+assert_normal_exit %q{
+ class C
+ def m
+ defined?(super())
+ end
+ end
+ C.new.m
+}
+
+assert_equal 'ok', %q{
+ class X < RuntimeError;end
+ x = [X]
+ begin
+ raise X
+ rescue *x
+ :ok
+ end
+}, '[ruby-core:14537]'
+
Modified: MacRuby/trunk/bootstraptest/test_thread.rb
===================================================================
--- MacRuby/trunk/bootstraptest/test_thread.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/bootstraptest/test_thread.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -246,3 +246,25 @@
t.join
}
}
+
+assert_equal 'ok', %q{
+ def m
+ t = Thread.new { while true do // =~ "" end }
+ sleep 0.1
+ 10.times {
+ if /((ab)*(ab)*)*(b)/ =~ "ab"*7
+ return :ng if !$4
+ return :ng if $~.size != 5
+ end
+ }
+ :ok
+ ensure
+ Thread.kill t
+ end
+ m
+}, '[ruby-dev:34492]'
+
+assert_normal_exit %q{
+ at_exit { Fiber.new{}.resume }
+}
+
Modified: MacRuby/trunk/bs.c
===================================================================
--- MacRuby/trunk/bs.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/bs.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -26,7 +26,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "bs_lex.h"
#include "bs.h"
#include <libxml/xmlreader.h>
@@ -34,6 +33,8 @@
#include <libgen.h>
#include <unistd.h>
+#include "bs_lex.h"
+
#define ASSERT_ALLOC(ptr) (assert(ptr != NULL))
static inline char *
@@ -369,7 +370,7 @@
unsigned int i;
#define MAX_ARGS 128
bs_element_arg_t args[MAX_ARGS];
- char *protocol_name;
+ char *protocol_name = NULL;
int func_ptr_arg_depth;
bs_element_function_pointer_t *func_ptr;
bool success;
@@ -436,10 +437,10 @@
const char *name;
unsigned int namelen;
int node_type = -1;
- bool eof;
+ bool eof = false;
struct bs_xml_atom *atom;
void *bs_element;
- bs_element_type_t bs_element_type;
+ bs_element_type_t bs_element_type = 0;
do {
int retval = xmlTextReaderRead(reader);
Modified: MacRuby/trunk/class.c
===================================================================
--- MacRuby/trunk/class.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/class.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -134,7 +134,6 @@
{
VALUE obj;
Class ocklass, ocsuper;
- size_t size;
char ocname[128];
if (name == NULL) {
@@ -146,7 +145,7 @@
long count = 1;
snprintf(ocname, sizeof ocname, "RB%s", name);
while (objc_getClass(ocname) != NULL)
- snprintf(ocname, sizeof ocname, "RB%s%d", name, ++count);
+ snprintf(ocname, sizeof ocname, "RB%s%ld", name, ++count);
rb_warning("can't create `%s' as an Objective-C class, because " \
"it already exists, instead using `%s'", name, ocname);
}
@@ -168,7 +167,7 @@
RBASIC(obj)->isa = ocklass->isa;
RCLASS(obj)->ocklass = ocklass;
- rb_objc_retain(obj); /* classes should never be released */
+ rb_objc_retain((const void *)obj); /* classes should never be released */
if (name == NULL)
FL_SET(obj, RCLASS_ANONYMOUS);
@@ -454,7 +453,7 @@
NEWOBJ(obj2, struct RClass);
OBJSETUP(obj2, rb_cClass, T_CLASS);
klass = (VALUE)obj2;
- rb_objc_retain(klass);
+ rb_objc_retain((const void *)klass);
class_init(klass);
OBJ_INFECT(klass, super);
RCLASS_SUPER(klass) = super;
Modified: MacRuby/trunk/common.mk
===================================================================
--- MacRuby/trunk/common.mk 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/common.mk 2008-06-05 08:11:58 UTC (rev 247)
@@ -110,9 +110,11 @@
BOOTSTRAPRUBY = $(BASERUBY)
+COMPILE_PRELUDE = $(MINIRUBY) -I$(srcdir) -rrbconfig $(srcdir)/tool/compile_prelude.rb
+
VCS = svn
-all: $(MKFILES) $(PREP) incs $(RBCONFIG) $(LIBRUBY) encs
+all: $(MKFILES) incs $(PREP) $(RBCONFIG) $(LIBRUBY) encs
@$(MINIRUBY) $(srcdir)/ext/extmk.rb --make="$(MAKE)" $(EXTMK_ARGS)
prog: $(PROGRAM) $(WPROGRAM)
@@ -373,12 +375,12 @@
-install_name=$(RUBY_INSTALL_NAME) \
-so_name=$(RUBY_SO_NAME) rbconfig.rb
-encs: enc.mk
+encs: enc.mk $(LIBRUBY)
$(MINIRUBY) -run -e mkdir -- -p "$(EXTOUT)/$(arch)/enc/trans" enc/trans
$(MAKE) -f enc.mk $(MFLAGS)
enc.mk: $(srcdir)/enc/make_encmake.rb $(srcdir)/enc/Makefile.in $(srcdir)/enc/depend \
- $(srcdir)/lib/mkmf.rb $(RBCONFIG)
+ $(srcdir)/lib/mkmf.rb $(PREP)
$(MINIRUBY) $(srcdir)/enc/make_encmake.rb --builtin-encs="$(BUILTIN_ENCOBJS)" $@
.PRECIOUS: $(MKFILES)
@@ -471,7 +473,7 @@
{$(VPATH)}util.h {$(VPATH)}signal.h {$(VPATH)}vm_core.h \
{$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \
{$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}dln.h \
- {$(VPATH)}eval_error.c {$(VPATH)}eval_method.c {$(VPATH)}eval_safe.c \
+ {$(VPATH)}eval_error.c {$(VPATH)}eval_safe.c \
{$(VPATH)}eval_jump.c
load.$(OBJEXT): {$(VPATH)}load.c {$(VPATH)}eval_intern.h \
{$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}defines.h \
@@ -616,7 +618,7 @@
{$(VPATH)}eval_intern.h {$(VPATH)}util.h {$(VPATH)}dln.h
time.$(OBJEXT): {$(VPATH)}time.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
{$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
- {$(VPATH)}st.h
+ {$(VPATH)}st.h {$(VPATH)}encoding.h
util.$(OBJEXT): {$(VPATH)}util.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
{$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
{$(VPATH)}st.h {$(VPATH)}util.h
@@ -648,7 +650,8 @@
{$(VPATH)}vm_core.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \
{$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}dln.h {$(VPATH)}vm.h \
{$(VPATH)}vm_insnhelper.c {$(VPATH)}insns.inc {$(VPATH)}vm_evalbody.c \
- {$(VPATH)}vmtc.inc {$(VPATH)}vm.inc {$(VPATH)}insns.def
+ {$(VPATH)}vmtc.inc {$(VPATH)}vm.inc {$(VPATH)}insns.def \
+ {$(VPATH)}vm_method.c {$(VPATH)}vm_eval.c
vm_dump.$(OBJEXT): {$(VPATH)}vm_dump.c {$(VPATH)}ruby.h \
{$(VPATH)}config.h {$(VPATH)}defines.h {$(VPATH)}missing.h \
{$(VPATH)}intern.h {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}vm_core.h \
@@ -746,14 +749,11 @@
miniprelude.c: $(srcdir)/tool/compile_prelude.rb $(srcdir)/prelude.rb
$(BASERUBY) -I$(srcdir) $(srcdir)/tool/compile_prelude.rb $(srcdir)/prelude.rb $@
-prelude.c: $(srcdir)/tool/compile_prelude.rb $(PRELUDE_SCRIPTS) $(RBCONFIG) $(PREP)
- $(MINIRUBY) -I$(srcdir) -rrbconfig $(srcdir)/tool/compile_prelude.rb \
- $(PRELUDE_SCRIPTS) $@.new
- $(IFCHANGE) "$@" "$@.new"
+prelude.c: $(srcdir)/tool/compile_prelude.rb $(PRELUDE_SCRIPTS) $(PREP)
+ $(COMPILE_PRELUDE) $(PRELUDE_SCRIPTS) $@
golf_prelude.c: $(srcdir)/tool/compile_prelude.rb $(srcdir)/prelude.rb $(srcdir)/golf_prelude.rb $(PREP)
- $(MINIRUBY) -I$(srcdir) -rrbconfig $(srcdir)/tool/compile_prelude.rb $(srcdir)/golf_prelude.rb $@.new
- $(IFCHANGE) "$@" "$@.new"
+ $(COMPILE_PRELUDE) $(srcdir)/golf_prelude.rb $@
prereq: incs srcs preludes
Modified: MacRuby/trunk/compile.c
===================================================================
--- MacRuby/trunk/compile.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/compile.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
compile.c - ruby node tree -> VM instruction sequence
- $Author: ko1 $
+ $Author: nobu $
created at: 04/01/01 03:42:15 JST
Copyright (C) 2004-2007 Koichi Sasada
@@ -26,12 +26,8 @@
#define va_init_list(a,b) va_start(a)
#endif
-/* iseq.c */
VALUE iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt);
-/* vm.c */
-VALUE vm_eval(void *);
-
/* types */
typedef struct iseq_link_element {
@@ -138,7 +134,7 @@
*/
static void
-verify_list(ISEQ_ARG_DECLARE char *info, LINK_ANCHOR *anchor)
+verify_list(ISEQ_ARG_DECLARE const char *info, LINK_ANCHOR *anchor)
{
#if CPDEBUG
int flag = 0;
@@ -277,6 +273,7 @@
COMPILE_POPED(ret, "ensure", node);
break;
case ISEQ_TYPE_DEFINED_GUARD:
+ iseq_set_local_table(iseq, 0);
COMPILE(ret, "defined guard", node);
break;
default:
@@ -285,7 +282,7 @@
}
if (iseq->type == ISEQ_TYPE_RESCUE || iseq->type == ISEQ_TYPE_ENSURE) {
- ADD_INSN2(ret, 0, getdynamic, INT2FIX(1), INT2FIX(0));
+ ADD_INSN2(ret, 0, getdynamic, INT2FIX(2), INT2FIX(0));
ADD_INSN1(ret, 0, throw, INT2FIX(0) /* continue throw */ );
}
else {
@@ -299,12 +296,11 @@
iseq_translate_threaded_code(rb_iseq_t *iseq)
{
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
-
+ extern const void **vm_get_insns_address_table(void);
#if OPT_DIRECT_THREADED_CODE
- const void *const *table = (const void **)vm_eval(0);
+ const void * const *table = vm_get_insns_address_table();
#else
- extern const void *const *get_insns_address_table();
- const void *const *table = get_insns_address_table();
+ const void * const *table = vm_get_insns_address_table();
#endif
int i;
@@ -776,7 +772,8 @@
id_dollar_bang = rb_intern("#$!");
}
iseq->local_table = (ID *)ALLOC_N(ID *, 1);
- iseq->local_table_size = iseq->local_size = 1;
+ iseq->local_table_size = 1;
+ iseq->local_size = iseq->local_table_size + 1;
iseq->local_table[0] = id_dollar_bang;
return COMPILE_OK;
}
@@ -1002,13 +999,15 @@
}
iseq->local_size = iseq->local_table_size = size;
+ iseq->local_size += 1;
+ /*
+ if (lfp == dfp ) { // top, class, method
+ dfp[-1]: svar
+ else { // block
+ dfp[-1]: cref
+ }
+ */
- if (iseq->type == ISEQ_TYPE_METHOD ||
- iseq->type == ISEQ_TYPE_CLASS ||
- iseq->type == ISEQ_TYPE_TOP) {
- iseq->local_size += 1 /* svar */;
- }
-
debugs("iseq_set_local_table: %d, %d\n", iseq->local_size, iseq->local_table_size);
return COMPILE_OK;
}
@@ -1368,7 +1367,7 @@
list = lobj->link.next;
while (list) {
- if (list->type == ISEQ_ELEMENT_INSN) {
+ if (list->type == ISEQ_ELEMENT_INSN || list->type == ISEQ_ELEMENT_ADJUST) {
break;
}
list = list->next;
@@ -1382,7 +1381,7 @@
LINK_ELEMENT *list = iobj->link.next;
while (list) {
- if (list->type == ISEQ_ELEMENT_INSN) {
+ if (list->type == ISEQ_ELEMENT_INSN || list->type == ISEQ_ELEMENT_ADJUST) {
return list;
}
list = list->next;
@@ -1396,7 +1395,7 @@
LINK_ELEMENT *list = iobj->link.prev;
while (list) {
- if (list->type == ISEQ_ELEMENT_INSN) {
+ if (list->type == ISEQ_ELEMENT_INSN || list->type == ISEQ_ELEMENT_ADJUST) {
return list;
}
list = list->prev;
@@ -2026,20 +2025,11 @@
}
iseq_add_mark_object_compile_time(iseq, ary);
-#if WITH_OBJC
- if (node_root->flags & NODE_ARRAY_NAMED_ARGS)
- rb_ary_set_named_args(ary, true);
-#endif
ADD_INSN1(ret, nd_line(node_root), duparray, ary);
}
}
else {
if (!poped) {
-#if WITH_OBJC
- if (node_root->flags & NODE_ARRAY_NAMED_ARGS)
- ADD_INSN1(anchor, line, newarray_named_args, INT2FIX(len));
- else
-#endif
ADD_INSN1(anchor, line, newarray, INT2FIX(len));
}
APPEND_LIST(ret, anchor);
@@ -2322,7 +2312,7 @@
defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
NODE *node, LABEL **lfinish, VALUE needstr)
{
- char *estr = 0;
+ const char *estr = 0;
enum node_type type;
switch (type = nd_type(node)) {
@@ -2347,18 +2337,10 @@
do {
defined_expr(iseq, ret, vals->nd_head, lfinish, Qfalse);
- if (lfinish[1]) {
- ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
- }
- else {
- LABEL *lcont = NEW_LABEL(nd_line(node));
+ if (!lfinish[1]) {
lfinish[1] = NEW_LABEL(nd_line(node));
- ADD_INSNL(ret, nd_line(node), branchif, lcont);
- ADD_LABEL(ret, lfinish[1]);
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSNL(ret, nd_line(node), jump, lfinish[0]);
- ADD_LABEL(ret, lcont);
}
+ ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
} while ((vals = vals->nd_next) != NULL);
}
case NODE_STR:
@@ -2950,12 +2932,24 @@
LABEL *break_label = iseq->compile_data->end_label = NEW_LABEL(nd_line(node)); /* break */
LABEL *end_label = NEW_LABEL(nd_line(node));
+ LABEL *next_catch_label = NEW_LABEL(nd_line(node));
+ LABEL *tmp_label = NULL;
+
iseq->compile_data->loopval_popped = 0;
iseq->compile_data->ensure_node_stack = 0;
if (type == NODE_OPT_N || node->nd_state == 1) {
ADD_INSNL(ret, nd_line(node), jump, next_label);
}
+ else {
+ tmp_label = NEW_LABEL(nd_line(node));
+ ADD_INSNL(ret, nd_line(node), jump, tmp_label);
+ }
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_LABEL(ret, next_catch_label);
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSNL(ret, nd_line(node), jump, next_label);
+ if (tmp_label) ADD_LABEL(ret, tmp_label);
ADD_LABEL(ret, redo_label);
COMPILE_POPED(ret, "while body", node->nd_body);
@@ -2987,7 +2981,7 @@
ADD_INSN(ret, nd_line(node), putnil);
}
- ADD_LABEL(ret, break_label); /* braek */
+ ADD_LABEL(ret, break_label); /* break */
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
@@ -2995,8 +2989,8 @@
ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label,
0, break_label);
- ADD_CATCH_ENTRY(CATCH_TYPE_NEXT | 0x10000, redo_label,
- break_label, 0, iseq->compile_data->start_label);
+ ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, redo_label, break_label, 0,
+ next_catch_label);
ADD_CATCH_ENTRY(CATCH_TYPE_REDO, redo_label, break_label, 0,
iseq->compile_data->redo_label);
@@ -3134,13 +3128,12 @@
rb_iseq_t *ip;
ip = iseq;
while (ip) {
- level = 0x8000;
+ level = 0x8000 | 0x4000;
if (ip->compile_data->redo_label != 0) {
/* while loop */
break;
}
else if (ip->type == ISEQ_TYPE_BLOCK) {
- level |= 0x4000;
break;
}
else if (ip->type == ISEQ_TYPE_EVAL) {
@@ -3282,8 +3275,7 @@
case NODE_ARRAY:
while (narg) {
COMPILE(ret, "rescue arg", narg->nd_head);
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
ADD_INSNL(ret, nd_line(node), branchif, label_hit);
narg = narg->nd_next;
@@ -3292,8 +3284,7 @@
case NODE_SPLAT:
case NODE_ARGSCAT:
case NODE_ARGSPUSH:
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
COMPILE(ret, "rescue/cond splat", narg);
ADD_INSN1(ret, nd_line(node), checkincludearray, Qtrue);
ADD_INSN(ret, nd_line(node), swap);
@@ -3308,8 +3299,7 @@
else {
ADD_INSN1(ret, nd_line(node), putobject,
rb_eStandardError);
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
ADD_INSNL(ret, nd_line(node), branchif, label_hit);
}
@@ -4030,8 +4020,7 @@
if (idx < 0) {
rb_bug("unknown dvar (%s)", rb_id2name(node->nd_vid));
}
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx),
- INT2FIX(lv));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx), INT2FIX(lv));
}
break;
}
@@ -4503,8 +4492,7 @@
case NODE_ERRINFO:{
if (!poped) {
if (iseq->type == ISEQ_TYPE_RESCUE) {
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
}
else {
rb_iseq_t *ip = iseq;
@@ -4517,8 +4505,7 @@
level++;
}
if (ip) {
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(level));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(level));
}
else {
ADD_INSN(ret, nd_line(node), putnil);
@@ -4970,6 +4957,7 @@
{
int i;
op = rb_convert_type(op, T_ARRAY, "Array", "to_ary");
+ op = rb_ary_dup(op);
for (i=0; i<RARRAY_LEN(op); i+=2) {
VALUE sym = rb_ary_entry(op, i+1);
LABEL *label =
Modified: MacRuby/trunk/configure.in
===================================================================
--- MacRuby/trunk/configure.in 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/configure.in 2008-06-05 08:11:58 UTC (rev 247)
@@ -180,14 +180,17 @@
dnl Checks for programs.
+: ${CFLAGS=} ${CXXFLAGS=}
if test x"${build}" != x"${host}"; then
AC_CHECK_TOOL(CC, gcc)
fi
AC_PROG_CC
AC_PROG_CXX
AC_PROG_GCC_TRADITIONAL
+test $ac_cv_prog_cc_g = yes && : ${debugflags=-g}
if test "$GCC" = yes; then
linker_flag=-Wl,
+ : ${optflags=-O2} ${warnflags="-Wall -Wno-parentheses"}
else
linker_flag=
fi
@@ -1630,7 +1633,7 @@
;;
darwin*)
LIBRUBY_SO='lib$(RUBY_SO_NAME).$(MAJOR).$(MINOR).$(TEENY).dylib'
- LIBRUBY_LDSHARED='$(CC) -dynamiclib -undefined suppress -flat_namespace'
+ LIBRUBY_LDSHARED='cc -dynamiclib -undefined suppress -flat_namespace'
LIBRUBY_DLDFLAGS='-install_name $(libdir)/lib$(RUBY_SO_NAME).dylib -current_version $(MAJOR).$(MINOR).$(TEENY) -compatibility_version $(MAJOR).$(MINOR)'
LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).$(MAJOR).$(MINOR).dylib lib$(RUBY_SO_NAME).dylib'
;;
@@ -1771,9 +1774,10 @@
test -z "$CFLAGS" || CFLAGS="$CFLAGS "; CFLAGS="$CFLAGS"'${cflags}'
test -z "$CPPFLAGS" || CPPFLAGS="$CPPFLAGS "; CPPFLAGS="$CPPFLAGS"'${cppflags}'
AC_SUBST(cppflags, [])dnl
-AC_SUBST(cflags, ['${optflags} ${debugflags}'])dnl
+AC_SUBST(cflags, ['${optflags} ${debugflags} ${warnflags}'])dnl
AC_SUBST(optflags)dnl
AC_SUBST(debugflags)dnl
+AC_SUBST(warnflags)dnl
AC_SUBST(XCFLAGS)dnl
AC_SUBST(XLDFLAGS)dnl
AC_SUBST(LIBRUBY_LDSHARED)
@@ -1819,15 +1823,7 @@
rubyw_install_name="$RUBYW_INSTALL_NAME"
;;
esac
-case "$target_os" in
- cygwin*|mingw*|*djgpp*|os2-emx*)
- RUBY_LIB_PREFIX="/lib/ruby"
- ;;
- *)
- RUBY_LIB_PREFIX="${prefix}/lib/ruby"
- ;;
-esac
-RUBY_LIB_PATH="${RUBY_LIB_PREFIX}/${MAJOR}.${MINOR}.${TEENY}"
+RUBY_LIB_PREFIX=`eval echo \\"${libdir}/ruby\\"`
AC_ARG_WITH(sitedir,
[ --with-sitedir=DIR site libraries in DIR [PREFIX/lib/ruby/site_ruby]],
Modified: MacRuby/trunk/cont.c
===================================================================
--- MacRuby/trunk/cont.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/cont.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -108,10 +108,10 @@
static void
cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
{
+#if !WITH_OBJC
int size;
rb_thread_t *sth = &cont->saved_thread;
-#if !WITH_OBJC
SET_MACHINE_STACK_END(&th->machine_stack_end);
#ifdef __ia64
th->machine_register_stack_end = rb_ia64_bsp();
Modified: MacRuby/trunk/dir.c
===================================================================
--- MacRuby/trunk/dir.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/dir.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -460,7 +460,7 @@
Data_Get_Struct(dir, struct dir_data, dirp);
if (dirp->path) {
- char *c = rb_obj_classname(dir);
+ const char *c = rb_obj_classname(dir);
int len = strlen(c) + strlen(dirp->path) + 4;
VALUE s = rb_str_new(0, len);
snprintf(RSTRING_PTR(s), len+1, "#<%s:%s>", c, dirp->path);
@@ -715,7 +715,7 @@
chdir_thread = Qnil;
dir_chdir(args->old_path);
}
- rb_objc_release(args->old_path);
+ rb_objc_release((const void *)args->old_path);
return Qnil;
}
@@ -786,7 +786,7 @@
char *cwd = my_getcwd();
args.old_path = rb_tainted_str_new2(cwd); xfree(cwd);
- rb_objc_retain(args.old_path);
+ rb_objc_retain((const void *)args.old_path);
args.new_path = path;
args.done = Qfalse;
return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
@@ -1690,7 +1690,7 @@
ary = rb_push_glob(str, flags);
}
else {
- VALUE v = ary;
+ volatile VALUE v = ary;
ary = dir_globs(RARRAY_LEN(v), RARRAY_PTR(v), flags);
}
Modified: MacRuby/trunk/doc/NEWS
===================================================================
--- MacRuby/trunk/doc/NEWS 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/doc/NEWS 2008-06-05 08:11:58 UTC (rev 247)
@@ -7,6 +7,8 @@
o Block arguments
o New semantics for block arguments
o Block local variables
+ * Array
+ o Array#nitems was removed (use count {|i| !i.nil?})
* String
o No longer an Enumerable
o ?c semantics
@@ -33,7 +35,6 @@
o SecurityError
o Removed Exception#to_str [Ruby2]
* Array
- o Array#nitems
o Array#[m,n] = nil places nil in the array.
* Hash
o Hash#to_s is equivalent to Hash#inspect
@@ -49,12 +50,9 @@
o Dir.exist?
* IO operations
o Non-blocking IO
- o IO#getbyte, IO#readbyte, StringIO#getbyte, StringIO#readbyte
o Kernel#open takes encoding specified
o IO#initialize now accepts an IO argument
o StringIO#readpartial
- o IO#lines
- o IO#bytes
o IO.try_convert
o Limit input in IO#gets, IO#readline, IO#readlines, IO#each_line, IO#lines, IO.foreach, IO.readlines, StringIO#gets, StringIO#readline, StringIO#each, StringIO#readlines
o IO#ungetc, StringIO#ungetc
@@ -89,9 +87,7 @@
o Newlines allowed before ternary colon
* Kernel and Object
o BasicObject
- o #instance_exec
o Object#=~
- o Object#tap
o Kernel#instance_variable_defined?
o Kernel#define_singleton_method
o Kernel#singleton_methods, Kernel#methods
@@ -100,7 +96,6 @@
o Module#class_variable_defined?
o #class_variable_{set,get}
o Class of singleton classes
- o #module_exec
* Binding#eval
* Blocks and Procs
o Arity of blocks without arguments
@@ -110,48 +105,18 @@
o Passing blocks to #[]
o Proc#lambda?
* Enumerable and Enumerator
- o Enumerable methods called without a block
- o Enumerable#cycle
- o Enumerable#each_with_index
- o Enumerable#first(n)
- o Enumerable#group_by
- o Enumerable#find_index
- o Enumerable#take
- o Enumerable#drop
- o Enumerable#take_while
- o Enumerable#drop_while
- o Enumerator#each
- o Enumerable#inject (#reduce) without a block
- o Enumerable#count
- o Enumerable#reduce
- o Enumerator#with_index
- o Enumerable##min_by, #max_by
- o Enumerable#zip
- o Enumerable#minmax and minmax_by
- o Enumerator#rewind
- o Enumerator#next
+ o Enumerable#map,collect_all called without a block returns
+ an enumerator.
* Regexp#match, String#match
o Regexp#match, String#match
* Fiber: coroutines/micro-threads
* Array
- o Block argument to Array#index, Array#rindex [Ruby2]
- o Array#combination
- o Array#permutation
- o Array#product
- o Array#pop, Array#shift
o Array#to_s is equivalent to Array#inspect
o Array.try_convert
* Hash
o preserving item insertion order
o Hash#_compare_by_identity and Hash#compare_by_identity?
o Hash.try_convert
- * Integer
- o Integer#odd?, #even?
- o Integer#pred
- * Method
- o Method#receiver
- o Method#name
- o Method#owner
* Numeric
o Numeric#upto, #downto, #times, #step
o Numeric#scalar?, Complex#scalar?
@@ -166,17 +131,11 @@
o Regexp.try_convert
* String
o String#clear
- o String#each_char
o String#ord
- o String#partition, #rpartition
- o String#lines
- o String#bytes
o String#encoding
o String#force_encoding
- o String#start_with?, #end_with?
o String#unpack with a block
o String#hash
- o String#upto
o String.try_convert
o String.encoding, String#force_encoding, String#encode
* Symbol
@@ -190,16 +149,13 @@
* File and Dir operations
o New methods
* Process
- o Process.setrlimit
o Process.daemon
- o Process.exec
* Misc. new methods
o public_send
- o GC.stress, GC.stress=, GC.count
+ o GC.count
o ObjectSpace.count_objects
o Method#hash, Proc#hash
- o __method__ and __callee__
- o Symbol#to_proc
+ o __callee__
* Implementation
* Memory Diet
Modified: MacRuby/trunk/encoding.c
===================================================================
--- MacRuby/trunk/encoding.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/encoding.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -18,7 +18,7 @@
#endif
static ID id_encoding, id_base_encoding;
-static VALUE rb_cEncoding;
+VALUE rb_cEncoding;
#if WITH_OBJC
@@ -416,17 +416,6 @@
}
#endif // WITH_OBJC
-int
-rb_enc_dummy_p(rb_encoding *enc)
-{
-#if WITH_OBJC
- return Qfalse;
-#else
- VALUE encoding = rb_enc_from_encoding(enc);
- return ENC_DUMMY_P(encoding);
-#endif
-}
-
/*
* call-seq:
* enc.dummy? => true or false
Modified: MacRuby/trunk/enum.c
===================================================================
--- MacRuby/trunk/enum.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/enum.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
enum.c -
- $Author: nobu $
+ $Author: knu $
created at: Fri Oct 1 15:15:19 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -14,7 +14,7 @@
#include "ruby/util.h"
VALUE rb_mEnumerable;
-static ID id_each, id_eqq, id_cmp, id_next;
+static ID id_each, id_eqq, id_cmp, id_next, id_size;
static VALUE
enum_values_pack(int argc, VALUE *argv)
@@ -108,15 +108,29 @@
return Qnil;
}
+static VALUE
+count_all_i(VALUE i, VALUE memop, int argc, VALUE *argv)
+{
+ VALUE *memo = (VALUE*)memop;
+
+ memo[0]++;
+ return Qnil;
+}
+
/*
* call-seq:
+ * enum.count => int
* enum.count(item) => int
* enum.count {| obj | block } => int
*
- * Returns the number of items in <i>enum</i> for which equals to <i>item</i>.
- * If a block is given, counts the number of elements yielding a true value.
+ * Returns the number of items in <i>enum</i>, where #size is called
+ * if it responds to it, otherwise the items are counted through
+ * enumeration. If an argument is given, counts the number of items
+ * in <i>enum</i>, for which equals to <i>item</i>. If a block is
+ * given, counts the number of elements yielding a true value.
*
* ary = [1, 2, 4, 2]
+ * ary.count # => 4
* ary.count(2) # => 2
* ary.count{|x|x%2==0} # => 3
*
@@ -129,8 +143,15 @@
rb_block_call_func *func;
if (argc == 0) {
- RETURN_ENUMERATOR(obj, 0, 0);
- func = count_iter_i;
+ if (rb_block_given_p()) {
+ func = count_iter_i;
+ }
+ else {
+ if (rb_respond_to(obj, id_size)) {
+ return rb_funcall(obj, id_size, 0, 0);
+ }
+ func = count_all_i;
+ }
}
else {
rb_scan_args(argc, argv, "1", &memo[1]);
@@ -383,11 +404,11 @@
* { 'a'=>1, 'b'=>2, 'c'=>3 }.to_a #=> [["a", 1], ["b", 2], ["c", 3]]
*/
static VALUE
-enum_to_a(VALUE obj)
+enum_to_a(int argc, VALUE *argv, VALUE obj)
{
VALUE ary = rb_ary_new();
- rb_block_call(obj, id_each, 0, 0, collect_all, ary);
+ rb_block_call(obj, id_each, argc, argv, collect_all, ary);
return ary;
}
@@ -657,7 +678,7 @@
static VALUE
enum_sort(VALUE obj)
{
- return rb_ary_sort(enum_to_a(obj));
+ return rb_ary_sort(enum_to_a(0, 0, obj));
}
static VALUE
@@ -685,10 +706,8 @@
#else
VALUE a = (*(NODE *const *)ap)->u1.value;
VALUE b = (*(NODE *const *)bp)->u1.value;
-#endif
VALUE ary = (VALUE)data;
-
-#if !WITH_OBJC
+
if (RBASIC(ary)->klass) {
rb_raise(rb_eRuntimeError, "sort_by reentered");
}
@@ -1424,7 +1443,32 @@
}
+/*
+ * call-seq:
+ * enum.reverse_each {|item| block }
+ *
+ * Traverses <i>enum</i> in reverse order.
+ */
+
static VALUE
+enum_reverse_each(int argc, VALUE *argv, VALUE obj)
+{
+ VALUE ary;
+ long i;
+
+ RETURN_ENUMERATOR(obj, argc, argv);
+
+ ary = enum_to_a(argc, argv, obj);
+
+ for (i = RARRAY_LEN(ary); --i >= 0; ) {
+ rb_yield(RARRAY_AT(ary, i));
+ }
+
+ return obj;
+}
+
+
+static VALUE
zip_ary(VALUE val, NODE *memo, int argc, VALUE *argv)
{
volatile VALUE result = memo->u1.value;
@@ -1776,8 +1820,8 @@
{
rb_mEnumerable = rb_define_module("Enumerable");
- rb_define_method(rb_mEnumerable,"to_a", enum_to_a, 0);
- rb_define_method(rb_mEnumerable,"entries", enum_to_a, 0);
+ rb_define_method(rb_mEnumerable, "to_a", enum_to_a, -1);
+ rb_define_method(rb_mEnumerable, "entries", enum_to_a, -1);
rb_define_method(rb_mEnumerable,"sort", enum_sort, 0);
rb_define_method(rb_mEnumerable,"sort_by", enum_sort_by, 0);
@@ -1790,32 +1834,33 @@
#else
rb_define_method(rb_mEnumerable,"count", enum_count, -1);
#endif
- rb_define_method(rb_mEnumerable,"find", enum_find, -1);
- rb_define_method(rb_mEnumerable,"detect", enum_find, -1);
- rb_define_method(rb_mEnumerable,"find_index", enum_find_index, -1);
- rb_define_method(rb_mEnumerable,"find_all", enum_find_all, 0);
- rb_define_method(rb_mEnumerable,"select", enum_find_all, 0);
- rb_define_method(rb_mEnumerable,"reject", enum_reject, 0);
- rb_define_method(rb_mEnumerable,"collect", enum_collect, 0);
- rb_define_method(rb_mEnumerable,"map", enum_collect, 0);
- rb_define_method(rb_mEnumerable,"inject", enum_inject, -1);
- rb_define_method(rb_mEnumerable,"reduce", enum_inject, -1);
- rb_define_method(rb_mEnumerable,"partition", enum_partition, 0);
- rb_define_method(rb_mEnumerable,"group_by", enum_group_by, 0);
- rb_define_method(rb_mEnumerable,"first", enum_first, -1);
- rb_define_method(rb_mEnumerable,"all?", enum_all, 0);
- rb_define_method(rb_mEnumerable,"any?", enum_any, 0);
- rb_define_method(rb_mEnumerable,"one?", enum_one, 0);
- rb_define_method(rb_mEnumerable,"none?", enum_none, 0);
- rb_define_method(rb_mEnumerable,"min", enum_min, 0);
- rb_define_method(rb_mEnumerable,"max", enum_max, 0);
- rb_define_method(rb_mEnumerable,"minmax", enum_minmax, 0);
- rb_define_method(rb_mEnumerable,"min_by", enum_min_by, 0);
- rb_define_method(rb_mEnumerable,"max_by", enum_max_by, 0);
- rb_define_method(rb_mEnumerable,"minmax_by", enum_minmax_by, 0);
- rb_define_method(rb_mEnumerable,"member?", enum_member, 1);
- rb_define_method(rb_mEnumerable,"include?", enum_member, 1);
- rb_define_method(rb_mEnumerable,"each_with_index", enum_each_with_index, -1);
+ rb_define_method(rb_mEnumerable, "find", enum_find, -1);
+ rb_define_method(rb_mEnumerable, "detect", enum_find, -1);
+ rb_define_method(rb_mEnumerable, "find_index", enum_find_index, -1);
+ rb_define_method(rb_mEnumerable, "find_all", enum_find_all, 0);
+ rb_define_method(rb_mEnumerable, "select", enum_find_all, 0);
+ rb_define_method(rb_mEnumerable, "reject", enum_reject, 0);
+ rb_define_method(rb_mEnumerable, "collect", enum_collect, 0);
+ rb_define_method(rb_mEnumerable, "map", enum_collect, 0);
+ rb_define_method(rb_mEnumerable, "inject", enum_inject, -1);
+ rb_define_method(rb_mEnumerable, "reduce", enum_inject, -1);
+ rb_define_method(rb_mEnumerable, "partition", enum_partition, 0);
+ rb_define_method(rb_mEnumerable, "group_by", enum_group_by, 0);
+ rb_define_method(rb_mEnumerable, "first", enum_first, -1);
+ rb_define_method(rb_mEnumerable, "all?", enum_all, 0);
+ rb_define_method(rb_mEnumerable, "any?", enum_any, 0);
+ rb_define_method(rb_mEnumerable, "one?", enum_one, 0);
+ rb_define_method(rb_mEnumerable, "none?", enum_none, 0);
+ rb_define_method(rb_mEnumerable, "min", enum_min, 0);
+ rb_define_method(rb_mEnumerable, "max", enum_max, 0);
+ rb_define_method(rb_mEnumerable, "minmax", enum_minmax, 0);
+ rb_define_method(rb_mEnumerable, "min_by", enum_min_by, 0);
+ rb_define_method(rb_mEnumerable, "max_by", enum_max_by, 0);
+ rb_define_method(rb_mEnumerable, "minmax_by", enum_minmax_by, 0);
+ rb_define_method(rb_mEnumerable, "member?", enum_member, 1);
+ rb_define_method(rb_mEnumerable, "include?", enum_member, 1);
+ rb_define_method(rb_mEnumerable, "each_with_index", enum_each_with_index, -1);
+ rb_define_method(rb_mEnumerable, "reverse_each", enum_reverse_each, -1);
rb_define_method(rb_mEnumerable, "zip", enum_zip, -1);
rb_define_method(rb_mEnumerable, "take", enum_take, 1);
rb_define_method(rb_mEnumerable, "take_while", enum_take_while, 0);
@@ -1827,5 +1872,6 @@
id_each = rb_intern("each");
id_cmp = rb_intern("<=>");
id_next = rb_intern("next");
+ id_size = rb_intern("size");
}
Modified: MacRuby/trunk/enumerator.c
===================================================================
--- MacRuby/trunk/enumerator.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/enumerator.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -8,7 +8,7 @@
$Idaemons: /home/cvs/rb/enumerator/enumerator.c,v 1.1.1.1 2001/07/15 10:12:48 knu Exp $
$RoughId: enumerator.c,v 1.6 2003/07/27 11:03:24 nobu Exp $
- $Id: enumerator.c 16402 2008-05-13 06:10:56Z knu $
+ $Id: enumerator.c 16614 2008-05-26 08:49:08Z knu $
************************************************/
@@ -30,7 +30,6 @@
VALUE obj;
ID meth;
VALUE args;
- rb_block_call_func *iter;
VALUE fib;
VALUE dst;
VALUE no_next;
@@ -39,11 +38,13 @@
static void
enumerator_mark(void *p)
{
+#if !WITH_OBJC
struct enumerator *ptr = p;
rb_gc_mark(ptr->obj);
rb_gc_mark(ptr->args);
rb_gc_mark(ptr->fib);
rb_gc_mark(ptr->dst);
+#endif
}
static struct enumerator *
@@ -54,8 +55,8 @@
Data_Get_Struct(obj, struct enumerator, ptr);
if (RDATA(obj)->dmark != enumerator_mark) {
rb_raise(rb_eTypeError,
- "wrong argument type %s (expected Enumerable::Enumerator)",
- rb_obj_classname(obj));
+ "wrong argument type %s (expected %s)",
+ rb_obj_classname(obj), rb_class2name(rb_cEnumerator));
}
if (!ptr) {
rb_raise(rb_eArgError, "uninitialized enumerator");
@@ -222,7 +223,6 @@
ptr->obj = obj;
ptr->meth = rb_to_id(meth);
- ptr->iter = enumerator_each_i;
if (argc) GC_WB(&ptr->args, rb_ary_new4(argc, argv));
ptr->fib = 0;
ptr->dst = Qnil;
@@ -272,7 +272,6 @@
ptr1->obj = ptr0->obj;
ptr1->meth = ptr0->meth;
- ptr1->iter = ptr0->iter;
ptr1->args = ptr0->args;
ptr1->fib = 0;
@@ -306,7 +305,8 @@
argc = RARRAY_LEN(e->args);
argv = RARRAY_PTR(e->args);
}
- return rb_block_call(e->obj, e->meth, argc, argv, e->iter, (VALUE)e);
+ return rb_block_call(e->obj, e->meth, argc, argv,
+ enumerator_each_i, (VALUE)e);
}
static VALUE
@@ -329,12 +329,13 @@
static VALUE
enumerator_with_index(VALUE obj)
{
- struct enumerator *e = enumerator_ptr(obj);
+ struct enumerator *e;
VALUE memo = 0;
int argc = 0;
const VALUE *argv = 0;
RETURN_ENUMERATOR(obj, 0, 0);
+ e = enumerator_ptr(obj);
if (e->args) {
argc = RARRAY_LEN(e->args);
argv = RARRAY_PTR(e->args);
@@ -438,6 +439,7 @@
rb_define_method(rb_cEnumerator, "initialize", enumerator_initialize, -1);
rb_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1);
rb_define_method(rb_cEnumerator, "each", enumerator_each, 0);
+ rb_define_method(rb_cEnumerator, "each_with_index", enumerator_with_index, 0);
rb_define_method(rb_cEnumerator, "with_index", enumerator_with_index, 0);
rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
Modified: MacRuby/trunk/error.c
===================================================================
--- MacRuby/trunk/error.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/error.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
error.c -
- $Author: nobu $
+ $Author: matz $
created at: Mon Aug 9 16:11:34 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -556,7 +556,7 @@
if (exc == obj) return Qtrue;
if (rb_obj_class(exc) != rb_obj_class(obj))
- return Qfalse;
+ return rb_equal(obj, exc);
if (!rb_equal(rb_attr_get(exc, id_mesg), rb_attr_get(obj, id_mesg)))
return Qfalse;
if (!rb_equal(exc_backtrace(exc), exc_backtrace(obj)))
@@ -963,18 +963,16 @@
syserr_eqq(VALUE self, VALUE exc)
{
VALUE num, e;
+ ID en = rb_intern("errno");
- if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) return Qfalse;
- if (self == rb_eSystemCallError) return Qtrue;
+ if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {
+ if (!rb_respond_to(exc, en)) return Qfalse;
+ }
+ else if (self == rb_eSystemCallError) return Qtrue;
num = rb_attr_get(exc, rb_intern("errno"));
if (NIL_P(num)) {
- VALUE klass = CLASS_OF(exc);
-
- while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
- klass = (VALUE)RCLASS_SUPER(klass);
- }
- num = rb_const_get(klass, rb_intern("Errno"));
+ num = rb_funcall(exc, en, 0, 0);
}
e = rb_const_get(self, rb_intern("Errno"));
if (FIXNUM_P(num) ? num == e : rb_equal(num, e))
Modified: MacRuby/trunk/eval.c
===================================================================
--- MacRuby/trunk/eval.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/eval.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
eval.c -
- $Author: matz $
+ $Author: nobu $
created at: Thu Jun 10 14:22:17 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -14,31 +14,19 @@
#include "eval_intern.h"
VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
-VALUE rb_binding_new();
+VALUE rb_binding_new(void);
+NORETURN(void rb_raise_jump(VALUE));
VALUE rb_f_block_given_p(void);
ID rb_frame_callee(void);
-static VALUE rb_frame_self(void);
-
-static ID removed, singleton_removed, undefined, singleton_undefined;
-static ID init, eqq, each, aref, aset, match, missing;
-static ID added, singleton_added;
-static ID object_id, __send__, respond_to;
-
VALUE rb_eLocalJumpError;
VALUE rb_eSysStackError;
VALUE sysstack_error;
static VALUE exception_error;
-static VALUE eval(VALUE, VALUE, VALUE, const char *, int);
-
-static inline VALUE rb_yield_0(int argc, VALUE *argv);
-static VALUE rb_call(VALUE, VALUE, ID, int, const VALUE *, int);
-
#include "eval_error.c"
-#include "eval_method.c"
#include "eval_safe.c"
#include "eval_jump.c"
@@ -106,7 +94,7 @@
error_print();
exit(EXIT_FAILURE);
}
- ruby_running = 1;
+ GET_VM()->running = 1;
}
extern void rb_clear_trace_func(void);
@@ -268,83 +256,6 @@
return ruby_cleanup(ruby_exec_node(n, 0));
}
-VALUE
-rb_eval_string(const char *str)
-{
- return eval(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
-}
-
-VALUE
-rb_eval_string_protect(const char *str, int *state)
-{
- return rb_protect((VALUE (*)(VALUE))rb_eval_string, (VALUE)str, state);
-}
-
-VALUE
-rb_eval_string_wrap(const char *str, int *state)
-{
- int status;
- rb_thread_t *th = GET_THREAD();
- VALUE self = th->top_self;
- VALUE wrapper = th->top_wrapper;
- VALUE val;
-
- th->top_wrapper = rb_module_new();
- th->top_self = rb_obj_clone(rb_vm_top_self());
- rb_extend_object(th->top_self, th->top_wrapper);
-
- val = rb_eval_string_protect(str, &status);
-
- th->top_self = self;
- th->top_wrapper = wrapper;
-
- if (state) {
- *state = status;
- }
- else if (status) {
- JUMP_TAG(status);
- }
- return val;
-}
-
-VALUE
-rb_eval_cmd(VALUE cmd, VALUE arg, int level)
-{
- int state;
- VALUE val = Qnil; /* OK */
- volatile int safe = rb_safe_level();
-
- if (OBJ_TAINTED(cmd)) {
- level = 4;
- }
-
- if (TYPE(cmd) != T_STRING) {
- PUSH_TAG();
- rb_set_safe_level_force(level);
- if ((state = EXEC_TAG()) == 0) {
- val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LEN(arg),
- RARRAY_PTR(arg));
- }
- POP_TAG();
-
- rb_set_safe_level_force(safe);
-
- if (state)
- JUMP_TAG(state);
- return val;
- }
-
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- val = eval(rb_vm_top_self(), cmd, Qnil, 0, 0);
- }
- POP_TAG();
-
- rb_set_safe_level_force(safe);
- if (state) vm_jump_tag_but_local_jump(state, val);
- return val;
-}
-
/*
* call-seq:
* Module.nesting => array
@@ -364,7 +275,7 @@
rb_mod_nesting(void)
{
VALUE ary = rb_ary_new();
- NODE *cref = ruby_cref();
+ const NODE *cref = vm_cref();
while (cref && cref->nd_next) {
VALUE klass = cref->nd_clss;
@@ -393,7 +304,7 @@
static VALUE
rb_mod_s_constants(int argc, VALUE *argv, VALUE mod)
{
- NODE *cref = ruby_cref();
+ const NODE *cref = vm_cref();
VALUE klass;
VALUE cbase = 0;
void *data = 0;
@@ -422,7 +333,7 @@
void
rb_frozen_class_p(VALUE klass)
{
- char *desc = "something(?!)";
+ const char *desc = "something(?!)";
if (OBJ_FROZEN(klass)) {
if (FL_TEST(klass, FL_SINGLETON))
@@ -442,220 +353,8 @@
}
}
-/*
- * call-seq:
- * obj.respond_to?(symbol, include_private=false) => true or false
- *
- * Returns +true+> if _obj_ responds to the given
- * method. Private methods are included in the search only if the
- * optional second parameter evaluates to +true+.
- */
-
-static NODE *basic_respond_to = 0;
-
-int
-rb_obj_respond_to(VALUE obj, ID id, int priv)
-{
- VALUE klass = CLASS_OF(obj);
-
- if (rb_method_node(klass, respond_to) == basic_respond_to) {
- return rb_method_boundp(klass, id, !priv);
- }
- else {
- VALUE args[2];
- int n = 0;
- args[n++] = ID2SYM(id);
- if (priv)
- args[n++] = Qtrue;
- return RTEST(rb_funcall2(obj, respond_to, n, args));
- }
-}
-
-int
-rb_respond_to(VALUE obj, ID id)
-{
- return rb_obj_respond_to(obj, id, Qfalse);
-}
-
-/*
- * call-seq:
- * obj.respond_to?(symbol, include_private=false) => true or false
- *
- * Returns +true+> if _obj_ responds to the given
- * method. Private methods are included in the search only if the
- * optional second parameter evaluates to +true+.
- */
-
-static VALUE
-obj_respond_to(int argc, VALUE *argv, VALUE obj)
-{
- VALUE mid, priv;
- ID id;
-
- rb_scan_args(argc, argv, "11", &mid, &priv);
- id = rb_to_id(mid);
- if (rb_method_boundp(CLASS_OF(obj), id, !RTEST(priv))) {
- return Qtrue;
- }
- return Qfalse;
-}
-
-/*
- * call-seq:
- * mod.method_defined?(symbol) => true or false
- *
- * Returns +true+ if the named method is defined by
- * _mod_ (or its included modules and, if _mod_ is a class,
- * its ancestors). Public and protected methods are matched.
- *
- * module A
- * def method1() end
- * end
- * class B
- * def method2() end
- * end
- * class C < B
- * include A
- * def method3() end
- * end
- *
- * A.method_defined? :method1 #=> true
- * C.method_defined? "method1" #=> true
- * C.method_defined? "method2" #=> true
- * C.method_defined? "method3" #=> true
- * C.method_defined? "method4" #=> false
- */
-
-static VALUE
-rb_mod_method_defined(VALUE mod, VALUE mid)
-{
- return rb_method_boundp(mod, rb_to_id(mid), 1);
-}
-
-#define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
-
-/*
- * call-seq:
- * mod.public_method_defined?(symbol) => true or false
- *
- * Returns +true+ if the named public method is defined by
- * _mod_ (or its included modules and, if _mod_ is a class,
- * its ancestors).
- *
- * module A
- * def method1() end
- * end
- * class B
- * protected
- * def method2() end
- * end
- * class C < B
- * include A
- * def method3() end
- * end
- *
- * A.method_defined? :method1 #=> true
- * C.public_method_defined? "method1" #=> true
- * C.public_method_defined? "method2" #=> false
- * C.method_defined? "method2" #=> true
- */
-
-static VALUE
-rb_mod_public_method_defined(VALUE mod, VALUE mid)
-{
- ID id = rb_to_id(mid);
- NODE *method;
-
- method = rb_method_node(mod, id);
- if (method) {
- if (VISI_CHECK(method->nd_noex, NOEX_PUBLIC))
- return Qtrue;
- }
- return Qfalse;
-}
-
-/*
- * call-seq:
- * mod.private_method_defined?(symbol) => true or false
- *
- * Returns +true+ if the named private method is defined by
- * _ mod_ (or its included modules and, if _mod_ is a class,
- * its ancestors).
- *
- * module A
- * def method1() end
- * end
- * class B
- * private
- * def method2() end
- * end
- * class C < B
- * include A
- * def method3() end
- * end
- *
- * A.method_defined? :method1 #=> true
- * C.private_method_defined? "method1" #=> false
- * C.private_method_defined? "method2" #=> true
- * C.method_defined? "method2" #=> false
- */
-
-static VALUE
-rb_mod_private_method_defined(VALUE mod, VALUE mid)
-{
- ID id = rb_to_id(mid);
- NODE *method;
-
- method = rb_method_node(mod, id);
- if (method) {
- if (VISI_CHECK(method->nd_noex, NOEX_PRIVATE))
- return Qtrue;
- }
- return Qfalse;
-}
-
-/*
- * call-seq:
- * mod.protected_method_defined?(symbol) => true or false
- *
- * Returns +true+ if the named protected method is defined
- * by _mod_ (or its included modules and, if _mod_ is a
- * class, its ancestors).
- *
- * module A
- * def method1() end
- * end
- * class B
- * protected
- * def method2() end
- * end
- * class C < B
- * include A
- * def method3() end
- * end
- *
- * A.method_defined? :method1 #=> true
- * C.protected_method_defined? "method1" #=> false
- * C.protected_method_defined? "method2" #=> true
- * C.method_defined? "method2" #=> true
- */
-
-static VALUE
-rb_mod_protected_method_defined(VALUE mod, VALUE mid)
-{
- ID id = rb_to_id(mid);
- NODE *method;
-
- method = rb_method_node(mod, id);
- if (method) {
- if (VISI_CHECK(method->nd_noex, NOEX_PROTECTED))
- return Qtrue;
- }
- return Qfalse;
-}
-
NORETURN(static void rb_longjmp(int, VALUE));
-static VALUE make_backtrace(void);
+VALUE rb_make_backtrace(void);
static void
rb_longjmp(int tag, VALUE mesg)
@@ -682,7 +381,7 @@
if (file && !NIL_P(mesg)) {
at = get_backtrace(mesg);
if (NIL_P(at)) {
- at = make_backtrace();
+ at = rb_make_backtrace();
set_backtrace(mesg, at);
}
}
@@ -891,11 +590,12 @@
VALUE
-rb_f_block_given_p()
+rb_f_block_given_p(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
cfp = vm_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
+
if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
return Qtrue;
}
@@ -914,202 +614,13 @@
}
}
-static inline VALUE
-rb_yield_0(int argc, VALUE *argv)
-{
- return vm_yield(GET_THREAD(), argc, argv);
-}
-
VALUE
-rb_yield(VALUE val)
+rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
+ VALUE (* r_proc) (ANYARGS), VALUE data2, ...)
{
- volatile VALUE tmp = val;
- if (val == Qundef) {
- tmp = rb_yield_0(0, 0);
- }
- else {
- tmp = rb_yield_0(1, &val);
- }
- return tmp;
-}
-
-VALUE
-rb_yield_values(int n, ...)
-{
- int i;
- VALUE *argv;
- va_list args;
-
- if (n == 0) {
- return rb_yield_0(0, 0);
- }
-
- argv = ALLOCA_N(VALUE, n);
-
- va_init_list(args, n);
- for (i=0; i<n; i++) {
- argv[i] = va_arg(args, VALUE);
- }
- va_end(args);
-
- return rb_yield_0(n, argv);
-}
-
-VALUE
-rb_yield_values2(int argc, VALUE *argv)
-{
- return rb_yield_0(argc, argv);
-}
-
-VALUE
-rb_yield_splat(VALUE values)
-{
- VALUE tmp = rb_check_array_type(values);
- volatile VALUE v;
- if (NIL_P(tmp)) {
- rb_raise(rb_eArgError, "not an array");
- }
- v = rb_yield_0(RARRAY_LEN(tmp), RARRAY_PTR(tmp));
- return v;
-}
-
-static VALUE
-loop_i()
-{
- for (;;) {
- rb_yield_0(0, 0);
- }
- return Qnil;
-}
-
-/*
- * call-seq:
- * loop {|| block }
- *
- * Repeatedly executes the block.
- *
- * loop do
- * print "Input: "
- * line = gets
- * break if !line or line =~ /^qQ/
- * # ...
- * end
- *
- * StopIteration raised in the block breaks the loop.
- */
-
-static VALUE
-rb_f_loop(void)
-{
- rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
- return Qnil; /* dummy */
-}
-
-VALUE
-rb_iterate(VALUE (*it_proc) (VALUE), VALUE data1,
- VALUE (*bl_proc) (ANYARGS), VALUE data2)
-{
int state;
- volatile VALUE retval = Qnil;
- NODE *node = NEW_IFUNC(bl_proc, data2);
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
-
- TH_PUSH_TAG(th);
- state = TH_EXEC_TAG();
- if (state == 0) {
- iter_retry:
- {
- rb_block_t *blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(th->cfp);
- blockptr->iseq = (void *)node;
- blockptr->proc = 0;
- th->passed_block = blockptr;
- }
- retval = (*it_proc) (data1);
- }
- else {
- VALUE err = th->errinfo;
- if (state == TAG_BREAK) {
- VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
- VALUE *cdfp = cfp->dfp;
-
- if (cdfp == escape_dfp) {
- state = 0;
- th->state = 0;
- th->errinfo = Qnil;
- th->cfp = cfp;
- }
- else{
- /* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
- }
- }
- else if (state == TAG_RETRY) {
- VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
- VALUE *cdfp = cfp->dfp;
-
- if (cdfp == escape_dfp) {
- state = 0;
- th->state = 0;
- th->errinfo = Qnil;
- th->cfp = cfp;
- goto iter_retry;
- }
- }
- }
- TH_POP_TAG();
-
- switch (state) {
- case 0:
- break;
- default:
- TH_JUMP_TAG(th, state);
- }
- return retval;
-}
-
-struct iter_method_arg {
- VALUE obj;
- ID mid;
- int argc;
- VALUE *argv;
-};
-
-static VALUE
-iterate_method(VALUE obj)
-{
- struct iter_method_arg *arg;
-
- arg = (struct iter_method_arg *)obj;
- return rb_call(CLASS_OF(arg->obj), arg->obj, arg->mid,
- arg->argc, arg->argv, CALL_FCALL);
-}
-
-VALUE
-rb_block_call(VALUE obj, ID mid, int argc, VALUE *argv,
- VALUE (*bl_proc) (ANYARGS), VALUE data2)
-{
- struct iter_method_arg arg;
-
- arg.obj = obj;
- arg.mid = mid;
- arg.argc = argc;
- arg.argv = argv;
- return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
-}
-
-VALUE
-rb_each(VALUE obj)
-{
- return rb_call(CLASS_OF(obj), obj, rb_intern("each"), 0, 0, CALL_FCALL);
-}
-
-VALUE
-rb_rescue2(VALUE (*b_proc) (ANYARGS), VALUE data1, VALUE (*r_proc) (ANYARGS),
- VALUE data2, ...)
-{
- int state;
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = th->cfp;
volatile VALUE result;
volatile VALUE e_info = th->errinfo;
va_list args;
@@ -1166,14 +677,15 @@
}
VALUE
-rb_rescue(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2)
+rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
+ VALUE (* r_proc)(ANYARGS), VALUE data2)
{
return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
(VALUE)0);
}
VALUE
-rb_protect(VALUE (*proc) (VALUE), VALUE data, int *state)
+rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state)
{
VALUE result = Qnil; /* OK */
int status;
@@ -1249,415 +761,6 @@
return result;
}
-static inline void
-stack_check(void)
-{
- rb_thread_t *th = GET_THREAD();
-
- if (!rb_thread_raised_p(th, RAISED_STACKOVERFLOW) && ruby_stack_check()) {
- rb_thread_raised_set(th, RAISED_STACKOVERFLOW);
- rb_exc_raise(sysstack_error);
- }
-}
-
-/*
- * call-seq:
- * obj.method_missing(symbol [, *args] ) => result
- *
- * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
- * <i>symbol</i> is the symbol for the method called, and <i>args</i>
- * are any arguments that were passed to it. By default, the interpreter
- * raises an error when this method is called. However, it is possible
- * to override the method to provide more dynamic behavior.
- * If it is decided that a particular method should not be handled, then
- * <i>super</i> should be called, so that ancestors can pick up the
- * missing method.
- * The example below creates
- * a class <code>Roman</code>, which responds to methods with names
- * consisting of roman numerals, returning the corresponding integer
- * values.
- *
- * class Roman
- * def romanToInt(str)
- * # ...
- * end
- * def method_missing(methId)
- * str = methId.id2name
- * romanToInt(str)
- * end
- * end
- *
- * r = Roman.new
- * r.iv #=> 4
- * r.xxiii #=> 23
- * r.mm #=> 2000
- */
-
-static VALUE
-rb_method_missing(int argc, const VALUE *argv, VALUE obj)
-{
- ID id;
- VALUE exc = rb_eNoMethodError;
- char *format = 0;
- rb_thread_t *th = GET_THREAD();
- int last_call_status = th->method_missing_reason;
- if (argc == 0 || !SYMBOL_P(argv[0])) {
- rb_raise(rb_eArgError, "no id given");
- }
-
- stack_check();
-
- id = SYM2ID(argv[0]);
-
- if (last_call_status & NOEX_PRIVATE) {
- format = "private method `%s' called for %s";
- }
- else if (last_call_status & NOEX_PROTECTED) {
- format = "protected method `%s' called for %s";
- }
- else if (last_call_status & NOEX_VCALL) {
- format = "undefined local variable or method `%s' for %s";
- exc = rb_eNameError;
- }
- else if (last_call_status & NOEX_SUPER) {
- format = "super: no superclass method `%s' for %s";
- }
- if (!format) {
- format = "undefined method `%s' for %s";
- }
-
- {
- int n = 0;
- VALUE args[3];
- args[n++] = rb_funcall(rb_const_get(exc, rb_intern("message")), '!',
- 3, rb_str_new2(format), obj, argv[0]);
- args[n++] = argv[0];
- if (exc == rb_eNoMethodError) {
- args[n++] = rb_ary_new4(argc - 1, argv + 1);
- }
- exc = rb_class_new_instance(n, args, exc);
-
- th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
- rb_exc_raise(exc);
- }
-
- return Qnil; /* not reached */
-}
-
-static VALUE
-method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
-{
- VALUE *nargv;
- GET_THREAD()->method_missing_reason = call_status;
-
- if (id == missing) {
- rb_method_missing(argc, argv, obj);
- }
- else if (id == ID_ALLOCATOR) {
- rb_raise(rb_eTypeError, "allocator undefined for %s",
- rb_class2name(obj));
- }
-
- nargv = ALLOCA_N(VALUE, argc + 1);
- nargv[0] = ID2SYM(id);
- MEMCPY(nargv + 1, argv, VALUE, argc);
-
- return rb_funcall2(obj, missing, argc + 1, nargv);
-}
-
-static VALUE
-rb_call0(VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int scope, VALUE self)
-{
- NODE *body, *method;
- int noex;
- ID id = mid;
- struct cache_entry *ent;
- rb_thread_t *th = GET_THREAD();
-#if WITH_OBJC
- unsigned redo = 0;
-#endif
-
-rb_call0_redo:
-
-#if WITH_OBJC
-# define REDO_PERHAPS() \
- if (!redo) { \
- ID newid = rb_objc_missing_sel(mid, argc); \
- if (newid != mid) { \
- id = mid = newid; \
- redo = 1; \
- goto rb_call0_redo; \
- } \
- }
-#else
-# define REDO_PERHAPS()
-#endif
-
- if (!klass) {
- rb_raise(rb_eNotImpError,
- "method `%s' called on terminated object (%p)",
- rb_id2name(mid), (void *)recv);
- }
- /* is it in the method cache? */
- ent = cache + EXPR1(klass, mid);
-
- if (ent->mid == mid && ent->klass == klass) {
- if (!ent->method) {
- REDO_PERHAPS();
- return method_missing(recv, mid, argc, argv,
- scope == 2 ? NOEX_VCALL : 0);
- }
- id = ent->mid0;
- noex = ent->method->nd_noex;
- klass = ent->method->nd_clss;
- body = ent->method->nd_body;
- }
- else if ((method = rb_get_method_body(klass, id, &id)) != 0) {
- noex = method->nd_noex;
- klass = method->nd_clss;
- body = method->nd_body;
- }
- else {
- REDO_PERHAPS();
- if (scope == 3) {
- return method_missing(recv, mid, argc, argv, NOEX_SUPER);
- }
- return method_missing(recv, mid, argc, argv,
- scope == 2 ? NOEX_VCALL : 0);
- }
-
-
- if (mid != missing) {
- /* receiver specified form for private method */
- if (UNLIKELY(noex)) {
- if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == 0) {
- return method_missing(recv, mid, argc, argv, NOEX_PRIVATE);
- }
-
- /* self must be kind of a specified form for protected method */
- if (((noex & NOEX_MASK) & NOEX_PROTECTED) && scope == 0) {
- VALUE defined_class = klass;
-
- if (TYPE(defined_class) == T_ICLASS) {
- defined_class = RBASIC(defined_class)->klass;
- }
-
- if (self == Qundef) {
- self = rb_frame_self();
- }
- if (!rb_obj_is_kind_of(self, rb_class_real(defined_class))) {
- return method_missing(recv, mid, argc, argv, NOEX_PROTECTED);
- }
- }
-
- if (NOEX_SAFE(noex) > th->safe_level) {
- rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(mid));
- }
- }
- }
-
- stack_check();
-
- {
- VALUE val;
- /*
- //static int level;
- //int i;
- //for(i=0; i<level; i++){printf(" ");}
- //printf("invoke %s (%s)\n", rb_id2name(mid), ruby_node_name(nd_type(body)));
- //level++;
- //printf("%s with %d args\n", rb_id2name(mid), argc);
- */
- val = vm_call0(th, klass, recv, mid, id, argc, argv, body,
- noex & NOEX_NOSUPER);
- /*
- //level--;
- //for(i=0; i<level; i++){printf(" ");}
- //printf("done %s (%s)\n", rb_id2name(mid), ruby_node_name(nd_type(body)));
- */
- return val;
- }
-
-#undef REDO_PERHAPS
-}
-
-static VALUE
-rb_call(VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int scope)
-{
- return rb_call0(klass, recv, mid, argc, argv, scope, Qundef);
-}
-
-VALUE
-rb_apply(VALUE recv, ID mid, VALUE args)
-{
- int argc;
- VALUE *argv;
-
- argc = RARRAY_LEN(args); /* Assigns LONG, but argc is INT */
- argv = ALLOCA_N(VALUE, argc);
- MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
- return rb_call(CLASS_OF(recv), recv, mid, argc, argv, CALL_FCALL);
-}
-
-static VALUE
-send_internal(int argc, VALUE *argv, VALUE recv, int scope)
-{
- VALUE vid;
- VALUE self = RUBY_VM_PREVIOUS_CONTROL_FRAME(GET_THREAD()->cfp)->self;
-
- if (argc == 0) {
- rb_raise(rb_eArgError, "no method name given");
- }
-
- vid = *argv++; argc--;
- PASS_PASSED_BLOCK();
- return rb_call0(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, scope, self);
-}
-
-/*
- * call-seq:
- * obj.send(symbol [, args...]) => obj
- * obj.__send__(symbol [, args...]) => obj
- *
- * Invokes the method identified by _symbol_, passing it any
- * arguments specified. You can use <code>__send__</code> if the name
- * +send+ clashes with an existing method in _obj_.
- *
- * class Klass
- * def hello(*args)
- * "Hello " + args.join(' ')
- * end
- * end
- * k = Klass.new
- * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
- */
-
-VALUE
-rb_f_send(int argc, VALUE *argv, VALUE recv)
-{
- return send_internal(argc, argv, recv, NOEX_NOSUPER | NOEX_PRIVATE);
-}
-
-
-/*
- * call-seq:
- * obj.public_send(symbol [, args...]) => obj
- *
- * Invokes the method identified by _symbol_, passing it any
- * arguments specified. Unlike send, public_send calls public
- * methods only.
- *
- * 1.public_send(:puts, "hello") # causes NoMethodError
- */
-
-VALUE
-rb_f_public_send(int argc, VALUE *argv, VALUE recv)
-{
- return send_internal(argc, argv, recv, NOEX_PUBLIC);
-}
-
-VALUE
-rb_funcall(VALUE recv, ID mid, int n, ...)
-{
- VALUE *argv;
- va_list ar;
- va_init_list(ar, n);
-
- if (n > 0) {
- long i;
-
- argv = ALLOCA_N(VALUE, n);
-
- for (i = 0; i < n; i++) {
- argv[i] = va_arg(ar, VALUE);
- }
- va_end(ar);
- }
- else {
- argv = 0;
- }
- return rb_call(CLASS_OF(recv), recv, mid, n, argv, CALL_FCALL);
-}
-
-VALUE
-rb_funcall2(VALUE recv, ID mid, int argc, const VALUE *argv)
-{
- return rb_call(CLASS_OF(recv), recv, mid, argc, argv, CALL_FCALL);
-}
-
-VALUE
-rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
-{
- return rb_call(CLASS_OF(recv), recv, mid, argc, argv, CALL_PUBLIC);
-}
-
-static VALUE
-backtrace(int lev)
-{
- return vm_backtrace(GET_THREAD(), lev);
-}
-
-/*
- * call-seq:
- * caller(start=1) => array
- *
- * Returns the current execution stack---an array containing strings in
- * the form ``<em>file:line</em>'' or ``<em>file:line: in
- * `method'</em>''. The optional _start_ parameter
- * determines the number of initial stack entries to omit from the
- * result.
- *
- * def a(skip)
- * caller(skip)
- * end
- * def b(skip)
- * a(skip)
- * end
- * def c(skip)
- * b(skip)
- * end
- * c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"]
- * c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"]
- * c(2) #=> ["prog:8:in `c'", "prog:12"]
- * c(3) #=> ["prog:13"]
- */
-
-static VALUE
-rb_f_caller(int argc, VALUE *argv)
-{
- VALUE level;
- int lev;
-
- rb_scan_args(argc, argv, "01", &level);
-
- if (NIL_P(level))
- lev = 1;
- else
- lev = NUM2INT(level);
- if (lev < 0)
- rb_raise(rb_eArgError, "negative level (%d)", lev);
-
- return backtrace(lev);
-}
-
-void
-rb_backtrace(void)
-{
- long i;
- VALUE ary;
-
- ary = backtrace(-1);
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- printf("\tfrom %s\n", RSTRING_CPTR(RARRAY_AT(ary, i)));
- }
-}
-
-static VALUE
-make_backtrace(void)
-{
- return backtrace(-1);
-}
-
static ID
frame_func_id(rb_control_frame_t *cfp)
{
@@ -1705,659 +808,8 @@
th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
}
-static VALUE
-rb_frame_self(void)
-{
- return GET_THREAD()->cfp->self;
-}
-
-static VALUE
-eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
-{
- int state;
- VALUE result = Qundef;
- VALUE envval;
- rb_binding_t *bind = 0;
- rb_thread_t *th = GET_THREAD();
- rb_env_t *env = NULL;
- NODE *stored_cref_stack = 0;
-
- if (file == 0) {
- file = rb_sourcefile();
- line = rb_sourceline();
- }
-
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- rb_iseq_t *iseq;
- volatile VALUE iseqval;
-
- if (scope != Qnil) {
- if (rb_obj_is_kind_of(scope, rb_cBinding)) {
- GetBindingPtr(scope, bind);
- envval = bind->env;
- stored_cref_stack = bind->cref_stack;
- }
- else {
- rb_raise(rb_eTypeError,
- "wrong argument type %s (expected Binding)",
- rb_obj_classname(scope));
- }
- GetEnvPtr(envval, env);
- th->base_block = &env->block;
- }
- else {
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- th->base_block = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
- th->base_block->iseq = cfp->iseq; /* TODO */
- }
-
- /* make eval iseq */
- th->parse_in_eval++;
- iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
- th->parse_in_eval--;
- rb_vm_set_eval_stack(th, iseqval);
- th->base_block = 0;
-
- if (0) { /* for debug */
- extern VALUE ruby_iseq_disasm(VALUE);
- printf("%s\n", RSTRING_CPTR(ruby_iseq_disasm(iseqval)));
- }
-
- /* save new env */
- GetISeqPtr(iseqval, iseq);
- if (bind && iseq->local_size > 0) {
- bind->env = vm_make_env_object(th, th->cfp);
- }
-
- /* push tag */
- if (stored_cref_stack) {
- stored_cref_stack =
- vm_set_special_cref(th, env->block.lfp, stored_cref_stack);
- }
-
- /* kick */
- CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
- result = vm_eval_body(th);
- }
- POP_TAG();
-
- if (stored_cref_stack) {
- vm_set_special_cref(th, env->block.lfp, stored_cref_stack);
- }
-
- if (state) {
- if (state == TAG_RAISE) {
- VALUE errinfo = th->errinfo;
- if (strcmp(file, "(eval)") == 0) {
- VALUE mesg, errat, bt2;
-
- errat = get_backtrace(errinfo);
- mesg = rb_attr_get(errinfo, rb_intern("mesg"));
- if (!NIL_P(errat) && TYPE(errat) == T_ARRAY &&
- (bt2 = backtrace(-2), RARRAY_LEN(bt2) > 0)) {
- if (!NIL_P(mesg) && TYPE(mesg) == T_STRING && !RSTRING_CLEN(mesg)) {
- rb_str_update(mesg, 0, 0, rb_str_new2(": "));
- rb_str_update(mesg, 0, 0, RARRAY_AT(errat, 0));
- }
- rb_ary_store(errat, 0, RARRAY_AT(bt2, 0));
- }
- }
- rb_exc_raise(errinfo);
- }
- JUMP_TAG(state);
- }
- return result;
-}
-
/*
* call-seq:
- * eval(string [, binding [, filename [,lineno]]]) => obj
- *
- * Evaluates the Ruby expression(s) in <em>string</em>. If
- * <em>binding</em> is given, the evaluation is performed in its
- * context. The binding may be a <code>Binding</code> object or a
- * <code>Proc</code> object. If the optional <em>filename</em> and
- * <em>lineno</em> parameters are present, they will be used when
- * reporting syntax errors.
- *
- * def getBinding(str)
- * return binding
- * end
- * str = "hello"
- * eval "str + ' Fred'" #=> "hello Fred"
- * eval "str + ' Fred'", getBinding("bye") #=> "bye Fred"
- */
-
-VALUE
-rb_f_eval(int argc, VALUE *argv, VALUE self)
-{
- VALUE src, scope, vfile, vline;
- const char *file = "(eval)";
- int line = 1;
-
- rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
- if (rb_safe_level() >= 4) {
- StringValue(src);
- if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {
- rb_raise(rb_eSecurityError,
- "Insecure: can't modify trusted binding");
- }
- }
- else {
- SafeStringValue(src);
- }
- if (argc >= 3) {
- StringValue(vfile);
- }
- if (argc >= 4) {
- line = NUM2INT(vline);
- }
-
- if (!NIL_P(vfile))
- file = RSTRING_CPTR(vfile);
- return eval(self, src, scope, file, line);
-}
-
-VALUE vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key);
-void vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, VALUE val);
-
-/* function to call func under the specified class/module context */
-static VALUE
-exec_under(VALUE (*func) (VALUE), VALUE under, VALUE self, VALUE args)
-{
- VALUE val = Qnil; /* OK */
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = th->cfp;
- rb_control_frame_t *pcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- VALUE stored_self = pcfp->self;
- NODE *stored_cref = 0;
-
- rb_block_t block;
- rb_block_t *blockptr;
- int state;
-
- /* replace environment */
- pcfp->self = self;
- if ((blockptr = GC_GUARDED_PTR_REF(*th->cfp->lfp)) != 0) {
- /* copy block info */
- /* TODO: why? */
- block = *blockptr;
- block.self = self;
- *th->cfp->lfp = GC_GUARDED_PTR(&block);
- }
-
- while (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
- cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- }
-
- stored_cref = (NODE *)vm_cfp_svar_get(th, cfp, 2);
- vm_cfp_svar_set(th, cfp, 2, (VALUE)vm_cref_push(th, under, NOEX_PUBLIC));
-
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- val = (*func) (args);
- }
- POP_TAG();
-
- /* restore environment */
- vm_cfp_svar_set(th, cfp, 2, (VALUE)stored_cref);
- pcfp->self = stored_self;
-
- if (state) {
- JUMP_TAG(state);
- }
- return val;
-}
-
-static VALUE
-yield_under_i(VALUE arg)
-{
- if (arg == Qundef) {
- return rb_yield_0(0, 0);
- }
- else {
- return rb_yield_0(RARRAY_LEN(arg), RARRAY_PTR(arg));
- }
-}
-
-/* block eval under the class/module context */
-static VALUE
-yield_under(VALUE under, VALUE self, VALUE values)
-{
- return exec_under(yield_under_i, under, self, values);
-}
-
-static VALUE
-eval_under_i(VALUE arg)
-{
- VALUE *args = (VALUE *)arg;
- return eval(args[0], args[1], Qnil, (char *)args[2], (int)args[3]);
-}
-
-/* string eval under the class/module context */
-static VALUE
-eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
-{
- VALUE args[4];
-
- if (rb_safe_level() >= 4) {
- StringValue(src);
- }
- else {
- SafeStringValue(src);
- }
- args[0] = self;
- args[1] = src;
- args[2] = (VALUE)file;
- args[3] = (VALUE)line;
- return exec_under(eval_under_i, under, self, (VALUE)args);
-}
-
-static VALUE
-specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
-{
- if (rb_block_given_p()) {
- if (argc > 0) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)",
- argc);
- }
- return yield_under(klass, self, Qundef);
- }
- else {
- char *file = "(eval)";
- int line = 1;
-
- if (argc == 0) {
- rb_raise(rb_eArgError, "block not supplied");
- }
- else {
- if (rb_safe_level() >= 4) {
- StringValue(argv[0]);
- }
- else {
- SafeStringValue(argv[0]);
- }
- if (argc > 3) {
- const char *name = rb_id2name(rb_frame_callee());
- rb_raise(rb_eArgError,
- "wrong number of arguments: %s(src) or %s{..}",
- name, name);
- }
- if (argc > 2)
- line = NUM2INT(argv[2]);
- if (argc > 1) {
- file = StringValuePtr(argv[1]);
- }
- }
- return eval_under(klass, self, argv[0], file, line);
- }
-}
-
-/*
- * call-seq:
- * obj.instance_eval(string [, filename [, lineno]] ) => obj
- * obj.instance_eval {| | block } => obj
- *
- * Evaluates a string containing Ruby source code, or the given block,
- * within the context of the receiver (_obj_). In order to set the
- * context, the variable +self+ is set to _obj_ while
- * the code is executing, giving the code access to _obj_'s
- * instance variables. In the version of <code>instance_eval</code>
- * that takes a +String+, the optional second and third
- * parameters supply a filename and starting line number that are used
- * when reporting compilation errors.
- *
- * class KlassWithSecret
- * def initialize
- * @secret = 99
- * end
- * end
- * k = KlassWithSecret.new
- * k.instance_eval { @secret } #=> 99
- */
-
-VALUE
-rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
-{
- VALUE klass;
-
- if (SPECIAL_CONST_P(self)) {
- klass = CLASS_OF(self); /* klass = Qnil; */
- }
- else {
- klass = rb_singleton_class(self);
- }
- return specific_eval(argc, argv, klass, self);
-}
-
-/*
- * call-seq:
- * obj.instance_exec(arg...) {|var...| block } => obj
- *
- * Executes the given block within the context of the receiver
- * (_obj_). In order to set the context, the variable +self+ is set
- * to _obj_ while the code is executing, giving the code access to
- * _obj_'s instance variables. Arguments are passed as block parameters.
- *
- * class KlassWithSecret
- * def initialize
- * @secret = 99
- * end
- * end
- * k = KlassWithSecret.new
- * k.instance_exec(5) {|x| @secret+x } #=> 104
- */
-
-VALUE
-rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
-{
- VALUE klass;
-
- if (SPECIAL_CONST_P(self)) {
- klass = Qnil;
- }
- else {
- klass = rb_singleton_class(self);
- }
- return yield_under(klass, self, rb_ary_new4(argc, argv));
-}
-
-/*
- * call-seq:
- * mod.class_eval(string [, filename [, lineno]]) => obj
- * mod.module_eval {|| block } => obj
- *
- * Evaluates the string or block in the context of _mod_. This can
- * be used to add methods to a class. <code>module_eval</code> returns
- * the result of evaluating its argument. The optional _filename_
- * and _lineno_ parameters set the text for error messages.
- *
- * class Thing
- * end
- * a = %q{def hello() "Hello there!" end}
- * Thing.module_eval(a)
- * puts Thing.new.hello()
- * Thing.module_eval("invalid code", "dummy", 123)
- *
- * <em>produces:</em>
- *
- * Hello there!
- * dummy:123:in `module_eval': undefined local variable
- * or method `code' for Thing:Class
- */
-
-VALUE
-rb_mod_module_eval(int argc, VALUE *argv, VALUE mod)
-{
- return specific_eval(argc, argv, mod, mod);
-}
-
-/*
- * call-seq:
- * mod.module_exec(arg...) {|var...| block } => obj
- * mod.class_exec(arg...) {|var...| block } => obj
- *
- * Evaluates the given block in the context of the class/module.
- * The method defined in the block will belong to the receiver.
- *
- * class Thing
- * end
- * Thing.class_exec{
- * def hello() "Hello there!" end
- * }
- * puts Thing.new.hello()
- *
- * <em>produces:</em>
- *
- * Hello there!
- */
-
-VALUE
-rb_mod_module_exec(int argc, VALUE *argv, VALUE mod)
-{
- return yield_under(mod, mod, rb_ary_new4(argc, argv));
-}
-
-static void
-secure_visibility(VALUE self)
-{
- if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
- rb_raise(rb_eSecurityError,
- "Insecure: can't change method visibility");
- }
-}
-
-static void
-set_method_visibility(VALUE self, int argc, VALUE *argv, ID ex)
-{
- int i;
- secure_visibility(self);
- for (i = 0; i < argc; i++) {
- rb_export_method(self, rb_to_id(argv[i]), ex);
- }
- rb_clear_cache_by_class(self);
-}
-
-/*
- * call-seq:
- * public => self
- * public(symbol, ...) => self
- *
- * With no arguments, sets the default visibility for subsequently
- * defined methods to public. With arguments, sets the named methods to
- * have public visibility.
- */
-
-static VALUE
-rb_mod_public(int argc, VALUE *argv, VALUE module)
-{
- secure_visibility(module);
- if (argc == 0) {
- SCOPE_SET(NOEX_PUBLIC);
- }
- else {
- set_method_visibility(module, argc, argv, NOEX_PUBLIC);
- }
- return module;
-}
-
-/*
- * call-seq:
- * protected => self
- * protected(symbol, ...) => self
- *
- * With no arguments, sets the default visibility for subsequently
- * defined methods to protected. With arguments, sets the named methods
- * to have protected visibility.
- */
-
-static VALUE
-rb_mod_protected(int argc, VALUE *argv, VALUE module)
-{
- secure_visibility(module);
- if (argc == 0) {
- SCOPE_SET(NOEX_PROTECTED);
- }
- else {
- set_method_visibility(module, argc, argv, NOEX_PROTECTED);
- }
- return module;
-}
-
-/*
- * call-seq:
- * private => self
- * private(symbol, ...) => self
- *
- * With no arguments, sets the default visibility for subsequently
- * defined methods to private. With arguments, sets the named methods
- * to have private visibility.
- *
- * module Mod
- * def a() end
- * def b() end
- * private
- * def c() end
- * private :a
- * end
- * Mod.private_instance_methods #=> [:a, :c]
- */
-
-static VALUE
-rb_mod_private(int argc, VALUE *argv, VALUE module)
-{
- secure_visibility(module);
- if (argc == 0) {
- SCOPE_SET(NOEX_PRIVATE);
- }
- else {
- set_method_visibility(module, argc, argv, NOEX_PRIVATE);
- }
- return module;
-}
-
-/*
- * call-seq:
- * mod.public_class_method(symbol, ...) => mod
- *
- * Makes a list of existing class methods public.
- */
-
-static VALUE
-rb_mod_public_method(int argc, VALUE *argv, VALUE obj)
-{
- set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PUBLIC);
- return obj;
-}
-
-/*
- * call-seq:
- * mod.private_class_method(symbol, ...) => mod
- *
- * Makes existing class methods private. Often used to hide the default
- * constructor <code>new</code>.
- *
- * class SimpleSingleton # Not thread safe
- * private_class_method :new
- * def SimpleSingleton.create(*args, &block)
- * @me = new(*args, &block) if ! @me
- * @me
- * end
- * end
- */
-
-static VALUE
-rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
-{
- set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PRIVATE);
- return obj;
-}
-
-/*
- * call-seq:
- * public
- * public(symbol, ...)
- *
- * With no arguments, sets the default visibility for subsequently
- * defined methods to public. With arguments, sets the named methods to
- * have public visibility.
- */
-
-static VALUE
-top_public(int argc, VALUE *argv)
-{
- return rb_mod_public(argc, argv, rb_cObject);
-}
-
-static VALUE
-top_private(int argc, VALUE *argv)
-{
- return rb_mod_private(argc, argv, rb_cObject);
-}
-
-/*
- * call-seq:
- * module_function(symbol, ...) => self
- *
- * Creates module functions for the named methods. These functions may
- * be called with the module as a receiver, and also become available
- * as instance methods to classes that mix in the module. Module
- * functions are copies of the original, and so may be changed
- * independently. The instance-method versions are made private. If
- * used with no arguments, subsequently defined methods become module
- * functions.
- *
- * module Mod
- * def one
- * "This is one"
- * end
- * module_function :one
- * end
- * class Cls
- * include Mod
- * def callOne
- * one
- * end
- * end
- * Mod.one #=> "This is one"
- * c = Cls.new
- * c.callOne #=> "This is one"
- * module Mod
- * def one
- * "This is the new one"
- * end
- * end
- * Mod.one #=> "This is one"
- * c.callOne #=> "This is the new one"
- */
-
-static VALUE
-rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
-{
- int i;
- ID id;
- NODE *fbody;
-
- if (TYPE(module) != T_MODULE) {
- rb_raise(rb_eTypeError, "module_function must be called for modules");
- }
-
- secure_visibility(module);
- if (argc == 0) {
- SCOPE_SET(NOEX_MODFUNC);
- return module;
- }
-
- set_method_visibility(module, argc, argv, NOEX_PRIVATE);
-
- for (i = 0; i < argc; i++) {
- VALUE m = module;
-
- id = rb_to_id(argv[i]);
- for (;;) {
- fbody = search_method(m, id, &m);
- if (fbody == 0) {
- fbody = search_method(rb_cObject, id, &m);
- }
- if (fbody == 0 || fbody->nd_body == 0) {
- rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
- }
- if (nd_type(fbody->nd_body->nd_body) != NODE_ZSUPER) {
- break; /* normal case: need not to follow 'super' link */
- }
- m = RCLASS_SUPER(m);
- if (!m)
- break;
- }
- rb_add_method(rb_singleton_class(module), id, fbody->nd_body->nd_body,
- NOEX_PUBLIC);
- }
- return module;
-}
-
-/*
- * call-seq:
* append_features(mod) => mod
*
* When this module is included in another, Ruby calls
@@ -2409,7 +861,7 @@
rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
{
PASS_PASSED_BLOCK();
- rb_funcall2(obj, init, argc, argv);
+ rb_funcall2(obj, idInitialize, argc, argv);
}
void
@@ -2530,12 +982,12 @@
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
- return &cfp->dfp[-1];
+ return &cfp->dfp[-2];
}
else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
- TYPE(cfp->dfp[-1]) != T_NODE &&
- !FIXNUM_P(cfp->dfp[-1])) {
- return &cfp->dfp[-1];
+ TYPE(cfp->dfp[-2]) != T_NODE &&
+ !FIXNUM_P(cfp->dfp[-2])) {
+ return &cfp->dfp[-2];
}
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
@@ -2711,85 +1163,41 @@
/* TODO: fix position */
GET_THREAD()->vm->mark_object_ary = rb_ary_new();
- init = rb_intern("initialize");
- eqq = rb_intern("===");
- each = rb_intern("each");
-
- aref = rb_intern("[]");
- aset = rb_intern("[]=");
- match = rb_intern("=~");
- missing = rb_intern("method_missing");
- added = rb_intern("method_added");
- singleton_added = rb_intern("singleton_method_added");
- removed = rb_intern("method_removed");
- singleton_removed = rb_intern("singleton_method_removed");
- undefined = rb_intern("method_undefined");
- singleton_undefined = rb_intern("singleton_method_undefined");
-
- object_id = rb_intern("object_id");
- __send__ = rb_intern("__send__");
-
rb_define_virtual_variable("$@", errat_getter, errat_setter);
rb_define_virtual_variable("$!", errinfo_getter, 0);
- rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
-
rb_define_global_function("eval", rb_f_eval, -1);
rb_define_global_function("iterator?", rb_f_block_given_p, 0);
rb_define_global_function("block_given?", rb_f_block_given_p, 0);
- rb_define_global_function("loop", rb_f_loop, 0);
- rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
- respond_to = rb_intern("respond_to?");
- basic_respond_to = rb_method_node(rb_cObject, respond_to);
- rb_register_mark_object((VALUE)basic_respond_to);
-
rb_define_global_function("raise", rb_f_raise, -1);
rb_define_global_function("fail", rb_f_raise, -1);
- rb_define_global_function("caller", rb_f_caller, -1);
-
rb_define_global_function("global_variables", rb_f_global_variables, 0); /* in variable.c */
rb_define_global_function("local_variables", rb_f_local_variables, 0);
rb_define_global_function("__method__", rb_f_method_name, 0);
rb_define_global_function("__callee__", rb_f_method_name, 0);
- rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
- rb_define_method(rb_mKernel, "send", rb_f_send, -1);
- rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
-
- rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
- rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
-
rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
rb_define_private_method(rb_cModule, "include", rb_mod_include, -1);
- rb_define_private_method(rb_cModule, "public", rb_mod_public, -1);
- rb_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
- rb_define_private_method(rb_cModule, "private", rb_mod_private, -1);
- rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
- rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
- rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
- rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
- rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
- rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
- rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
- rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
- rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
rb_undef_method(rb_cClass, "module_function");
- Init_eval_method();
+ {
+ extern void Init_vm_eval(void);
+ extern void Init_eval_method(void);
+ Init_vm_eval();
+ Init_eval_method();
+ }
rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
rb_define_singleton_method(rb_vm_top_self(), "include", top_include, -1);
- rb_define_singleton_method(rb_vm_top_self(), "public", top_public, -1);
- rb_define_singleton_method(rb_vm_top_self(), "private", top_private, -1);
rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
@@ -2853,3 +1261,5 @@
{
return GET_THREAD()->parse_in_eval != 0;
}
+
+
Modified: MacRuby/trunk/eval_error.c
===================================================================
--- MacRuby/trunk/eval_error.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/eval_error.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -3,34 +3,6 @@
* included by eval.c
*/
-const char *
-rb_sourcefile(void)
-{
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
-
- if (cfp) {
- return RSTRING_CPTR(cfp->iseq->filename);
- }
- else {
- return 0;
- }
-}
-
-int
-rb_sourceline(void)
-{
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
-
- if (cfp) {
- return vm_get_sourceline(cfp);
- }
- else {
- return 0;
- }
-}
-
static void
warn_printf(const char *fmt, ...)
{
@@ -79,6 +51,12 @@
return rb_check_backtrace(info);
}
+VALUE
+rb_get_backtrace(VALUE info)
+{
+ return get_backtrace(info);
+}
+
static void
set_backtrace(VALUE info, VALUE bt)
{
@@ -210,7 +188,7 @@
void
rb_print_undef(VALUE klass, ID id, int scope)
{
- char *v;
+ const char *v;
switch (scope) {
default:
@@ -269,8 +247,7 @@
error_pos();
warn_printf(": unexpected throw\n");
break;
- case TAG_RAISE:
- case TAG_FATAL: {
+ case TAG_RAISE: {
VALUE errinfo = GET_THREAD()->errinfo;
if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
status = sysexit_status(errinfo);
@@ -283,6 +260,9 @@
}
break;
}
+ case TAG_FATAL:
+ error_print();
+ break;
default:
rb_bug("Unknown longjmp status %d", ex);
break;
Modified: MacRuby/trunk/eval_intern.h
===================================================================
--- MacRuby/trunk/eval_intern.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/eval_intern.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -183,17 +183,10 @@
#define GET_THROWOBJ_CATCH_POINT(obj) ((VALUE*)RNODE((obj))->u2.value)
#define GET_THROWOBJ_STATE(obj) ((int)RNODE((obj))->u3.value)
-#define SCOPE_TEST(f) \
- (ruby_cref()->nd_visi & (f))
+#define SCOPE_TEST(f) (vm_cref()->nd_visi & (f))
+#define SCOPE_CHECK(f) (vm_cref()->nd_visi == (f))
+#define SCOPE_SET(f) (vm_cref()->nd_visi = (f))
-#define SCOPE_CHECK(f) \
- (ruby_cref()->nd_visi == (f))
-
-#define SCOPE_SET(f) \
-{ \
- ruby_cref()->nd_visi = (f); \
-}
-
#define CHECK_STACK_OVERFLOW(cfp, margin) do \
if (((VALUE *)(cfp)->sp) + (margin) + sizeof(rb_control_frame_t) >= ((VALUE *)cfp)) { \
rb_exc_raise(sysstack_error); \
@@ -220,44 +213,17 @@
NORETURN(void rb_fiber_start(void));
-NORETURN(void rb_raise_jump(VALUE));
NORETURN(void rb_print_undef(VALUE, ID, int));
-NORETURN(void vm_localjump_error(const char *, VALUE, int));
+NORETURN(void vm_localjump_error(const char *,VALUE, int));
NORETURN(void vm_jump_tag_but_local_jump(int, VALUE));
-NODE *vm_get_cref(rb_thread_t *th, rb_iseq_t *iseq, rb_control_frame_t *cfp);
-NODE *vm_cref_push(rb_thread_t *th, VALUE, int);
-NODE *vm_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack);
VALUE vm_make_jump_tag_but_local_jump(int state, VALUE val);
-
-static rb_control_frame_t *
-vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
-{
- while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
- if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
- return cfp;
- }
- cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- }
- return 0;
-}
-
-static inline NODE *
-ruby_cref()
-{
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- return vm_get_cref(th, cfp->iseq, cfp);
-}
-
-VALUE vm_get_cbase(rb_thread_t *th);
+NODE *vm_cref(void);
+rb_control_frame_t *vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
VALUE rb_obj_is_proc(VALUE);
-void rb_vm_check_redefinition_opt_method(NODE *node);
-VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, rb_block_t *blockptr, VALUE filename);
+VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, const rb_block_t *blockptr, VALUE filename);
void rb_thread_terminate_all(void);
-void rb_vm_set_eval_stack(rb_thread_t *, VALUE iseq);
VALUE rb_vm_top_self();
+VALUE rb_vm_cbase(void);
-#define ruby_cbase() vm_get_cbase(GET_THREAD())
-
#endif /* RUBY_EVAL_INTERN_H */
Modified: MacRuby/trunk/eval_jump.c
===================================================================
--- MacRuby/trunk/eval_jump.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/eval_jump.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -5,162 +5,6 @@
#include "eval_intern.h"
-NORETURN(static VALUE rb_f_throw _((int, VALUE *)));
-
-/*
- * call-seq:
- * throw(symbol [, obj])
- *
- * Transfers control to the end of the active +catch+ block
- * waiting for _symbol_. Raises +NameError+ if there
- * is no +catch+ block for the symbol. The optional second
- * parameter supplies a return value for the +catch+ block,
- * which otherwise defaults to +nil+. For examples, see
- * <code>Kernel::catch</code>.
- */
-
-static VALUE
-rb_f_throw(int argc, VALUE *argv)
-{
- VALUE tag, value;
- rb_thread_t *th = GET_THREAD();
- struct rb_vm_tag *tt = th->tag;
-
- rb_scan_args(argc, argv, "11", &tag, &value);
- while (tt) {
- if (tt->tag == tag) {
- tt->retval = value;
- break;
- }
- tt = tt->prev;
- }
- if (!tt) {
- VALUE desc = rb_inspect(tag);
- rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_CPTR(desc));
- }
- rb_trap_restore_mask();
- th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW);
-
- JUMP_TAG(TAG_THROW);
-#ifndef __GNUC__
- return Qnil; /* not reached */
-#endif
-}
-
-void
-rb_throw(const char *tag, VALUE val)
-{
- VALUE argv[2];
-
- argv[0] = ID2SYM(rb_intern(tag));
- argv[1] = val;
- rb_f_throw(2, argv);
-}
-
-void
-rb_throw_obj(VALUE tag, VALUE val)
-{
- VALUE argv[2];
-
- argv[0] = tag;
- argv[1] = val;
- rb_f_throw(2, argv);
-}
-
-/*
- * call-seq:
- * catch(symbol) {| | block } > obj
- *
- * +catch+ executes its block. If a +throw+ is
- * executed, Ruby searches up its stack for a +catch+ block
- * with a tag corresponding to the +throw+'s
- * _symbol_. If found, that block is terminated, and
- * +catch+ returns the value given to +throw+. If
- * +throw+ is not called, the block terminates normally, and
- * the value of +catch+ is the value of the last expression
- * evaluated. +catch+ expressions may be nested, and the
- * +throw+ call need not be in lexical scope.
- *
- * def routine(n)
- * puts n
- * throw :done if n <= 0
- * routine(n-1)
- * end
- *
- *
- * catch(:done) { routine(3) }
- *
- * <em>produces:</em>
- *
- * 3
- * 2
- * 1
- * 0
- */
-
-static VALUE
-rb_f_catch(int argc, VALUE *argv)
-{
- VALUE tag;
- int state;
- VALUE val = Qnil; /* OK */
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *saved_cfp = th->cfp;
-
- if (argc == 0) {
- tag = rb_obj_alloc(rb_cObject);
- }
- else {
- rb_scan_args(argc, argv, "01", &tag);
- }
- PUSH_TAG();
-
- th->tag->tag = tag;
-
- if ((state = EXEC_TAG()) == 0) {
- val = rb_yield_0(1, &tag);
- }
- else if (state == TAG_THROW && RNODE(th->errinfo)->u1.value == tag) {
- th->cfp = saved_cfp;
- val = th->tag->retval;
- th->errinfo = Qnil;
- state = 0;
- }
- POP_TAG();
- if (state)
- JUMP_TAG(state);
-
- return val;
-}
-
-static VALUE
-catch_null_i(VALUE dmy)
-{
- return rb_funcall(Qnil, rb_intern("catch"), 0, 0);
-}
-
-static VALUE
-catch_i(VALUE tag)
-{
- return rb_funcall(Qnil, rb_intern("catch"), 1, tag);
-}
-
-VALUE
-rb_catch(const char *tag, VALUE (*func)(), VALUE data)
-{
- if (!tag) {
- return rb_iterate(catch_null_i, 0, func, data);
- }
- return rb_iterate(catch_i, ID2SYM(rb_intern(tag)), func, data);
-}
-
-VALUE
-rb_catch_obj(VALUE tag, VALUE (*func)(), VALUE data)
-{
- return rb_iterate((VALUE (*)_((VALUE)))catch_i, tag, func, data);
-}
-
-
/* exit */
void
@@ -303,8 +147,6 @@
void
Init_jump(void)
{
- rb_define_global_function("catch", rb_f_catch, -1);
- rb_define_global_function("throw", rb_f_throw, -1);
rb_define_global_function("at_exit", rb_f_at_exit, 0);
GC_ROOT(&end_procs);
}
Deleted: MacRuby/trunk/eval_method.c
===================================================================
--- MacRuby/trunk/eval_method.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/eval_method.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,700 +0,0 @@
-/* -*-c-*- */
-/*
- * This file is included by eval.c
- */
-
-#define CACHE_SIZE 0x800
-#define CACHE_MASK 0x7ff
-#define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)
-
-struct cache_entry { /* method hash table. */
- ID mid; /* method's id */
- ID mid0; /* method's original id */
- VALUE klass; /* receiver's class */
- VALUE oklass; /* original's class */
- NODE *method;
-};
-
-static struct cache_entry cache[CACHE_SIZE];
-static int ruby_running = 0;
-
-void
-rb_clear_cache(void)
-{
- struct cache_entry *ent, *end;
-
- rb_vm_change_state();
-
- if (!ruby_running)
- return;
- ent = cache;
- end = ent + CACHE_SIZE;
- while (ent < end) {
- ent->mid = 0;
- ent++;
- }
-}
-
-static void
-rb_clear_cache_for_undef(VALUE klass, ID id)
-{
- struct cache_entry *ent, *end;
-
- rb_vm_change_state();
-
- if (!ruby_running)
- return;
- ent = cache;
- end = ent + CACHE_SIZE;
- while (ent < end) {
- if (ent->oklass == klass && ent->mid == id) {
- ent->mid = 0;
- }
- ent++;
- }
-}
-
-static void
-rb_clear_cache_by_id(ID id)
-{
- struct cache_entry *ent, *end;
-
- rb_vm_change_state();
-
- if (!ruby_running)
- return;
- ent = cache;
- end = ent + CACHE_SIZE;
- while (ent < end) {
- if (ent->mid == id) {
- ent->mid = 0;
- }
- ent++;
- }
-}
-
-void
-rb_clear_cache_by_class(VALUE klass)
-{
- struct cache_entry *ent, *end;
-
- rb_vm_change_state();
-
- if (!ruby_running)
- return;
- ent = cache;
- end = ent + CACHE_SIZE;
- while (ent < end) {
- if (ent->klass == klass || ent->oklass == klass) {
- ent->mid = 0;
- }
- ent++;
- }
-}
-
-#if WITH_OBJC
-void rb_objc_sync_ruby_method(VALUE, ID, NODE*, unsigned);
-#endif
-
-void
-rb_add_method_direct(VALUE klass, ID mid, NODE *node)
-{
- rb_clear_cache_by_id(mid);
- st_insert(RCLASS_M_TBL(klass), (st_data_t)mid, (st_data_t)node);
-}
-
-void
-rb_add_method(VALUE klass, ID mid, NODE * node, int noex)
-{
- NODE *body;
-
- if (NIL_P(klass) || klass == 0) {
- klass = rb_cObject;
- }
- if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
- rb_raise(rb_eSecurityError, "Insecure: can't define method");
- }
- if (!FL_TEST(klass, FL_SINGLETON) &&
- node && nd_type(node) != NODE_ZSUPER &&
- (mid == rb_intern("initialize") || mid == rb_intern("initialize_copy"))) {
- noex = NOEX_PRIVATE | noex;
- }
- else if (FL_TEST(klass, FL_SINGLETON) && node
- && nd_type(node) == NODE_CFUNC && mid == rb_intern("allocate")) {
- rb_warn
- ("defining %s.allocate is deprecated; use rb_define_alloc_func()",
- rb_class2name(rb_iv_get(klass, "__attached__")));
- mid = ID_ALLOCATOR;
- }
- if (OBJ_FROZEN(klass)) {
- rb_error_frozen("class/module");
- }
- rb_clear_cache_by_id(mid);
-
- /*
- * NODE_METHOD (NEW_METHOD(body, klass, vis)):
- * nd_body : method body // (2) // mark
- * nd_clss : klass // (1) // mark
- * nd_noex : visibility // (3)
- *
- * NODE_FBODY (NEW_FBODY(method, alias)):
- * nd_body : method (NODE_METHOD) // (2) // mark
- * nd_oid : original id // (1)
- * nd_cnt : alias count // (3)
- */
- if (node) {
- body = NEW_FBODY(NEW_METHOD(node, klass, NOEX_WITH_SAFE(noex)), 0);
- }
- else {
- body = 0;
- }
-
- {
- /* check re-definition */
- st_data_t data;
- NODE *old_node;
-
- if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) {
- old_node = (NODE *)data;
- if (old_node) {
- if (nd_type(old_node->nd_body->nd_body) == NODE_CFUNC) {
- rb_vm_check_redefinition_opt_method(old_node);
- }
- if (RTEST(ruby_verbose) && node && old_node->nd_cnt == 0 && old_node->nd_body) {
- rb_warning("method redefined; discarding old %s", rb_id2name(mid));
- }
- }
- }
- if (klass == rb_cObject && node && mid == init) {
- rb_warn("redefining Object#initialize may cause infinite loop");
- }
-
- if (mid == object_id || mid == __send__) {
- if (node && nd_type(node) == RUBY_VM_METHOD_NODE) {
- rb_warn("redefining `%s' may cause serious problem",
- rb_id2name(mid));
- }
- }
- }
-
- st_insert(RCLASS_M_TBL(klass), mid, (st_data_t) body);
-
-#if WITH_OBJC
- if (node != NULL && noex == NOEX_PUBLIC) {
- unsigned override = !FL_TEST(klass, FL_SINGLETON);
- rb_objc_sync_ruby_method(klass, mid, node, override);
- }
-#endif
-
- if (node && mid != ID_ALLOCATOR && ruby_running) {
- if (FL_TEST(klass, FL_SINGLETON)) {
- rb_funcall(rb_iv_get(klass, "__attached__"), singleton_added, 1,
- ID2SYM(mid));
- }
- else {
- rb_funcall(klass, added, 1, ID2SYM(mid));
- }
- }
-}
-
-void
-rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE))
-{
- Check_Type(klass, T_CLASS);
- rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0),
- NOEX_PRIVATE);
-}
-
-void
-rb_undef_alloc_func(VALUE klass)
-{
- Check_Type(klass, T_CLASS);
- rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
-}
-
-rb_alloc_func_t
-rb_get_alloc_func(VALUE klass)
-{
- NODE *n;
- Check_Type(klass, T_CLASS);
- n = rb_method_node(CLASS_OF(klass), ID_ALLOCATOR);
- if (!n) return 0;
- if (nd_type(n) != NODE_METHOD) return 0;
- n = n->nd_body;
- if (nd_type(n) != NODE_CFUNC) return 0;
- return (rb_alloc_func_t)n->nd_cfnc;
-}
-
-static NODE *
-search_method(VALUE klass, ID id, VALUE *klassp)
-{
- st_data_t body;
-
- if (!klass) {
- return 0;
- }
-
- while (!st_lookup(RCLASS_M_TBL(klass), id, &body)) {
- klass = RCLASS_SUPER(klass);
- if (!klass)
- return 0;
- }
-
- if (klassp) {
- *klassp = klass;
- }
-
- return (NODE *)body;
-}
-
-/*
- * search method body (NODE_METHOD)
- * with : klass and id
- * without : method cache
- *
- * if you need method node with method cache, use
- * rb_method_node()
- */
-NODE *
-rb_get_method_body(VALUE klass, ID id, ID *idp)
-{
- NODE *volatile fbody, *body;
- NODE *method;
-
- if ((fbody = search_method(klass, id, 0)) == 0 || !fbody->nd_body) {
- /* store empty info in cache */
- struct cache_entry *ent;
- ent = cache + EXPR1(klass, id);
- ent->klass = klass;
- ent->mid = ent->mid0 = id;
- ent->method = 0;
- ent->oklass = 0;
- return 0;
- }
-
- method = fbody->nd_body;
-
- if (ruby_running) {
- /* store in cache */
- struct cache_entry *ent;
- ent = cache + EXPR1(klass, id);
- ent->klass = klass;
- ent->mid = id;
- ent->mid0 = fbody->nd_oid;
- ent->method = body = method;
- ent->oklass = method->nd_clss;
- }
- else {
- body = method;
- }
-
- if (idp) {
- *idp = fbody->nd_oid;
- }
-
- return body;
-}
-
-NODE *
-rb_method_node(VALUE klass, ID id)
-{
- struct cache_entry *ent;
-
- ent = cache + EXPR1(klass, id);
- if (ent->mid == id && ent->klass == klass && ent->method) {
- return ent->method;
- }
-
- return rb_get_method_body(klass, id, 0);
-}
-
-static void
-remove_method(VALUE klass, ID mid)
-{
- st_data_t data;
- NODE *body = 0;
-
- if (klass == rb_cObject) {
- rb_secure(4);
- }
- if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
- rb_raise(rb_eSecurityError, "Insecure: can't remove method");
- }
- if (OBJ_FROZEN(klass))
- rb_error_frozen("class/module");
- if (mid == object_id || mid == __send__ || mid == init) {
- rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
- }
- if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) {
- body = (NODE *)data;
- if (!body || !body->nd_body) body = 0;
- else {
- st_delete(RCLASS_M_TBL(klass), &mid, &data);
- }
- }
- if (!body) {
- rb_name_error(mid, "method `%s' not defined in %s",
- rb_id2name(mid), rb_class2name(klass));
- }
-
- if (nd_type(body->nd_body->nd_body) == NODE_CFUNC) {
- rb_vm_check_redefinition_opt_method(body);
- }
-
- rb_clear_cache_for_undef(klass, mid);
- if (FL_TEST(klass, FL_SINGLETON)) {
- rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1,
- ID2SYM(mid));
- }
- else {
- rb_funcall(klass, removed, 1, ID2SYM(mid));
- }
-}
-
-void
-rb_remove_method(VALUE klass, const char *name)
-{
- remove_method(klass, rb_intern(name));
-}
-
-/*
- * call-seq:
- * remove_method(symbol) => self
- *
- * Removes the method identified by _symbol_ from the current
- * class. For an example, see <code>Module.undef_method</code>.
- */
-
-static VALUE
-rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
-{
- int i;
-
- for (i = 0; i < argc; i++) {
- remove_method(mod, rb_to_id(argv[i]));
- }
- return mod;
-}
-
-#undef rb_disable_super
-#undef rb_enable_super
-
-void
-rb_disable_super(VALUE klass, const char *name)
-{
- /* obsolete - no use */
-}
-
-void
-rb_enable_super(VALUE klass, const char *name)
-{
- rb_warning("rb_enable_super() is obsolete");
-}
-
-static void
-rb_export_method(VALUE klass, ID name, ID noex)
-{
- NODE *fbody;
- VALUE origin;
-
- if (klass == rb_cObject) {
- rb_secure(4);
- }
- fbody = search_method(klass, name, &origin);
- if (!fbody && TYPE(klass) == T_MODULE) {
- fbody = search_method(rb_cObject, name, &origin);
- }
- if (!fbody || !fbody->nd_body) {
- rb_print_undef(klass, name, 0);
- }
- if (fbody->nd_body->nd_noex != noex) {
- if (nd_type(fbody->nd_body->nd_body) == NODE_CFUNC) {
- rb_vm_check_redefinition_opt_method(fbody);
- }
- if (klass == origin) {
- fbody->nd_body->nd_noex = noex;
- }
- else {
- rb_add_method(klass, name, NEW_ZSUPER(), noex);
- }
- }
-}
-
-int
-rb_method_boundp(VALUE klass, ID id, int ex)
-{
- NODE *method;
-
- if ((method = rb_method_node(klass, id)) != 0) {
- if (ex && (method->nd_noex & NOEX_PRIVATE)) {
- return Qfalse;
- }
- return Qtrue;
- }
- return Qfalse;
-}
-
-void
-rb_attr(VALUE klass, ID id, int read, int write, int ex)
-{
- const char *name;
- ID attriv;
- int noex;
-
- if (!ex) {
- noex = NOEX_PUBLIC;
- }
- else {
- if (SCOPE_TEST(NOEX_PRIVATE)) {
- noex = NOEX_PRIVATE;
- rb_warning((SCOPE_CHECK(NOEX_MODFUNC)) ?
- "attribute accessor as module_function" :
- "private attribute?");
- }
- else if (SCOPE_TEST(NOEX_PROTECTED)) {
- noex = NOEX_PROTECTED;
- }
- else {
- noex = NOEX_PUBLIC;
- }
- }
-
- if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
- rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
- }
- name = rb_id2name(id);
- if (!name) {
- rb_raise(rb_eArgError, "argument needs to be symbol or string");
- }
- attriv = rb_intern_str(rb_sprintf("@%s", name));
- if (read) {
- rb_add_method(klass, id, NEW_IVAR(attriv), noex);
- }
- if (write) {
- rb_add_method(klass, rb_id_attrset(id), NEW_ATTRSET(attriv), noex);
- }
-}
-
-void
-rb_undef(VALUE klass, ID id)
-{
- VALUE origin;
- NODE *body;
-
- if (ruby_cbase() == rb_cObject && klass == rb_cObject) {
- rb_secure(4);
- }
- if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
- rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
- rb_id2name(id));
- }
- rb_frozen_class_p(klass);
- if (id == object_id || id == __send__ || id == init) {
- rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
- }
-#if WITH_OBJC
- /* TODO: we should only warn regarding important NSObject methods that
- are necessary by the GC to call finalizers. */
- if (class_respondsToSelector(RCLASS_OCID(rb_cBasicObject),
- sel_registerName(rb_id2name(id)))) {
- rb_warn("undefining `NSObject#%s' may cause serious problem",
- rb_id2name(id));
- }
-#endif
- body = search_method(klass, id, &origin);
- if (!body || !body->nd_body) {
- char *s0 = " class";
- VALUE c = klass;
-
- if (FL_TEST(c, FL_SINGLETON)) {
- VALUE obj = rb_iv_get(klass, "__attached__");
-
- switch (TYPE(obj)) {
- case T_MODULE:
- case T_CLASS:
- c = obj;
- s0 = "";
- }
- }
- else if (TYPE(c) == T_MODULE) {
- s0 = " module";
- }
-#if WITH_OBJC
- if (!class_respondsToSelector(RCLASS(klass)->ocklass,
- sel_registerName(rb_id2name(id))))
-#endif
- rb_name_error(id, "undefined method `%s' for%s `%s'",
- rb_id2name(id), s0, rb_class2name(c));
- }
-
- rb_add_method(klass, id, 0, NOEX_PUBLIC);
-
-#if WITH_OBJC
- {
- Method method;
- method = class_getInstanceMethod(RCLASS(klass)->ocklass,
- sel_registerName(rb_id2name(id)));
- if (method != NULL)
- method_setImplementation(method, NULL);
- }
-#endif
-
- if (FL_TEST(klass, FL_SINGLETON)) {
- rb_funcall(rb_iv_get(klass, "__attached__"),
- singleton_undefined, 1, ID2SYM(id));
- }
- else {
- rb_funcall(klass, undefined, 1, ID2SYM(id));
- }
-}
-
-/*
- * call-seq:
- * undef_method(symbol) => self
- *
- * Prevents the current class from responding to calls to the named
- * method. Contrast this with <code>remove_method</code>, which deletes
- * the method from the particular class; Ruby will still search
- * superclasses and mixed-in modules for a possible receiver.
- *
- * class Parent
- * def hello
- * puts "In parent"
- * end
- * end
- * class Child < Parent
- * def hello
- * puts "In child"
- * end
- * end
- *
- *
- * c = Child.new
- * c.hello
- *
- *
- * class Child
- * remove_method :hello # remove from child, still in parent
- * end
- * c.hello
- *
- *
- * class Child
- * undef_method :hello # prevent any calls to 'hello'
- * end
- * c.hello
- *
- * <em>produces:</em>
- *
- * In child
- * In parent
- * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
- */
-
-static VALUE
-rb_mod_undef_method(int argc, VALUE *argv, VALUE mod)
-{
- int i;
- for (i = 0; i < argc; i++) {
- rb_undef(mod, rb_to_id(argv[i]));
- }
- return mod;
-}
-
-void
-rb_alias(VALUE klass, ID name, ID def)
-{
- NODE *orig_fbody, *node;
- VALUE singleton = 0;
- st_data_t data;
-
- rb_frozen_class_p(klass);
- if (klass == rb_cObject) {
- rb_secure(4);
- }
- orig_fbody = search_method(klass, def, 0);
- if (!orig_fbody || !orig_fbody->nd_body) {
- if (TYPE(klass) == T_MODULE) {
- orig_fbody = search_method(rb_cObject, def, 0);
- }
- }
- if (!orig_fbody || !orig_fbody->nd_body) {
- rb_print_undef(klass, def, 0);
- }
- if (FL_TEST(klass, FL_SINGLETON)) {
- singleton = rb_iv_get(klass, "__attached__");
- }
-
- orig_fbody->nd_cnt++;
-
- if (st_lookup(RCLASS_M_TBL(klass), name, &data)) {
- node = (NODE *)data;
- if (node) {
- if (RTEST(ruby_verbose) && node->nd_cnt == 0 && node->nd_body) {
- rb_warning("discarding old %s", rb_id2name(name));
- }
- if (nd_type(node->nd_body->nd_body) == NODE_CFUNC) {
- rb_vm_check_redefinition_opt_method(node);
- }
- }
- }
-
- st_insert(RCLASS_M_TBL(klass), name,
- (st_data_t) NEW_FBODY(
- NEW_METHOD(orig_fbody->nd_body->nd_body,
- orig_fbody->nd_body->nd_clss,
- NOEX_WITH_SAFE(orig_fbody->nd_body->nd_noex)), def));
-
-#if WITH_OBJC
- if (orig_fbody->nd_body->nd_noex == NOEX_PUBLIC)
- rb_objc_sync_ruby_method(klass, name, orig_fbody->nd_body->nd_body, 0);
-#endif
-
- rb_clear_cache_by_id(name);
-
- if (!ruby_running) return;
-
- if (singleton) {
- rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
- }
- else {
- rb_funcall(klass, added, 1, ID2SYM(name));
- }
-}
-
-/*
- * call-seq:
- * alias_method(new_name, old_name) => self
- *
- * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
- * be used to retain access to methods that are overridden.
- *
- * module Mod
- * alias_method :orig_exit, :exit
- * def exit(code=0)
- * puts "Exiting with code #{code}"
- * orig_exit(code)
- * end
- * end
- * include Mod
- * exit(99)
- *
- * <em>produces:</em>
- *
- * Exiting with code 99
- */
-
-static VALUE
-rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
-{
- rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
- return mod;
-}
-
-static void
-Init_eval_method(void)
-{
- rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
- rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
- rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
-}
Modified: MacRuby/trunk/ext/nkf/nkf-utf8/nkf.c
===================================================================
--- MacRuby/trunk/ext/nkf/nkf-utf8/nkf.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/nkf/nkf-utf8/nkf.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,39 +1,39 @@
/** Network Kanji Filter. (PDS Version)
-** -*- coding: ISO-2022-JP -*-
-************************************************************************
-** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
-** $BO"Mm at h!'(B $B!J3t!KIY;NDL8&5f=j!!%=%U%H#38&!!;T at n!!;j(B
-** $B!J(BE-Mail Address: ichikawa at flab.fujitsu.co.jp$B!K(B
-** Copyright (C) 1996,1998
-** Copyright (C) 2002
-** $BO"Mm at h!'(B $BN05eBg3X>pJs9)3X2J(B $B2OLn(B $B??<#(B mime/X0208 support
-** $B!J(BE-Mail Address: kono at ie.u-ryukyu.ac.jp$B!K(B
-** $BO"Mm at h!'(B COW for DOS & Win16 & Win32 & OS/2
-** $B!J(BE-Mail Address: GHG00637 at niftyserve.or.p$B!K(B
-**
-** $B$3$N%=!<%9$N$$$+$J$kJ#<L!$2~JQ!$=$@5$b5vBz$7$^$9!#$?$@$7!"(B
-** $B$=$N:]$K$O!"C/$,9W8%$7$?$r<($9$3$NItJ,$r;D$9$3$H!#(B
-** $B:FG[I[$d;(;o$NIUO?$J$I$NLd$$9g$o$;$bI,MW$"$j$^$;$s!#(B
-** $B1DMxMxMQ$b>e5-$KH?$7$J$$HO0O$G5v2D$7$^$9!#(B
-** $B%P%$%J%j$NG[I[$N:]$K$O(Bversion message$B$rJ]B8$9$k$3$H$r>r7o$H$7$^$9!#(B
-** $B$3$N%W%m%0%i%`$K$D$$$F$OFC$K2?$NJ]>Z$b$7$J$$!"0-$7$+$i$:!#(B
-**
-** Everyone is permitted to do anything on this program
-** including copying, modifying, improving,
-** as long as you don't try to pretend that you wrote it.
-** i.e., the above copyright notice has to appear in all copies.
-** Binary distribution requires original version messages.
-** You don't have to ask before copying, redistribution or publishing.
-** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
-***********************************************************************/
+ ** -*- coding: ISO-2022-JP -*-
+ ************************************************************************
+ ** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
+ ** $BO"Mm at h!'(B $B!J3t!KIY;NDL8&5f=j!!%=%U%H#38&!!;T at n!!;j(B
+ ** $B!J(BE-Mail Address: ichikawa at flab.fujitsu.co.jp$B!K(B
+ ** Copyright (C) 1996,1998
+ ** Copyright (C) 2002
+ ** $BO"Mm at h!'(B $BN05eBg3X>pJs9)3X2J(B $B2OLn(B $B??<#(B mime/X0208 support
+ ** $B!J(BE-Mail Address: kono at ie.u-ryukyu.ac.jp$B!K(B
+ ** $BO"Mm at h!'(B COW for DOS & Win16 & Win32 & OS/2
+ ** $B!J(BE-Mail Address: GHG00637 at niftyserve.or.p$B!K(B
+ **
+ ** $B$3$N%=!<%9$N$$$+$J$kJ#<L!$2~JQ!$=$@5$b5vBz$7$^$9!#$?$@$7!"(B
+ ** $B$=$N:]$K$O!"C/$,9W8%$7$?$r<($9$3$NItJ,$r;D$9$3$H!#(B
+ ** $B:FG[I[$d;(;o$NIUO?$J$I$NLd$$9g$o$;$bI,MW$"$j$^$;$s!#(B
+ ** $B1DMxMxMQ$b>e5-$KH?$7$J$$HO0O$G5v2D$7$^$9!#(B
+ ** $B%P%$%J%j$NG[I[$N:]$K$O(Bversion message$B$rJ]B8$9$k$3$H$r>r7o$H$7$^$9!#(B
+ ** $B$3$N%W%m%0%i%`$K$D$$$F$OFC$K2?$NJ]>Z$b$7$J$$!"0-$7$+$i$:!#(B
+ **
+ ** Everyone is permitted to do anything on this program
+ ** including copying, modifying, improving,
+ ** as long as you don't try to pretend that you wrote it.
+ ** i.e., the above copyright notice has to appear in all copies.
+ ** Binary distribution requires original version messages.
+ ** You don't have to ask before copying, redistribution or publishing.
+ ** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+ ***********************************************************************/
/***********************************************************************
* $B8=:_!"(Bnkf $B$O(B SorceForge $B$K$F%a%s%F%J%s%9$,B3$1$i$l$F$$$^$9!#(B
* http://sourceforge.jp/projects/nkf/
-***********************************************************************/
-#define NKF_IDENT "$Id: nkf.c 16149 2008-04-22 12:20:36Z naruse $"
+ ***********************************************************************/
+#define NKF_IDENT "$Id: nkf.c 16515 2008-05-21 21:23:51Z naruse $"
#define NKF_VERSION "2.0.8"
-#define NKF_RELEASE_DATE "2008-01-23"
+#define NKF_RELEASE_DATE "2008-02-08"
#define COPY_RIGHT \
"Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW\n" \
"Copyright (C) 2002-2008 Kono, Furukawa, Naruse, mastodon"
@@ -45,10 +45,10 @@
/* state of output_mode and input_mode
c2 0 means ASCII
- JIS_X_0201
- ISO_8859_1
- JIS_X_0208
- EOF all termination
+ JIS_X_0201_1976_K
+ ISO_8859_1
+ JIS_X_0208
+ EOF all termination
c1 32bit data
*/
@@ -74,12 +74,10 @@
#define CR 0x0d
#define ESC 0x1b
#define SP 0x20
-#define AT 0x40
-#define SSP 0xa0
#define DEL 0x7f
#define SI 0x0f
#define SO 0x0e
-#define SSO 0x8e
+#define SS2 0x8e
#define SS3 0x8f
#define CRLF 0x0D0A
@@ -95,10 +93,12 @@
CP50222,
ISO_2022_JP_1,
ISO_2022_JP_3,
+ ISO_2022_JP_2004,
SHIFT_JIS,
WINDOWS_31J,
CP10001,
EUC_JP,
+ EUCJP_NKF,
CP51932,
EUCJP_MS,
EUCJP_ASCII,
@@ -120,26 +120,30 @@
UTF_32BE_BOM,
UTF_32LE,
UTF_32LE_BOM,
+ BINARY,
NKF_ENCODING_TABLE_SIZE,
- JIS_X_0201=0x1000,
- JIS_X_0208=0x1001,
- JIS_X_0212=0x1002,
- JIS_X_0213_1=0x1003,
- JIS_X_0213_2=0x1004,
- BINARY
+ JIS_X_0201_1976_K = 0x1013, /* I */ /* JIS C 6220-1969 */
+ /* JIS_X_0201_1976_R = 0x1014, */ /* J */ /* JIS C 6220-1969 */
+ /* JIS_X_0208_1978 = 0x1040, */ /* @ */ /* JIS C 6226-1978 */
+ /* JIS_X_0208_1983 = 0x1087, */ /* B */ /* JIS C 6226-1983 */
+ JIS_X_0208 = 0x1168, /* @B */
+ JIS_X_0212 = 0x1159, /* D */
+ /* JIS_X_0213_2000_1 = 0x1228, */ /* O */
+ JIS_X_0213_2 = 0x1229, /* P */
+ JIS_X_0213_1 = 0x1233, /* Q */
};
-nkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
-nkf_char e_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
-nkf_char w_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
-nkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0);
-nkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0);
-void j_oconv(nkf_char c2, nkf_char c1);
-void s_oconv(nkf_char c2, nkf_char c1);
-void e_oconv(nkf_char c2, nkf_char c1);
-void w_oconv(nkf_char c2, nkf_char c1);
-void w_oconv16(nkf_char c2, nkf_char c1);
-void w_oconv32(nkf_char c2, nkf_char c1);
+static nkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
+static nkf_char e_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
+static nkf_char w_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
+static nkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0);
+static nkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0);
+static void j_oconv(nkf_char c2, nkf_char c1);
+static void s_oconv(nkf_char c2, nkf_char c1);
+static void e_oconv(nkf_char c2, nkf_char c1);
+static void w_oconv(nkf_char c2, nkf_char c1);
+static void w_oconv16(nkf_char c2, nkf_char c1);
+static void w_oconv32(nkf_char c2, nkf_char c1);
typedef struct {
const char *name;
@@ -170,10 +174,12 @@
{CP50222, "CP50222", &NkfEncodingISO_2022_JP},
{ISO_2022_JP_1, "ISO-2022-JP-1", &NkfEncodingISO_2022_JP},
{ISO_2022_JP_3, "ISO-2022-JP-3", &NkfEncodingISO_2022_JP},
+ {ISO_2022_JP_2004, "ISO-2022-JP-2004", &NkfEncodingISO_2022_JP},
{SHIFT_JIS, "Shift_JIS", &NkfEncodingShift_JIS},
{WINDOWS_31J, "Windows-31J", &NkfEncodingShift_JIS},
{CP10001, "CP10001", &NkfEncodingShift_JIS},
{EUC_JP, "EUC-JP", &NkfEncodingEUC_JP},
+ {EUCJP_NKF, "eucJP-nkf", &NkfEncodingEUC_JP},
{CP51932, "CP51932", &NkfEncodingEUC_JP},
{EUCJP_MS, "eucJP-MS", &NkfEncodingEUC_JP},
{EUCJP_ASCII, "eucJP-ASCII", &NkfEncodingEUC_JP},
@@ -209,9 +215,11 @@
{"ISO2022JP-CP932", CP50220},
{"CP50220", CP50220},
{"CP50221", CP50221},
+ {"CSISO2022JP", CP50221},
{"CP50222", CP50222},
{"ISO-2022-JP-1", ISO_2022_JP_1},
{"ISO-2022-JP-3", ISO_2022_JP_3},
+ {"ISO-2022-JP-2004", ISO_2022_JP_2004},
{"SHIFT_JIS", SHIFT_JIS},
{"SJIS", SHIFT_JIS},
{"WINDOWS-31J", WINDOWS_31J},
@@ -221,6 +229,7 @@
{"CP10001", CP10001},
{"EUCJP", EUC_JP},
{"EUC-JP", EUC_JP},
+ {"EUCJP-NKF", EUCJP_NKF},
{"CP51932", CP51932},
{"EUC-JP-MS", EUCJP_MS},
{"EUCJP-MS", EUCJP_MS},
@@ -258,13 +267,11 @@
#define DEFAULT_ENCIDX EUC_JP
#elif defined(DEFAULT_CODE_UTF8)
#define DEFAULT_ENCIDX UTF_8
-#else
-#define DEFAULT_ENCIDX 0
#endif
#define is_alnum(c) \
- (('a'<=c && c<='z')||('A'<= c && c<='Z')||('0'<=c && c<='9'))
+ (('a'<=c && c<='z')||('A'<= c && c<='Z')||('0'<=c && c<='9'))
/* I don't trust portablity of toupper */
#define nkf_toupper(c) (('a'<=c && c<='z')?(c-('a'-'A')):c)
@@ -278,15 +285,16 @@
#define nkf_isprint(c) (SP<=c && c<='~')
#define nkf_isgraph(c) ('!'<=c && c<='~')
#define hex2bin(c) (('0'<=c&&c<='9') ? (c-'0') : \
- ('A'<=c&&c<='F') ? (c-'A'+10) : \
- ('a'<=c&&c<='f') ? (c-'a'+10) : 0)
+ ('A'<=c&&c<='F') ? (c-'A'+10) : \
+ ('a'<=c&&c<='f') ? (c-'a'+10) : 0)
#define bin2hex(c) ("0123456789ABCDEF"[c&15])
#define is_eucg3(c2) (((unsigned short)c2 >> 8) == SS3)
#define nkf_noescape_mime(c) ((c == CR) || (c == LF) || \
- ((c > SP) && (c < DEL) && (c != '?') && (c != '=') && (c != '_') \
- && (c != '(') && (c != ')') && (c != '.') && (c != 0x22)))
+ ((c > SP) && (c < DEL) && (c != '?') && (c != '=') && (c != '_') \
+ && (c != '(') && (c != ')') && (c != '.') && (c != 0x22)))
#define is_ibmext_in_sjis(c2) (CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END)
+#define nkf_byte_jisx0201_katakana_p(c) (SP <= c && c < (0xE0&0x7F))
#define HOLD_SIZE 1024
#if defined(INT_IS_SHORT)
@@ -324,8 +332,7 @@
static nkf_encoding *input_encoding = NULL;
static nkf_encoding *output_encoding = NULL;
-static nkf_char kanji_convert(FILE *f);
-static nkf_char h_conv(FILE *f,nkf_char c2,nkf_char c1);
+static int kanji_convert(FILE *f);
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
/* UCS Mapping
* 0: Shift_JIS, eucJP-ascii
@@ -353,12 +360,6 @@
static int output_bom_f = FALSE;
static int output_endian = ENDIAN_BIG;
#endif
-static void fold_conv(nkf_char c2,nkf_char c1);
-static void eol_conv(nkf_char c2,nkf_char c1);
-static void z_conv(nkf_char c2,nkf_char c1);
-static void rot_conv(nkf_char c2,nkf_char c1);
-static void hira_conv(nkf_char c2,nkf_char c1);
-static void iso2022jp_check_conv(nkf_char c2,nkf_char c1);
static void std_putc(nkf_char c);
static nkf_char std_getc(FILE *f);
@@ -411,13 +412,17 @@
static nkf_char (*i_uungetc)(nkf_char c ,FILE *f) = std_ungetc;
#endif
-#define PREFIX_EUCG3 NKF_INT32_C(0x8F00)
-#define CLASS_MASK NKF_INT32_C(0xFF000000)
-#define CLASS_UNICODE NKF_INT32_C(0x01000000)
-#define VALUE_MASK NKF_INT32_C(0x00FFFFFF)
-#define UNICODE_MAX NKF_INT32_C(0x0010FFFF)
-#define is_unicode_capsule(c) ((c & CLASS_MASK) == CLASS_UNICODE)
-#define is_unicode_bmp(c) ((c & VALUE_MASK) <= NKF_INT32_C(0xFFFF))
+#define PREFIX_EUCG3 NKF_INT32_C(0x8F00)
+#define CLASS_MASK NKF_INT32_C(0xFF000000)
+#define CLASS_UNICODE NKF_INT32_C(0x01000000)
+#define VALUE_MASK NKF_INT32_C(0x00FFFFFF)
+#define UNICODE_BMP_MAX NKF_INT32_C(0x0000FFFF)
+#define UNICODE_MAX NKF_INT32_C(0x0010FFFF)
+#define nkf_char_euc3_new(c) ((c) | PREFIX_EUCG3)
+#define nkf_char_unicode_new(c) ((c) | CLASS_UNICODE)
+#define nkf_char_unicode_p(c) ((c & CLASS_MASK) == CLASS_UNICODE)
+#define nkf_char_unicode_bmp_p(c) ((c & VALUE_MASK) <= NKF_INT32_C(UNICODE_BMP_MAX))
+#define nkf_char_unicode_value_p(c) ((c & VALUE_MASK) <= NKF_INT32_C(UNICODE_MAX))
#ifdef NUMCHAR_OPTION
static int numchar_f = FALSE;
@@ -450,9 +455,7 @@
/* static nkf_char cp932_conv(nkf_char c2, nkf_char c1); */
#endif /* SHIFTJIS_CP932 */
-#ifdef X0212_ENABLE
static int x0212_f = FALSE;
-#endif
static int x0213_f = FALSE;
static unsigned char prefix_table[256];
@@ -465,8 +468,6 @@
{"Shift_JIS", 0, 0, 0, {0, 0, 0}, s_status, s_iconv, 0},
#ifdef UTF8_INPUT_ENABLE
{"UTF-8", 0, 0, 0, {0, 0, 0}, w_status, w_iconv, 0},
- {"UTF-16", 0, 0, 0, {0, 0, 0}, NULL, w_iconv16, 0},
- {"UTF-32", 0, 0, 0, {0, 0, 0}, NULL, w_iconv32, 0},
#endif
{0}
};
@@ -496,14 +497,16 @@
/* process default */
-nkf_char no_connection2(nkf_char c2, nkf_char c1, nkf_char c0)
+static nkf_char
+no_connection2(nkf_char c2, nkf_char c1, nkf_char c0)
{
fprintf(stderr,"nkf internal module connection failure.\n");
exit(1);
return 0; /* LINT */
}
-void no_connection(nkf_char c2, nkf_char c1)
+static void
+no_connection(nkf_char c2, nkf_char c1)
{
no_connection2(c2,c1,0);
}
@@ -539,9 +542,8 @@
static nkf_char (*i_mungetc_buf)(nkf_char c,FILE *f) = std_ungetc;
/* Global states */
-static int output_mode = ASCII, /* output kanji mode */
- input_mode = ASCII, /* input kanji mode */
- shift_mode = FALSE; /* TRUE shift out, or X0201 */
+static int output_mode = ASCII; /* output kanji mode */
+static int input_mode = ASCII; /* input kanji mode */
static int mime_decode_mode = FALSE; /* MIME mode B base64, Q hex */
/* X0201 / X0208 conversion tables */
@@ -651,49 +653,41 @@
nkf_char std_gc_buf[STD_GC_BUFSIZE];
nkf_char std_gc_ndx;
-char* nkf_strcpy(const char *str)
+static int
+nkf_str_caseeql(const char *src, const char *target)
{
- char* result = malloc(strlen(str) + 1);
- if (!result){
- perror(str);
- return "";
+ int i;
+ for (i = 0; src[i] && target[i]; i++) {
+ if (nkf_toupper(src[i]) != nkf_toupper(target[i])) return FALSE;
}
- strcpy(result, str);
- return result;
+ if (src[i] || target[i]) return FALSE;
+ else return TRUE;
}
-static void nkf_str_upcase(const char *src, char *dest, size_t length)
+static nkf_encoding*
+nkf_enc_from_index(int idx)
{
- int i = 0;
- for (; i < length && src[i]; i++) {
- dest[i] = nkf_toupper(src[i]);
- }
- dest[i] = 0;
-}
-
-static nkf_encoding *nkf_enc_from_index(int idx)
-{
if (idx < 0 || NKF_ENCODING_TABLE_SIZE <= idx) {
- if (idx == BINARY)
- return &nkf_encoding_table[NKF_ENCODING_TABLE_SIZE];
return 0;
}
return &nkf_encoding_table[idx];
}
-static int nkf_enc_find_index(const char *name)
+static int
+nkf_enc_find_index(const char *name)
{
- int i, index = -1;
- if (*name == 'X' && *(name+1) == '-') name += 2;
+ int i;
+ if (name[0] == 'X' && *(name+1) == '-') name += 2;
for (i = 0; encoding_name_to_id_table[i].id >= 0; i++) {
- if (strcmp(name, encoding_name_to_id_table[i].name) == 0) {
+ if (nkf_str_caseeql(encoding_name_to_id_table[i].name, name)) {
return encoding_name_to_id_table[i].id;
}
}
- return index;
+ return -1;
}
-static nkf_encoding *nkf_enc_find(const char *name)
+static nkf_encoding*
+nkf_enc_find(const char *name)
{
int idx = -1;
idx = nkf_enc_find_index(name);
@@ -707,19 +701,20 @@
#define nkf_enc_to_iconv(enc) nkf_enc_to_base_encoding(enc)->iconv
#define nkf_enc_to_oconv(enc) nkf_enc_to_base_encoding(enc)->oconv
#define nkf_enc_asciicompat(enc) (\
- nkf_enc_to_base_encoding(enc) == &NkfEncodingASCII ||\
- nkf_enc_to_base_encoding(enc) == &NkfEncodingISO_2022_JP)
+ nkf_enc_to_base_encoding(enc) == &NkfEncodingASCII ||\
+ nkf_enc_to_base_encoding(enc) == &NkfEncodingISO_2022_JP)
#define nkf_enc_unicode_p(enc) (\
- nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_8 ||\
- nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_16 ||\
- nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_32)
+ nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_8 ||\
+ nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_16 ||\
+ nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_32)
#define nkf_enc_cp5022x_p(enc) (\
- nkf_enc_to_index(enc) == CP50220 ||\
- nkf_enc_to_index(enc) == CP50221 ||\
- nkf_enc_to_index(enc) == CP50222)
+ nkf_enc_to_index(enc) == CP50220 ||\
+ nkf_enc_to_index(enc) == CP50221 ||\
+ nkf_enc_to_index(enc) == CP50222)
#ifdef DEFAULT_CODE_LOCALE
-static char* nkf_locale_charmap()
+static char*
+nkf_locale_charmap()
{
#ifdef HAVE_LANGINFO_H
return nl_langinfo(CODESET);
@@ -730,7 +725,8 @@
#endif
}
-static nkf_encoding* nkf_locale_encoding()
+static nkf_encoding*
+nkf_locale_encoding()
{
nkf_encoding *enc = 0;
char *encname = nkf_locale_charmap();
@@ -741,15 +737,16 @@
}
#endif /* DEFAULT_CODE_LOCALE */
-static nkf_encoding* nkf_default_encoding()
+static nkf_encoding*
+nkf_default_encoding()
{
+ nkf_encoding *enc = 0;
#ifdef DEFAULT_CODE_LOCALE
- nkf_encoding *enc = nkf_locale_encoding();
- if (enc <= 0) enc = nkf_enc_from_index(ISO_2022_JP);
+ enc = nkf_locale_encoding();
+#elif DEFAULT_ENCIDX
+ enc = nkf_enc_from_index(DEFAULT_ENCIDX);
+#endif
return enc;
-#else
- return nkf_enc_from_index(DEFAULT_ENCIDX);
-#endif
}
#ifndef PERL_XS
@@ -757,12 +754,14 @@
#define fprintf dllprintf
#endif
-void version(void)
+static void
+version(void)
{
fprintf(HELP_OUTPUT,"Network Kanji Filter Version " NKF_VERSION " (" NKF_RELEASE_DATE ") \n" COPY_RIGHT "\n");
}
-void usage(void)
+static void
+usage(void)
{
fprintf(HELP_OUTPUT,
"USAGE: nkf(nkf32,wnkf,nkf2) -[flags] [in file] .. [out file for -O flag]\n"
@@ -830,7 +829,8 @@
version();
}
-void show_configuration(void)
+static void
+show_configuration(void)
{
fprintf(HELP_OUTPUT,
"Summary of my nkf " NKF_VERSION " (" NKF_RELEASE_DATE ") configuration:\n"
@@ -842,12 +842,11 @@
fprintf(HELP_OUTPUT,
" Default output encoding: "
#ifdef DEFAULT_CODE_LOCALE
- "%s\n", nkf_enc_name(nkf_default_encoding())
+ "LOCALE (%s)\n", nkf_enc_name(nkf_default_encoding())
#elif DEFAULT_ENCIDX
- "%s (%s)\n", nkf_locale_encoding() ? "LOCALE" : "DEFAULT",
- nkf_enc_name(nkf_default_encoding())
+ "CONFIG (%s)\n", nkf_enc_name(nkf_default_encoding())
#else
- "NONE"
+ "NONE\n"
#endif
);
fprintf(HELP_OUTPUT,
@@ -885,7 +884,8 @@
#endif /*PERL_XS*/
#ifdef OVERWRITE
-char *get_backup_filename(const char *suffix, const char *filename)
+static char*
+get_backup_filename(const char *suffix, const char *filename)
{
char *backup_filename;
int asterisk_count = 0;
@@ -915,8 +915,7 @@
}
backup_filename[j] = '\0';
}else{
- j = strlen(suffix) + filename_length;
- backup_filename = malloc( + 1);
+ backup_filename = malloc(filename_length + strlen(suffix) + 1);
strcpy(backup_filename, filename);
strcat(backup_filename, suffix);
backup_filename[j] = '\0';
@@ -926,7 +925,8 @@
#endif
#ifdef UTF8_INPUT_ENABLE
-void nkf_each_char_to_hex(void (*f)(nkf_char c2,nkf_char c1), nkf_char c)
+static void
+nkf_each_char_to_hex(void (*f)(nkf_char c2,nkf_char c1), nkf_char c)
{
int shift = 20;
c &= VALUE_MASK;
@@ -943,7 +943,8 @@
return;
}
-void encode_fallback_html(nkf_char c)
+static void
+encode_fallback_html(nkf_char c)
{
(*oconv)(0, '&');
(*oconv)(0, '#');
@@ -966,7 +967,8 @@
return;
}
-void encode_fallback_xml(nkf_char c)
+static void
+encode_fallback_xml(nkf_char c)
{
(*oconv)(0, '&');
(*oconv)(0, '#');
@@ -976,11 +978,12 @@
return;
}
-void encode_fallback_java(nkf_char c)
+static void
+encode_fallback_java(nkf_char c)
{
(*oconv)(0, '\\');
c &= VALUE_MASK;
- if(!is_unicode_bmp(c)){
+ if(!nkf_char_unicode_bmp_p(c)){
(*oconv)(0, 'U');
(*oconv)(0, '0');
(*oconv)(0, '0');
@@ -996,7 +999,8 @@
return;
}
-void encode_fallback_perl(nkf_char c)
+static void
+encode_fallback_perl(nkf_char c)
{
(*oconv)(0, '\\');
(*oconv)(0, 'x');
@@ -1006,7 +1010,8 @@
return;
}
-void encode_fallback_subchar(nkf_char c)
+static void
+encode_fallback_subchar(nkf_char c)
{
c = unicode_subchar;
(*oconv)((c>>8)&0xFF, c&0xFF);
@@ -1094,9 +1099,13 @@
{"prefix=", ""},
};
-static void set_input_encoding(nkf_encoding *enc)
+static void
+set_input_encoding(nkf_encoding *enc)
{
switch (nkf_enc_to_index(enc)) {
+ case ISO_8859_1:
+ iso8859_f = TRUE;
+ break;
case CP50220:
case CP50221:
case CP50222:
@@ -1108,16 +1117,16 @@
#endif
break;
case ISO_2022_JP_1:
-#ifdef X0212_ENABLE
x0212_f = TRUE;
-#endif
break;
case ISO_2022_JP_3:
-#ifdef X0212_ENABLE
x0212_f = TRUE;
-#endif
x0213_f = TRUE;
break;
+ case ISO_2022_JP_2004:
+ x0212_f = TRUE;
+ x0213_f = TRUE;
+ break;
case SHIFT_JIS:
break;
case WINDOWS_31J:
@@ -1128,7 +1137,6 @@
ms_ucs_map_f = UCS_MAP_CP932;
#endif
break;
- case EUC_JP:
break;
case CP10001:
#ifdef SHIFTJIS_CP932
@@ -1138,6 +1146,10 @@
ms_ucs_map_f = UCS_MAP_CP10001;
#endif
break;
+ case EUC_JP:
+ break;
+ case EUCJP_NKF:
+ break;
case CP51932:
#ifdef SHIFTJIS_CP932
cp51932_f = TRUE;
@@ -1204,7 +1216,8 @@
}
}
-static void set_output_encoding(nkf_encoding *enc)
+static void
+set_output_encoding(nkf_encoding *enc)
{
switch (nkf_enc_to_index(enc)) {
case CP50220:
@@ -1225,17 +1238,13 @@
#endif
break;
case ISO_2022_JP_1:
-#ifdef X0212_ENABLE
x0212_f = TRUE;
-#endif
#ifdef SHIFTJIS_CP932
if (cp932inv_f == TRUE) cp932inv_f = FALSE;
#endif
break;
case ISO_2022_JP_3:
-#ifdef X0212_ENABLE
x0212_f = TRUE;
-#endif
x0213_f = TRUE;
#ifdef SHIFTJIS_CP932
if (cp932inv_f == TRUE) cp932inv_f = FALSE;
@@ -1259,9 +1268,18 @@
if (cp932inv_f == TRUE) cp932inv_f = FALSE;
#endif
#ifdef UTF8_OUTPUT_ENABLE
- ms_ucs_map_f = UCS_MAP_CP932;
+ ms_ucs_map_f = UCS_MAP_ASCII;
#endif
break;
+ case EUCJP_NKF:
+ x0212_f = FALSE;
+#ifdef SHIFTJIS_CP932
+ if (cp932inv_f == TRUE) cp932inv_f = FALSE;
+#endif
+#ifdef UTF8_OUTPUT_ENABLE
+ ms_ucs_map_f = UCS_MAP_ASCII;
+#endif
+ break;
case CP51932:
#ifdef SHIFTJIS_CP932
if (cp932inv_f == TRUE) cp932inv_f = FALSE;
@@ -1271,17 +1289,13 @@
#endif
break;
case EUCJP_MS:
-#ifdef X0212_ENABLE
x0212_f = TRUE;
-#endif
#ifdef UTF8_OUTPUT_ENABLE
ms_ucs_map_f = UCS_MAP_MS;
#endif
break;
case EUCJP_ASCII:
-#ifdef X0212_ENABLE
x0212_f = TRUE;
-#endif
#ifdef UTF8_OUTPUT_ENABLE
ms_ucs_map_f = UCS_MAP_ASCII;
#endif
@@ -1295,9 +1309,7 @@
break;
case EUC_JISX0213:
case EUC_JIS_2004:
-#ifdef X0212_ENABLE
x0212_f = TRUE;
-#endif
x0213_f = TRUE;
#ifdef SHIFTJIS_CP932
if (cp932inv_f == TRUE) cp932inv_f = FALSE;
@@ -1334,79 +1346,84 @@
}
}
-struct input_code * find_inputcode_byfunc(nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
+static struct input_code*
+find_inputcode_byfunc(nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
{
if (iconv_func){
- struct input_code *p = input_code_list;
- while (p->name){
- if (iconv_func == p->iconv_func){
- return p;
- }
- p++;
- }
+ struct input_code *p = input_code_list;
+ while (p->name){
+ if (iconv_func == p->iconv_func){
+ return p;
+ }
+ p++;
+ }
}
return 0;
}
-void set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
+static void
+set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
{
#ifdef INPUT_CODE_FIX
if (f || !input_encoding)
#endif
- if (estab_f != f){
- estab_f = f;
- }
+ if (estab_f != f){
+ estab_f = f;
+ }
if (iconv_func
#ifdef INPUT_CODE_FIX
- && (f == -TRUE || !input_encoding) /* -TRUE means "FORCE" */
+ && (f == -TRUE || !input_encoding) /* -TRUE means "FORCE" */
#endif
- ){
- iconv = iconv_func;
+ ){
+ iconv = iconv_func;
}
#ifdef CHECK_OPTION
if (estab_f && iconv_for_check != iconv){
- struct input_code *p = find_inputcode_byfunc(iconv);
- if (p){
- set_input_codename(p->name);
- debug(p->name);
- }
- iconv_for_check = iconv;
+ struct input_code *p = find_inputcode_byfunc(iconv);
+ if (p){
+ set_input_codename(p->name);
+ debug(p->name);
+ }
+ iconv_for_check = iconv;
}
#endif
}
#ifdef X0212_ENABLE
-nkf_char x0212_shift(nkf_char c)
+static nkf_char
+x0212_shift(nkf_char c)
{
nkf_char ret = c;
c &= 0x7f;
if (is_eucg3(ret)){
- if (0x75 <= c && c <= 0x7f){
- ret = c + (0x109 - 0x75);
- }
+ if (0x75 <= c && c <= 0x7f){
+ ret = c + (0x109 - 0x75);
+ }
}else{
- if (0x75 <= c && c <= 0x7f){
- ret = c + (0x113 - 0x75);
- }
+ if (0x75 <= c && c <= 0x7f){
+ ret = c + (0x113 - 0x75);
+ }
}
return ret;
}
-nkf_char x0212_unshift(nkf_char c)
+static nkf_char
+x0212_unshift(nkf_char c)
{
nkf_char ret = c;
if (0x7f <= c && c <= 0x88){
- ret = c + (0x75 - 0x7f);
+ ret = c + (0x75 - 0x7f);
}else if (0x89 <= c && c <= 0x92){
- ret = PREFIX_EUCG3 | 0x80 | (c + (0x75 - 0x89));
+ ret = PREFIX_EUCG3 | 0x80 | (c + (0x75 - 0x89));
}
return ret;
}
#endif /* X0212_ENABLE */
-nkf_char e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
+static nkf_char
+e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
{
nkf_char ndx;
if (is_eucg3(c2)){
@@ -1448,7 +1465,8 @@
return 0;
}
-nkf_char s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
+static nkf_char
+s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
{
#if defined(SHIFTJIS_CP932) || defined(X0212_ENABLE)
nkf_char val;
@@ -1456,36 +1474,36 @@
static const char shift_jisx0213_s1a3_table[5][2] ={ { 1, 8}, { 3, 4}, { 5,12}, {13,14}, {15, 0} };
#ifdef SHIFTJIS_CP932
if (!cp932inv_f && is_ibmext_in_sjis(c2)){
- val = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40];
- if (val){
- c2 = val >> 8;
- c1 = val & 0xff;
- }
+ val = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40];
+ if (val){
+ c2 = val >> 8;
+ c1 = val & 0xff;
+ }
}
if (cp932inv_f
- && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
- nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
- if (c){
- c2 = c >> 8;
- c1 = c & 0xff;
- }
+ && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
+ nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
+ if (c){
+ c2 = c >> 8;
+ c1 = c & 0xff;
+ }
}
#endif /* SHIFTJIS_CP932 */
#ifdef X0212_ENABLE
if (!x0213_f && is_ibmext_in_sjis(c2)){
- val = shiftjis_x0212[c2 - 0xfa][c1 - 0x40];
- if (val){
- if (val > 0x7FFF){
- c2 = PREFIX_EUCG3 | ((val >> 8) & 0x7f);
- c1 = val & 0xff;
- }else{
- c2 = val >> 8;
- c1 = val & 0xff;
- }
- if (p2) *p2 = c2;
- if (p1) *p1 = c1;
- return 0;
- }
+ val = shiftjis_x0212[c2 - 0xfa][c1 - 0x40];
+ if (val){
+ if (val > 0x7FFF){
+ c2 = PREFIX_EUCG3 | ((val >> 8) & 0x7f);
+ c1 = val & 0xff;
+ }else{
+ c2 = val >> 8;
+ c1 = val & 0xff;
+ }
+ if (p2) *p2 = c2;
+ if (p1) *p1 = c1;
+ return 0;
+ }
}
#endif
if(c2 >= 0x80){
@@ -1518,59 +1536,80 @@
}
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
-void w16w_conv(nkf_char val, nkf_char *p2, nkf_char *p1, nkf_char *p0)
+static void
+nkf_unicode_to_utf8(nkf_char val, int *p1, int *p2, int *p3, int *p4)
{
val &= VALUE_MASK;
if (val < 0x80){
- *p2 = val;
- *p1 = 0;
- *p0 = 0;
+ *p1 = val;
+ *p2 = 0;
+ *p3 = 0;
+ *p4 = 0;
}else if (val < 0x800){
- *p2 = 0xc0 | (val >> 6);
- *p1 = 0x80 | (val & 0x3f);
- *p0 = 0;
- } else if (val <= NKF_INT32_C(0xFFFF)) {
- *p2 = 0xe0 | (val >> 12);
- *p1 = 0x80 | ((val >> 6) & 0x3f);
- *p0 = 0x80 | (val & 0x3f);
- } else if (val <= NKF_INT32_C(0x10FFFF)) {
- *p2 = 0xe0 | (val >> 16);
- *p1 = 0x80 | ((val >> 12) & 0x3f);
- *p0 = 0x8080 | ((val << 2) & 0x3f00)| (val & 0x3f);
+ *p1 = 0xc0 | (val >> 6);
+ *p2 = 0x80 | (val & 0x3f);
+ *p3 = 0;
+ *p4 = 0;
+ } else if (nkf_char_unicode_bmp_p(val)) {
+ *p1 = 0xe0 | (val >> 12);
+ *p2 = 0x80 | ((val >> 6) & 0x3f);
+ *p3 = 0x80 | ( val & 0x3f);
+ *p4 = 0;
+ } else if (nkf_char_unicode_value_p(val)) {
+ *p1 = 0xe0 | (val >> 16);
+ *p2 = 0x80 | ((val >> 12) & 0x3f);
+ *p3 = 0x80 | ((val >> 6) & 0x3f);
+ *p4 = 0x80 | ( val & 0x3f);
} else {
- *p2 = 0;
- *p1 = 0;
- *p0 = 0;
+ *p1 = 0;
+ *p2 = 0;
+ *p3 = 0;
+ *p4 = 0;
}
}
-nkf_char ww16_conv(nkf_char c2, nkf_char c1, nkf_char c0)
+static nkf_char
+nkf_utf8_to_unicode(int c1, int c2, int c3, int c4)
{
- nkf_char val;
- if (c2 >= 0xf8) {
- val = -1;
- } else if (c2 >= 0xf0){
- /* c2: 1st, c1: 2nd, c0: 3rd/4th */
- val = (c2 & 0x0f) << 18;
- val |= (c1 & 0x3f) << 12;
- val |= (c0 & 0x3f00) >> 2;
- val |= (c0 & 0x3f);
- }else if (c2 >= 0xe0){
- val = (c2 & 0x0f) << 12;
- val |= (c1 & 0x3f) << 6;
- val |= (c0 & 0x3f);
- }else if (c2 >= 0xc0){
- val = (c2 & 0x1f) << 6;
- val |= (c1 & 0x3f);
- }else{
- val = c2;
+ nkf_char wc;
+ if (c1 <= 0x7F) {
+ /* single byte */
+ wc = c1;
}
- return val;
+ else if (c1 <= 0xC3) {
+ /* trail byte or invalid */
+ return -1;
+ }
+ else if (c1 <= 0xDF) {
+ /* 2 bytes */
+ wc = (c1 & 0x1F) << 6;
+ wc |= (c2 & 0x3F);
+ }
+ else if (c1 <= 0xEF) {
+ /* 3 bytes */
+ wc = (c1 & 0x0F) << 12;
+ wc |= (c2 & 0x3F) << 6;
+ wc |= (c3 & 0x3F);
+ }
+ else if (c2 <= 0xF4) {
+ /* 4 bytes */
+ wc = (c1 & 0x0F) << 18;
+ wc |= (c2 & 0x3F) << 12;
+ wc |= (c3 & 0x3F) << 6;
+ wc |= (c4 & 0x3F);
+ }
+ else {
+ return -1;
+ }
+ return wc;
}
#endif
#ifdef UTF8_INPUT_ENABLE
-nkf_char w_iconv_common(nkf_char c1, nkf_char c0, const unsigned short *const *pp, nkf_char psize, nkf_char *p2, nkf_char *p1)
+static int
+unicode_to_jis_common2(nkf_char c1, nkf_char c0,
+ const unsigned short *const *pp, nkf_char psize,
+ nkf_char *p2, nkf_char *p1)
{
nkf_char c2;
const unsigned short *p;
@@ -1588,23 +1627,24 @@
val = p[c0];
if (val == 0) return 1;
if (no_cp932ext_f && (
- (val>>8) == 0x2D || /* NEC special characters */
- val > NKF_INT32_C(0xF300) /* IBM extended characters */
- )) return 1;
+ (val>>8) == 0x2D || /* NEC special characters */
+ val > NKF_INT32_C(0xF300) /* IBM extended characters */
+ )) return 1;
c2 = val >> 8;
- if (val > 0x7FFF){
- c2 &= 0x7f;
- c2 |= PREFIX_EUCG3;
+ if (val > 0x7FFF){
+ c2 &= 0x7f;
+ c2 |= PREFIX_EUCG3;
}
- if (c2 == SO) c2 = JIS_X_0201;
- c1 = val & 0x7f;
+ if (c2 == SO) c2 = JIS_X_0201_1976_K;
+ c1 = val & 0xFF;
if (p2) *p2 = c2;
if (p1) *p1 = c1;
return 0;
}
-nkf_char unicode_to_jis_common(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
+static int
+unicode_to_jis_common(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
{
const unsigned short *const *pp;
const unsigned short *const *const *ppp;
@@ -1677,7 +1717,7 @@
ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_2bytes_ms :
ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_2bytes_mac :
utf8_to_euc_2bytes;
- ret = w_iconv_common(c2, c1, pp, sizeof_utf8_to_euc_2bytes, p2, p1);
+ ret = unicode_to_jis_common2(c2, c1, pp, sizeof_utf8_to_euc_2bytes, p2, p1);
}else if(c0 < 0xF0){
if(no_best_fit_chars_f){
if(ms_ucs_map_f == UCS_MAP_CP932){
@@ -1703,10 +1743,10 @@
case 0xE3:
switch(c1){
case 0x82:
- if(c0 == 0x94) return 1;
+ if(c0 == 0x94) return 1;
break;
case 0x83:
- if(c0 == 0xBB) return 1;
+ if(c0 == 0xBB) return 1;
break;
}
break;
@@ -1744,7 +1784,7 @@
ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_3bytes_ms :
ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_3bytes_mac :
utf8_to_euc_3bytes;
- ret = w_iconv_common(c1, c0, ppp[c2 - 0xE0], sizeof_utf8_to_euc_C2, p2, p1);
+ ret = unicode_to_jis_common2(c1, c0, ppp[c2 - 0xE0], sizeof_utf8_to_euc_C2, p2, p1);
}else return -1;
#ifdef SHIFTJIS_CP932
if (!ret && !cp932inv_f && is_eucg3(*p2)) {
@@ -1760,11 +1800,12 @@
}
#ifdef UTF8_OUTPUT_ENABLE
-nkf_char e2w_conv(nkf_char c2, nkf_char c1)
+static nkf_char
+e2w_conv(nkf_char c2, nkf_char c1)
{
const unsigned short *p;
- if (c2 == JIS_X_0201) {
+ if (c2 == JIS_X_0201_1976_K) {
if (ms_ucs_map_f == UCS_MAP_CP10001) {
switch (c1) {
case 0x20:
@@ -1773,23 +1814,23 @@
return 0xA9;
}
}
- p = euc_to_utf8_1byte;
+ p = euc_to_utf8_1byte;
#ifdef X0212_ENABLE
} else if (is_eucg3(c2)){
if(ms_ucs_map_f == UCS_MAP_ASCII&& c2 == NKF_INT32_C(0x8F22) && c1 == 0x43){
return 0xA6;
}
- c2 = (c2&0x7f) - 0x21;
- if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
+ c2 = (c2&0x7f) - 0x21;
+ if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
p = x0212_to_utf8_2bytes[c2];
- else
- return 0;
+ else
+ return 0;
#endif
} else {
- c2 &= 0x7f;
- c2 = (c2&0x7f) - 0x21;
- if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
- p =
+ c2 &= 0x7f;
+ c2 = (c2&0x7f) - 0x21;
+ if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
+ p =
ms_ucs_map_f == UCS_MAP_ASCII ? euc_to_utf8_2bytes[c2] :
ms_ucs_map_f == UCS_MAP_CP10001 ? euc_to_utf8_2bytes_mac[c2] :
euc_to_utf8_2bytes_ms[c2];
@@ -1804,62 +1845,73 @@
}
#endif
-nkf_char w2e_conv(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
+static nkf_char
+w2e_conv(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
{
nkf_char ret = 0;
if (!c1){
- *p2 = 0;
- *p1 = c2;
+ *p2 = 0;
+ *p1 = c2;
}else if (0xc0 <= c2 && c2 <= 0xef) {
ret = unicode_to_jis_common(c2, c1, c0, p2, p1);
#ifdef NUMCHAR_OPTION
- if (ret > 0){
- if (p2) *p2 = 0;
- if (p1) *p1 = CLASS_UNICODE | ww16_conv(c2, c1, c0);
- ret = 0;
- }
+ if (ret > 0){
+ if (p2) *p2 = 0;
+ if (p1) *p1 = nkf_char_unicode_new(nkf_utf8_to_unicode(c2, c1, c0, 0));
+ ret = 0;
+ }
#endif
}
return ret;
}
#ifdef UTF8_INPUT_ENABLE
-nkf_char w16e_conv(nkf_char val, nkf_char *p2, nkf_char *p1)
+static nkf_char
+w16e_conv(nkf_char val, nkf_char *p2, nkf_char *p1)
{
- nkf_char c2, c1, c0;
+ int c1, c2, c3, c4;
nkf_char ret = 0;
val &= VALUE_MASK;
- if (val < 0x80){
- *p2 = 0;
- *p1 = val;
- }else{
- w16w_conv(val, &c2, &c1, &c0);
- ret = unicode_to_jis_common(c2, c1, c0, p2, p1);
-#ifdef NUMCHAR_OPTION
+ if (val < 0x80) {
+ *p2 = 0;
+ *p1 = val;
+ }
+ else if (nkf_char_unicode_bmp_p(val)){
+ nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
+ ret = unicode_to_jis_common(c1, c2, c3, p2, p1);
if (ret > 0){
*p2 = 0;
- *p1 = CLASS_UNICODE | val;
+ *p1 = nkf_char_unicode_new(val);
ret = 0;
}
-#endif
}
+ else {
+ *p2 = 0;
+ *p1 = nkf_char_unicode_new(val);
+ }
return ret;
}
#endif
-nkf_char e_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
+static nkf_char
+e_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
{
- if (c2 == JIS_X_0201) {
- c1 &= 0x7f;
+ if (c2 == JIS_X_0201_1976_K || c2 == SS2){
+ if (iso2022jp_f && !x0201_f) {
+ c2 = GETA1; c1 = GETA2;
+ } else {
+ c2 = JIS_X_0201_1976_K;
+ c1 &= 0x7f;
+ }
#ifdef X0212_ENABLE
}else if (c2 == 0x8f){
- if (c0 == 0){
- return -1;
- }
+ if (c0 == 0){
+ return -1;
+ }
if (!cp51932_f && !x0213_f && 0xF5 <= c1 && c1 <= 0xFE && 0xA1 <= c0 && c0 <= 0xFE) {
/* encoding is eucJP-ms, so invert to Unicode Private User Area */
- c1 = (c1 - 0xF5) * 94 + c0 - 0xA1 + 0xE3AC + CLASS_UNICODE;
+ c1 = nkf_char_unicode_new((c1 - 0xF5) * 94 + c0 - 0xA1 + 0xE3AC);
c2 = 0;
} else {
c2 = (c2 << 8) | (c1 & 0x7f);
@@ -1876,17 +1928,14 @@
}
}
#endif /* SHIFTJIS_CP932 */
- }
+ }
#endif /* X0212_ENABLE */
- } else if (c2 == SSO){
- c2 = JIS_X_0201;
- c1 &= 0x7f;
- } else if ((c2 == EOF) || (c2 == 0) || c2 < SP) {
- /* NOP */
+ } else if ((c2 == EOF) || (c2 == 0) || c2 < SP || c2 == ISO_8859_1) {
+ /* NOP */
} else {
if (!cp51932_f && ms_ucs_map_f && 0xF5 <= c2 && c2 <= 0xFE && 0xA1 <= c1 && c1 <= 0xFE) {
/* encoding is eucJP-ms, so invert to Unicode Private User Area */
- c1 = (c2 - 0xF5) * 94 + c1 - 0xA1 + 0xE000 + CLASS_UNICODE;
+ c1 = nkf_char_unicode_new((c2 - 0xF5) * 94 + c1 - 0xA1 + 0xE000);
c2 = 0;
} else {
c1 &= 0x7f;
@@ -1903,34 +1952,40 @@
}
}
#endif /* SHIFTJIS_CP932 */
- }
+ }
}
(*oconv)(c2, c1);
return 0;
}
-nkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
+static nkf_char
+s_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
{
- if (c2 == JIS_X_0201) {
- c1 &= 0x7f;
+ if (c2 == JIS_X_0201_1976_K || (0xA1 <= c2 && c2 <= 0xDF)) {
+ if (iso2022jp_f && !x0201_f) {
+ c2 = GETA1; c1 = GETA2;
+ } else {
+ c1 &= 0x7f;
+ }
} else if ((c2 == EOF) || (c2 == 0) || c2 < SP) {
- /* NOP */
+ /* NOP */
} else if (!x0213_f && 0xF0 <= c2 && c2 <= 0xF9 && 0x40 <= c1 && c1 <= 0xFC) {
/* CP932 UDC */
if(c1 == 0x7F) return 0;
- c1 = (c2 - 0xF0) * 188 + (c1 - 0x40 - (0x7E < c1)) + 0xE000 + CLASS_UNICODE;
+ c1 = nkf_char_unicode_new((c2 - 0xF0) * 188 + (c1 - 0x40 - (0x7E < c1)) + 0xE000);
c2 = 0;
} else {
- nkf_char ret = s2e_conv(c2, c1, &c2, &c1);
- if (ret) return ret;
+ nkf_char ret = s2e_conv(c2, c1, &c2, &c1);
+ if (ret) return ret;
}
(*oconv)(c2, c1);
return 0;
}
-nkf_char w_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
+static nkf_char
+w_iconv(nkf_char c1, nkf_char c2, nkf_char c3)
{
- nkf_char ret = 0;
+ nkf_char ret = 0, c4 = 0;
static const char w_iconv_utf8_1st_byte[] =
{ /* 0xC0 - 0xFF */
20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -1938,45 +1993,50 @@
30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33,
40, 41, 41, 41, 42, 43, 43, 43, 50, 50, 50, 50, 60, 60, 70, 70};
- if (c2 < 0 || 0xff < c2) {
- }else if (c2 == 0) { /* 0 : 1 byte*/
- c0 = 0;
- } else if ((c2 & 0xc0) == 0x80) { /* 0x80-0xbf : trail byte */
+ if (c3 > 0xFF) {
+ c4 = c3 & 0xFF;
+ c3 >>= 8;
+ }
+
+ if (c1 < 0 || 0xff < c1) {
+ }else if (c1 == 0) { /* 0 : 1 byte*/
+ c3 = 0;
+ } else if ((c1 & 0xC0) == 0x80) { /* 0x80-0xbf : trail byte */
return 0;
} else{
- switch (w_iconv_utf8_1st_byte[c2 - 0xC0]) {
+ switch (w_iconv_utf8_1st_byte[c1 - 0xC0]) {
case 21:
- if (c1 < 0x80 || 0xBF < c1) return 0;
+ if (c2 < 0x80 || 0xBF < c2) return 0;
break;
case 30:
- if (c0 == 0) return -1;
- if (c1 < 0xA0 || 0xBF < c1 || (c0 & 0xc0) != 0x80)
+ if (c3 == 0) return -1;
+ if (c2 < 0xA0 || 0xBF < c2 || (c3 & 0xC0) != 0x80)
return 0;
break;
case 31:
case 33:
- if (c0 == 0) return -1;
- if ((c1 & 0xc0) != 0x80 || (c0 & 0xc0) != 0x80)
+ if (c3 == 0) return -1;
+ if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80)
return 0;
break;
case 32:
- if (c0 == 0) return -1;
- if (c1 < 0x80 || 0x9F < c1 || (c0 & 0xc0) != 0x80)
+ if (c3 == 0) return -1;
+ if (c2 < 0x80 || 0x9F < c2 || (c3 & 0xC0) != 0x80)
return 0;
break;
case 40:
- if (c0 == 0) return -2;
- if (c1 < 0x90 || 0xBF < c1 || (c0 & 0xc0c0) != 0x8080)
+ if (c3 == 0) return -2;
+ if (c2 < 0x90 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
return 0;
break;
case 41:
- if (c0 == 0) return -2;
- if (c1 < 0x80 || 0xBF < c1 || (c0 & 0xc0c0) != 0x8080)
+ if (c3 == 0) return -2;
+ if (c2 < 0x80 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
return 0;
break;
case 42:
- if (c0 == 0) return -2;
- if (c1 < 0x80 || 0x8F < c1 || (c0 & 0xc0c0) != 0x8080)
+ if (c3 == 0) return -2;
+ if (c2 < 0x80 || 0x8F < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
return 0;
break;
default:
@@ -1984,65 +2044,181 @@
break;
}
}
- if (c2 == 0 || c2 == EOF){
- } else if ((c2 & 0xf8) == 0xf0) { /* 4 bytes */
- c1 = CLASS_UNICODE | ww16_conv(c2, c1, c0);
- c2 = 0;
+ if (c1 == 0 || c1 == EOF){
+ } else if ((c1 & 0xf8) == 0xf0) { /* 4 bytes */
+ c2 = nkf_char_unicode_new(nkf_utf8_to_unicode(c1, c2, c3, c4));
+ c1 = 0;
} else {
- ret = w2e_conv(c2, c1, c0, &c2, &c1);
+ ret = w2e_conv(c1, c2, c3, &c1, &c2);
}
if (ret == 0){
- (*oconv)(c2, c1);
+ (*oconv)(c1, c2);
}
return ret;
}
-nkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0)
+#define NKF_ICONV_INVALID_CODE_RANGE -13
+static size_t
+unicode_iconv(nkf_char wc)
{
- nkf_char ret = 0;
- if ((c2==0 && c1 < 0x80) || c2==EOF) {
- (*oconv)(c2, c1);
- return 0;
- }else if (0xD8 <= c2 && c2 <= 0xDB) {
- if (c0 < NKF_INT32_C(0xDC00) || NKF_INT32_C(0xDFFF) < c0)
- return -2;
- c1 = CLASS_UNICODE | ((c2 << 18) + (c1 << 10) + c0 - NKF_INT32_C(0x35FDC00));
+ nkf_char c1, c2;
+ int ret = 0;
+
+ if (wc < 0x80) {
c2 = 0;
- }else if ((c2>>3) == 27) { /* unpaired surrogate */
- /*
- return 2;
- */
- return 1;
- }else ret = w16e_conv(((c2 & 0xff)<<8) + c1, &c2, &c1);
- if (ret) return ret;
+ c1 = wc;
+ }else if ((wc>>11) == 27) {
+ /* unpaired surrogate */
+ return NKF_ICONV_INVALID_CODE_RANGE;
+ }else if (wc < 0xFFFF) {
+ ret = w16e_conv(wc, &c2, &c1);
+ if (ret) return ret;
+ }else if (wc < 0x10FFFF) {
+ c2 = 0;
+ c1 = nkf_char_unicode_new(wc);
+ } else {
+ return NKF_ICONV_INVALID_CODE_RANGE;
+ }
(*oconv)(c2, c1);
return 0;
}
-nkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0)
+#define NKF_ICONV_NEED_ONE_MORE_BYTE -1
+#define NKF_ICONV_NEED_TWO_MORE_BYTES -2
+#define UTF16_TO_UTF32(lead, trail) (((lead) << 10) + (trail) - NKF_INT32_C(0x35FDC00))
+static size_t
+nkf_iconv_utf_16(int c1, int c2, int c3, int c4)
{
- int ret = 0;
+ nkf_char wc;
- if ((c2 == 0 && c1 < 0x80) || c2==EOF) {
- } else if (is_unicode_bmp(c1)) {
- ret = w16e_conv(c1, &c2, &c1);
+ if (c1 == EOF) {
+ (*oconv)(EOF, 0);
+ return 0;
+ }
+
+ if (input_endian == ENDIAN_BIG) {
+ if (0xD8 <= c1 && c1 <= 0xDB) {
+ if (0xDC <= c3 && c3 <= 0xDF) {
+ wc = UTF16_TO_UTF32(c1 << 8 | c2, c3 << 8 | c4);
+ } else return NKF_ICONV_NEED_TWO_MORE_BYTES;
+ } else {
+ wc = c1 << 8 | c2;
+ }
} else {
- c2 = 0;
- c1 = CLASS_UNICODE | c1;
+ if (0xD8 <= c2 && c2 <= 0xDB) {
+ if (0xDC <= c4 && c4 <= 0xDF) {
+ wc = UTF16_TO_UTF32(c2 << 8 | c1, c4 << 8 | c3);
+ } else return NKF_ICONV_NEED_TWO_MORE_BYTES;
+ } else {
+ wc = c2 << 8 | c1;
+ }
}
- if (ret) return ret;
- (*oconv)(c2, c1);
+
+ return (*unicode_iconv)(wc);
+}
+
+static nkf_char
+w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0)
+{
return 0;
}
+static nkf_char
+w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0)
+{
+ return 0;
+}
+
+static size_t
+nkf_iconv_utf_32(int c1, int c2, int c3, int c4)
+{
+ nkf_char wc;
+
+ if (c1 == EOF) {
+ (*oconv)(EOF, 0);
+ return 0;
+ }
+
+ switch(input_endian){
+ case ENDIAN_BIG:
+ wc = c2 << 16 | c3 << 8 | c4;
+ break;
+ case ENDIAN_LITTLE:
+ wc = c3 << 16 | c2 << 8 | c1;
+ break;
+ case ENDIAN_2143:
+ wc = c1 << 16 | c4 << 8 | c3;
+ break;
+ case ENDIAN_3412:
+ wc = c4 << 16 | c1 << 8 | c2;
+ break;
+ default:
+ return NKF_ICONV_INVALID_CODE_RANGE;
+ }
+
+ return (*unicode_iconv)(wc);
+}
#endif
-void j_oconv(nkf_char c2, nkf_char c1)
+#define output_ascii_escape_sequence(mode) do { \
+ if (output_mode != ASCII && output_mode != ISO_8859_1) { \
+ (*o_putc)(ESC); \
+ (*o_putc)('('); \
+ (*o_putc)(ascii_intro); \
+ output_mode = mode; \
+ } \
+ } while (0)
+
+static void
+output_escape_sequence(int mode)
{
+ if (output_mode == mode)
+ return;
+ switch(mode) {
+ case ISO_8859_1:
+ (*o_putc)(ESC);
+ (*o_putc)('.');
+ (*o_putc)('A');
+ break;
+ case JIS_X_0201_1976_K:
+ (*o_putc)(ESC);
+ (*o_putc)('(');
+ (*o_putc)('I');
+ break;
+ case JIS_X_0208:
+ (*o_putc)(ESC);
+ (*o_putc)('$');
+ (*o_putc)(kanji_intro);
+ break;
+ case JIS_X_0212:
+ (*o_putc)(ESC);
+ (*o_putc)('$');
+ (*o_putc)('(');
+ (*o_putc)('D');
+ break;
+ case JIS_X_0213_1:
+ (*o_putc)(ESC);
+ (*o_putc)('$');
+ (*o_putc)('(');
+ (*o_putc)('Q');
+ break;
+ case JIS_X_0213_2:
+ (*o_putc)(ESC);
+ (*o_putc)('$');
+ (*o_putc)('(');
+ (*o_putc)('P');
+ break;
+ }
+ output_mode = mode;
+}
+
+static void
+j_oconv(nkf_char c2, nkf_char c1)
+{
#ifdef NUMCHAR_OPTION
- if (c2 == 0 && is_unicode_capsule(c1)){
- w16e_conv(c1, &c2, &c1);
- if (c2 == 0 && is_unicode_capsule(c1)){
+ if (c2 == 0 && nkf_char_unicode_p(c1)){
+ w16e_conv(c1, &c2, &c1);
+ if (c2 == 0 && nkf_char_unicode_p(c1)){
c2 = c1 & VALUE_MASK;
if (ms_ucs_map_f && 0xE000 <= c2 && c2 <= 0xE757) {
/* CP5022x UDC */
@@ -2053,90 +2229,46 @@
if (encode_fallback) (*encode_fallback)(c1);
return;
}
- }
+ }
}
#endif
- if (c2 == EOF) {
- if (output_mode !=ASCII && output_mode!=ISO_8859_1) {
- (*o_putc)(ESC);
- (*o_putc)('(');
- (*o_putc)(ascii_intro);
- output_mode = ASCII;
- }
- (*o_putc)(EOF);
+ if (c2 == 0) {
+ output_ascii_escape_sequence(ASCII);
+ (*o_putc)(c1);
+ }
+ else if (c2 == EOF) {
+ output_ascii_escape_sequence(ASCII);
+ (*o_putc)(EOF);
+ }
+ else if (c2 == ISO_8859_1) {
+ output_ascii_escape_sequence(ISO_8859_1);
+ (*o_putc)(c1|0x80);
+ }
+ else if (c2 == JIS_X_0201_1976_K) {
+ output_escape_sequence(JIS_X_0201_1976_K);
+ (*o_putc)(c1);
#ifdef X0212_ENABLE
} else if (is_eucg3(c2)){
- if(x0213_f){
- if(output_mode!=JIS_X_0213_2){
- output_mode = JIS_X_0213_2;
- (*o_putc)(ESC);
- (*o_putc)('$');
- (*o_putc)('(');
- (*o_putc)(0x50);
- }
- }else{
- if(output_mode!=JIS_X_0212){
- output_mode = JIS_X_0212;
- (*o_putc)(ESC);
- (*o_putc)('$');
- (*o_putc)('(');
- (*o_putc)(0x44);
- }
- }
- (*o_putc)(c2 & 0x7f);
- (*o_putc)(c1);
+ output_escape_sequence(x0213_f ? JIS_X_0213_2 : JIS_X_0212);
+ (*o_putc)(c2 & 0x7f);
+ (*o_putc)(c1);
#endif
- } else if (c2==JIS_X_0201) {
- if (output_mode!=JIS_X_0201) {
- output_mode = JIS_X_0201;
- (*o_putc)(ESC);
- (*o_putc)('(');
- (*o_putc)('I');
- }
- (*o_putc)(c1);
- } else if (c2==ISO_8859_1) {
- /* iso8859 introduction, or 8th bit on */
- /* Can we convert in 7bit form using ESC-'-'-A ?
- Is this popular? */
- output_mode = ISO_8859_1;
- (*o_putc)(c1|0x80);
- } else if (c2 == 0) {
- if (output_mode !=ASCII && output_mode!=ISO_8859_1) {
- (*o_putc)(ESC);
- (*o_putc)('(');
- (*o_putc)(ascii_intro);
- output_mode = ASCII;
- }
- (*o_putc)(c1);
} else {
if(ms_ucs_map_f
? c2<0x20 || 0x92<c2 || c1<0x20 || 0x7e<c1
: c2<0x20 || 0x7e<c2 || c1<0x20 || 0x7e<c1) return;
- if(x0213_f){
- if (output_mode!=JIS_X_0213_1) {
- output_mode = JIS_X_0213_1;
- (*o_putc)(ESC);
- (*o_putc)('$');
- (*o_putc)('(');
- (*o_putc)(0x4F);
- }
- }else if (output_mode != JIS_X_0208) {
- output_mode = JIS_X_0208;
- (*o_putc)(ESC);
- (*o_putc)('$');
- (*o_putc)(kanji_intro);
- }
- (*o_putc)(c2);
- (*o_putc)(c1);
+ output_escape_sequence(x0213_f ? JIS_X_0213_1 : JIS_X_0208);
+ (*o_putc)(c2);
+ (*o_putc)(c1);
}
}
-void e_oconv(nkf_char c2, nkf_char c1)
+static void
+e_oconv(nkf_char c2, nkf_char c1)
{
-#ifdef NUMCHAR_OPTION
- if (c2 == 0 && is_unicode_capsule(c1)){
- w16e_conv(c1, &c2, &c1);
- if (c2 == 0 && is_unicode_capsule(c1)){
+ if (c2 == 0 && nkf_char_unicode_p(c1)){
+ w16e_conv(c1, &c2, &c1);
+ if (c2 == 0 && nkf_char_unicode_p(c1)){
c2 = c1 & VALUE_MASK;
if (x0212_f && 0xE000 <= c2 && c2 <= 0xE757) {
/* eucJP-ms UDC */
@@ -2157,63 +2289,63 @@
if (encode_fallback) (*encode_fallback)(c1);
return;
}
- }
+ }
}
-#endif
+
if (c2 == EOF) {
- (*o_putc)(EOF);
- return;
+ (*o_putc)(EOF);
} else if (c2 == 0) {
output_mode = ASCII;
- (*o_putc)(c1);
- } else if (c2 == JIS_X_0201) {
+ (*o_putc)(c1);
+ } else if (c2 == JIS_X_0201_1976_K) {
output_mode = EUC_JP;
- (*o_putc)(SSO); (*o_putc)(c1|0x80);
+ (*o_putc)(SS2); (*o_putc)(c1|0x80);
} else if (c2 == ISO_8859_1) {
output_mode = ISO_8859_1;
- (*o_putc)(c1 | 0x080);
+ (*o_putc)(c1 | 0x080);
#ifdef X0212_ENABLE
} else if (is_eucg3(c2)){
output_mode = EUC_JP;
#ifdef SHIFTJIS_CP932
- if (!cp932inv_f){
- nkf_char s2, s1;
- if (e2s_conv(c2, c1, &s2, &s1) == 0){
- s2e_conv(s2, s1, &c2, &c1);
- }
- }
+ if (!cp932inv_f){
+ nkf_char s2, s1;
+ if (e2s_conv(c2, c1, &s2, &s1) == 0){
+ s2e_conv(s2, s1, &c2, &c1);
+ }
+ }
#endif
- if (c2 == 0) {
+ if (c2 == 0) {
output_mode = ASCII;
(*o_putc)(c1);
}else if (is_eucg3(c2)){
- if (x0212_f){
- (*o_putc)(0x8f);
- (*o_putc)((c2 & 0x7f) | 0x080);
- (*o_putc)(c1 | 0x080);
- }
- }else{
- (*o_putc)((c2 & 0x7f) | 0x080);
- (*o_putc)(c1 | 0x080);
- }
+ if (x0212_f){
+ (*o_putc)(0x8f);
+ (*o_putc)((c2 & 0x7f) | 0x080);
+ (*o_putc)(c1 | 0x080);
+ }
+ }else{
+ (*o_putc)((c2 & 0x7f) | 0x080);
+ (*o_putc)(c1 | 0x080);
+ }
#endif
} else {
- if (!nkf_isgraph(c1) || !nkf_isgraph(c2)) {
- set_iconv(FALSE, 0);
- return; /* too late to rescue this char */
- }
+ if (!nkf_isgraph(c1) || !nkf_isgraph(c2)) {
+ set_iconv(FALSE, 0);
+ return; /* too late to rescue this char */
+ }
output_mode = EUC_JP;
- (*o_putc)(c2 | 0x080);
- (*o_putc)(c1 | 0x080);
+ (*o_putc)(c2 | 0x080);
+ (*o_putc)(c1 | 0x080);
}
}
-void s_oconv(nkf_char c2, nkf_char c1)
+static void
+s_oconv(nkf_char c2, nkf_char c1)
{
#ifdef NUMCHAR_OPTION
- if (c2 == 0 && is_unicode_capsule(c1)){
- w16e_conv(c1, &c2, &c1);
- if (c2 == 0 && is_unicode_capsule(c1)){
+ if (c2 == 0 && nkf_char_unicode_p(c1)){
+ w16e_conv(c1, &c2, &c1);
+ if (c2 == 0 && nkf_char_unicode_p(c1)){
c2 = c1 & VALUE_MASK;
if (!x0213_f && 0xE000 <= c2 && c2 <= 0xE757) {
/* CP932 UDC */
@@ -2232,215 +2364,193 @@
}
#endif
if (c2 == EOF) {
- (*o_putc)(EOF);
- return;
+ (*o_putc)(EOF);
+ return;
} else if (c2 == 0) {
output_mode = ASCII;
- (*o_putc)(c1);
- } else if (c2 == JIS_X_0201) {
+ (*o_putc)(c1);
+ } else if (c2 == JIS_X_0201_1976_K) {
output_mode = SHIFT_JIS;
- (*o_putc)(c1|0x80);
+ (*o_putc)(c1|0x80);
} else if (c2 == ISO_8859_1) {
output_mode = ISO_8859_1;
- (*o_putc)(c1 | 0x080);
+ (*o_putc)(c1 | 0x080);
#ifdef X0212_ENABLE
} else if (is_eucg3(c2)){
output_mode = SHIFT_JIS;
- if (e2s_conv(c2, c1, &c2, &c1) == 0){
- (*o_putc)(c2);
- (*o_putc)(c1);
- }
+ if (e2s_conv(c2, c1, &c2, &c1) == 0){
+ (*o_putc)(c2);
+ (*o_putc)(c1);
+ }
#endif
} else {
- if (!nkf_isprint(c1) || !nkf_isprint(c2)) {
- set_iconv(FALSE, 0);
- return; /* too late to rescue this char */
- }
+ if (!nkf_isprint(c1) || !nkf_isprint(c2)) {
+ set_iconv(FALSE, 0);
+ return; /* too late to rescue this char */
+ }
output_mode = SHIFT_JIS;
- e2s_conv(c2, c1, &c2, &c1);
+ e2s_conv(c2, c1, &c2, &c1);
#ifdef SHIFTJIS_CP932
- if (cp932inv_f
- && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
- nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
- if (c){
- c2 = c >> 8;
- c1 = c & 0xff;
- }
- }
+ if (cp932inv_f
+ && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
+ nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
+ if (c){
+ c2 = c >> 8;
+ c1 = c & 0xff;
+ }
+ }
#endif /* SHIFTJIS_CP932 */
- (*o_putc)(c2);
+ (*o_putc)(c2);
if (prefix_table[(unsigned char)c1]){
- (*o_putc)(prefix_table[(unsigned char)c1]);
+ (*o_putc)(prefix_table[(unsigned char)c1]);
}
- (*o_putc)(c1);
+ (*o_putc)(c1);
}
}
#ifdef UTF8_OUTPUT_ENABLE
-void w_oconv(nkf_char c2, nkf_char c1)
+static void
+w_oconv(nkf_char c2, nkf_char c1)
{
- nkf_char c0;
+ int c3, c4;
nkf_char val;
if (output_bom_f) {
output_bom_f = FALSE;
- (*o_putc)('\357');
+ (*o_putc)('\357');
(*o_putc)('\273');
(*o_putc)('\277');
}
if (c2 == EOF) {
- (*o_putc)(EOF);
- return;
+ (*o_putc)(EOF);
+ return;
}
-#ifdef NUMCHAR_OPTION
- if (c2 == 0 && is_unicode_capsule(c1)){
- val = c1 & VALUE_MASK;
- if (val < 0x80){
- (*o_putc)(val);
- }else if (val < 0x800){
- (*o_putc)(0xC0 | (val >> 6));
- (*o_putc)(0x80 | (val & 0x3f));
- } else if (val <= NKF_INT32_C(0xFFFF)) {
- (*o_putc)(0xE0 | (val >> 12));
- (*o_putc)(0x80 | ((val >> 6) & 0x3f));
- (*o_putc)(0x80 | (val & 0x3f));
- } else if (val <= NKF_INT32_C(0x10FFFF)) {
- (*o_putc)(0xF0 | ( val>>18));
- (*o_putc)(0x80 | ((val>>12) & 0x3f));
- (*o_putc)(0x80 | ((val>> 6) & 0x3f));
- (*o_putc)(0x80 | ( val & 0x3f));
- }
- return;
+ if (c2 == 0 && nkf_char_unicode_p(c1)){
+ val = c1 & VALUE_MASK;
+ nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
+ (*o_putc)(c1);
+ if (c2) (*o_putc)(c2);
+ if (c3) (*o_putc)(c3);
+ if (c4) (*o_putc)(c4);
+ return;
}
-#endif
if (c2 == 0) {
- output_mode = ASCII;
- (*o_putc)(c1);
- } else if (c2 == ISO_8859_1) {
- output_mode = UTF_8;
- (*o_putc)(c1 | 0x080);
+ (*o_putc)(c1);
} else {
- output_mode = UTF_8;
val = e2w_conv(c2, c1);
- if (val){
- w16w_conv(val, &c2, &c1, &c0);
- (*o_putc)(c2);
- if (c1){
- (*o_putc)(c1);
- if (c0) (*o_putc)(c0);
- }
- }
+ if (val){
+ nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
+ (*o_putc)(c1);
+ if (c2) (*o_putc)(c2);
+ if (c3) (*o_putc)(c3);
+ if (c4) (*o_putc)(c4);
+ }
}
}
-void w_oconv16(nkf_char c2, nkf_char c1)
+static void
+w_oconv16(nkf_char c2, nkf_char c1)
{
if (output_bom_f) {
output_bom_f = FALSE;
- if (output_endian == ENDIAN_LITTLE){
- (*o_putc)((unsigned char)'\377');
- (*o_putc)('\376');
- }else{
- (*o_putc)('\376');
- (*o_putc)((unsigned char)'\377');
- }
+ if (output_endian == ENDIAN_LITTLE){
+ (*o_putc)(0xFF);
+ (*o_putc)(0xFE);
+ }else{
+ (*o_putc)(0xFE);
+ (*o_putc)(0xFF);
+ }
}
if (c2 == EOF) {
- (*o_putc)(EOF);
- return;
+ (*o_putc)(EOF);
+ return;
}
- if (c2 == ISO_8859_1) {
- c2 = 0;
- c1 |= 0x80;
-#ifdef NUMCHAR_OPTION
- } else if (c2 == 0 && is_unicode_capsule(c1)) {
- if (is_unicode_bmp(c1)) {
- c2 = (c1 >> 8) & 0xff;
- c1 &= 0xff;
- } else {
- c1 &= VALUE_MASK;
- if (c1 <= UNICODE_MAX) {
- c2 = (c1 >> 10) + NKF_INT32_C(0xD7C0); /* high surrogate */
- c1 = (c1 & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */
- if (output_endian == ENDIAN_LITTLE){
- (*o_putc)(c2 & 0xff);
- (*o_putc)((c2 >> 8) & 0xff);
- (*o_putc)(c1 & 0xff);
- (*o_putc)((c1 >> 8) & 0xff);
- }else{
- (*o_putc)((c2 >> 8) & 0xff);
- (*o_putc)(c2 & 0xff);
- (*o_putc)((c1 >> 8) & 0xff);
- (*o_putc)(c1 & 0xff);
- }
- }
- return;
- }
-#endif
+ if (c2 == 0 && nkf_char_unicode_p(c1)) {
+ if (nkf_char_unicode_bmp_p(c1)) {
+ c2 = (c1 >> 8) & 0xff;
+ c1 &= 0xff;
+ } else {
+ c1 &= VALUE_MASK;
+ if (c1 <= UNICODE_MAX) {
+ c2 = (c1 >> 10) + NKF_INT32_C(0xD7C0); /* high surrogate */
+ c1 = (c1 & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */
+ if (output_endian == ENDIAN_LITTLE){
+ (*o_putc)(c2 & 0xff);
+ (*o_putc)((c2 >> 8) & 0xff);
+ (*o_putc)(c1 & 0xff);
+ (*o_putc)((c1 >> 8) & 0xff);
+ }else{
+ (*o_putc)((c2 >> 8) & 0xff);
+ (*o_putc)(c2 & 0xff);
+ (*o_putc)((c1 >> 8) & 0xff);
+ (*o_putc)(c1 & 0xff);
+ }
+ }
+ return;
+ }
} else if (c2) {
- nkf_char val = e2w_conv(c2, c1);
- c2 = (val >> 8) & 0xff;
- c1 = val & 0xff;
+ nkf_char val = e2w_conv(c2, c1);
+ c2 = (val >> 8) & 0xff;
+ c1 = val & 0xff;
if (!val) return;
}
if (output_endian == ENDIAN_LITTLE){
- (*o_putc)(c1);
- (*o_putc)(c2);
+ (*o_putc)(c1);
+ (*o_putc)(c2);
}else{
- (*o_putc)(c2);
- (*o_putc)(c1);
+ (*o_putc)(c2);
+ (*o_putc)(c1);
}
}
-void w_oconv32(nkf_char c2, nkf_char c1)
+static void
+w_oconv32(nkf_char c2, nkf_char c1)
{
if (output_bom_f) {
output_bom_f = FALSE;
- if (output_endian == ENDIAN_LITTLE){
- (*o_putc)((unsigned char)'\377');
- (*o_putc)('\376');
- (*o_putc)('\000');
- (*o_putc)('\000');
- }else{
- (*o_putc)('\000');
- (*o_putc)('\000');
- (*o_putc)('\376');
- (*o_putc)((unsigned char)'\377');
- }
+ if (output_endian == ENDIAN_LITTLE){
+ (*o_putc)(0xFF);
+ (*o_putc)(0xFE);
+ (*o_putc)(0);
+ (*o_putc)(0);
+ }else{
+ (*o_putc)(0);
+ (*o_putc)(0);
+ (*o_putc)(0xFE);
+ (*o_putc)(0xFF);
+ }
}
if (c2 == EOF) {
- (*o_putc)(EOF);
- return;
+ (*o_putc)(EOF);
+ return;
}
if (c2 == ISO_8859_1) {
- c1 |= 0x80;
-#ifdef NUMCHAR_OPTION
- } else if (c2 == 0 && is_unicode_capsule(c1)) {
+ c1 |= 0x80;
+ } else if (c2 == 0 && nkf_char_unicode_p(c1)) {
c1 &= VALUE_MASK;
-#endif
} else if (c2) {
- c1 = e2w_conv(c2, c1);
+ c1 = e2w_conv(c2, c1);
if (!c1) return;
}
if (output_endian == ENDIAN_LITTLE){
- (*o_putc)( c1 & NKF_INT32_C(0x000000FF));
- (*o_putc)((c1 & NKF_INT32_C(0x0000FF00)) >> 8);
- (*o_putc)((c1 & NKF_INT32_C(0x00FF0000)) >> 16);
- (*o_putc)('\000');
+ (*o_putc)( c1 & 0xFF);
+ (*o_putc)((c1 >> 8) & 0xFF);
+ (*o_putc)((c1 >> 16) & 0xFF);
+ (*o_putc)(0);
}else{
- (*o_putc)('\000');
- (*o_putc)((c1 & NKF_INT32_C(0x00FF0000)) >> 16);
- (*o_putc)((c1 & NKF_INT32_C(0x0000FF00)) >> 8);
- (*o_putc)( c1 & NKF_INT32_C(0x000000FF));
+ (*o_putc)(0);
+ (*o_putc)((c1 >> 16) & 0xFF);
+ (*o_putc)((c1 >> 8) & 0xFF);
+ (*o_putc)( c1 & 0xFF);
}
}
#endif
@@ -2456,60 +2566,64 @@
#define SCORE_INIT (SCORE_iMIME)
-static const unsigned char score_table_A0[] = {
+static const char score_table_A0[] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,
SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_NO_EXIST,
};
-static const unsigned char score_table_F0[] = {
+static const char score_table_F0[] = {
SCORE_L2, SCORE_L2, SCORE_L2, SCORE_L2,
SCORE_L2, SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST,
SCORE_DEPEND, SCORE_DEPEND, SCORE_CP932, SCORE_CP932,
SCORE_CP932, SCORE_NO_EXIST, SCORE_NO_EXIST, SCORE_ERROR,
};
-void set_code_score(struct input_code *ptr, nkf_char score)
+static void
+set_code_score(struct input_code *ptr, nkf_char score)
{
if (ptr){
- ptr->score |= score;
+ ptr->score |= score;
}
}
-void clr_code_score(struct input_code *ptr, nkf_char score)
+static void
+clr_code_score(struct input_code *ptr, nkf_char score)
{
if (ptr){
- ptr->score &= ~score;
+ ptr->score &= ~score;
}
}
-void code_score(struct input_code *ptr)
+static void
+code_score(struct input_code *ptr)
{
nkf_char c2 = ptr->buf[0];
#ifdef UTF8_OUTPUT_ENABLE
nkf_char c1 = ptr->buf[1];
#endif
if (c2 < 0){
- set_code_score(ptr, SCORE_ERROR);
- }else if (c2 == SSO){
- set_code_score(ptr, SCORE_KANA);
+ set_code_score(ptr, SCORE_ERROR);
+ }else if (c2 == SS2){
+ set_code_score(ptr, SCORE_KANA);
}else if (c2 == 0x8f){
- set_code_score(ptr, SCORE_X0212);
+ set_code_score(ptr, SCORE_X0212);
#ifdef UTF8_OUTPUT_ENABLE
}else if (!e2w_conv(c2, c1)){
- set_code_score(ptr, SCORE_NO_EXIST);
+ set_code_score(ptr, SCORE_NO_EXIST);
#endif
}else if ((c2 & 0x70) == 0x20){
- set_code_score(ptr, score_table_A0[c2 & 0x0f]);
+ set_code_score(ptr, score_table_A0[c2 & 0x0f]);
}else if ((c2 & 0x70) == 0x70){
- set_code_score(ptr, score_table_F0[c2 & 0x0f]);
+ set_code_score(ptr, score_table_F0[c2 & 0x0f]);
}else if ((c2 & 0x70) >= 0x50){
- set_code_score(ptr, SCORE_L2);
+ set_code_score(ptr, SCORE_L2);
}
}
-void status_disable(struct input_code *ptr)
+static void
+status_disable(struct input_code *ptr)
{
ptr->stat = -1;
ptr->buf[0] = -1;
@@ -2517,85 +2631,89 @@
if (iconv == ptr->iconv_func) set_iconv(FALSE, 0);
}
-void status_push_ch(struct input_code *ptr, nkf_char c)
+static void
+status_push_ch(struct input_code *ptr, nkf_char c)
{
ptr->buf[ptr->index++] = c;
}
-void status_clear(struct input_code *ptr)
+static void
+status_clear(struct input_code *ptr)
{
ptr->stat = 0;
ptr->index = 0;
}
-void status_reset(struct input_code *ptr)
+static void
+status_reset(struct input_code *ptr)
{
status_clear(ptr);
ptr->score = SCORE_INIT;
}
-void status_reinit(struct input_code *ptr)
+static void
+status_reinit(struct input_code *ptr)
{
status_reset(ptr);
ptr->_file_stat = 0;
}
-void status_check(struct input_code *ptr, nkf_char c)
+static void
+status_check(struct input_code *ptr, nkf_char c)
{
if (c <= DEL && estab_f){
- status_reset(ptr);
+ status_reset(ptr);
}
}
-void s_status(struct input_code *ptr, nkf_char c)
+static void
+s_status(struct input_code *ptr, nkf_char c)
{
switch(ptr->stat){
- case -1:
- status_check(ptr, c);
- break;
- case 0:
- if (c <= DEL){
- break;
-#ifdef NUMCHAR_OPTION
- }else if (is_unicode_capsule(c)){
- break;
-#endif
- }else if (0xa1 <= c && c <= 0xdf){
- status_push_ch(ptr, SSO);
- status_push_ch(ptr, c);
- code_score(ptr);
- status_clear(ptr);
- }else if ((0x81 <= c && c < 0xa0) || (0xe0 <= c && c <= 0xea)){
- ptr->stat = 1;
- status_push_ch(ptr, c);
- }else if (0xed <= c && c <= 0xee){
- ptr->stat = 3;
- status_push_ch(ptr, c);
+ case -1:
+ status_check(ptr, c);
+ break;
+ case 0:
+ if (c <= DEL){
+ break;
+ }else if (nkf_char_unicode_p(c)){
+ break;
+ }else if (0xa1 <= c && c <= 0xdf){
+ status_push_ch(ptr, SS2);
+ status_push_ch(ptr, c);
+ code_score(ptr);
+ status_clear(ptr);
+ }else if ((0x81 <= c && c < 0xa0) || (0xe0 <= c && c <= 0xea)){
+ ptr->stat = 1;
+ status_push_ch(ptr, c);
+ }else if (0xed <= c && c <= 0xee){
+ ptr->stat = 3;
+ status_push_ch(ptr, c);
#ifdef SHIFTJIS_CP932
- }else if (is_ibmext_in_sjis(c)){
- ptr->stat = 2;
- status_push_ch(ptr, c);
+ }else if (is_ibmext_in_sjis(c)){
+ ptr->stat = 2;
+ status_push_ch(ptr, c);
#endif /* SHIFTJIS_CP932 */
#ifdef X0212_ENABLE
- }else if (0xf0 <= c && c <= 0xfc){
- ptr->stat = 1;
- status_push_ch(ptr, c);
+ }else if (0xf0 <= c && c <= 0xfc){
+ ptr->stat = 1;
+ status_push_ch(ptr, c);
#endif /* X0212_ENABLE */
- }else{
- status_disable(ptr);
- }
- break;
- case 1:
- if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
- status_push_ch(ptr, c);
- s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
- code_score(ptr);
- status_clear(ptr);
- }else{
- status_disable(ptr);
- }
- break;
- case 2:
+ }else{
+ status_disable(ptr);
+ }
+ break;
+ case 1:
+ if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
+ status_push_ch(ptr, c);
+ s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
+ code_score(ptr);
+ status_clear(ptr);
+ }else{
+ status_disable(ptr);
+ }
+ break;
+ case 2:
#ifdef SHIFTJIS_CP932
if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)) {
status_push_ch(ptr, c);
@@ -2607,205 +2725,208 @@
}
#endif /* SHIFTJIS_CP932 */
status_disable(ptr);
- break;
- case 3:
- if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
- status_push_ch(ptr, c);
- s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
+ break;
+ case 3:
+ if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
+ status_push_ch(ptr, c);
+ s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
set_code_score(ptr, SCORE_CP932);
status_clear(ptr);
- }else{
- status_disable(ptr);
- }
- break;
+ }else{
+ status_disable(ptr);
+ }
+ break;
}
}
-void e_status(struct input_code *ptr, nkf_char c)
+static void
+e_status(struct input_code *ptr, nkf_char c)
{
switch (ptr->stat){
- case -1:
- status_check(ptr, c);
- break;
- case 0:
- if (c <= DEL){
- break;
-#ifdef NUMCHAR_OPTION
- }else if (is_unicode_capsule(c)){
- break;
-#endif
- }else if (SSO == c || (0xa1 <= c && c <= 0xfe)){
- ptr->stat = 1;
- status_push_ch(ptr, c);
+ case -1:
+ status_check(ptr, c);
+ break;
+ case 0:
+ if (c <= DEL){
+ break;
+ }else if (nkf_char_unicode_p(c)){
+ break;
+ }else if (SS2 == c || (0xa1 <= c && c <= 0xfe)){
+ ptr->stat = 1;
+ status_push_ch(ptr, c);
#ifdef X0212_ENABLE
- }else if (0x8f == c){
- ptr->stat = 2;
- status_push_ch(ptr, c);
+ }else if (0x8f == c){
+ ptr->stat = 2;
+ status_push_ch(ptr, c);
#endif /* X0212_ENABLE */
- }else{
- status_disable(ptr);
- }
- break;
- case 1:
- if (0xa1 <= c && c <= 0xfe){
- status_push_ch(ptr, c);
- code_score(ptr);
- status_clear(ptr);
- }else{
- status_disable(ptr);
- }
- break;
+ }else{
+ status_disable(ptr);
+ }
+ break;
+ case 1:
+ if (0xa1 <= c && c <= 0xfe){
+ status_push_ch(ptr, c);
+ code_score(ptr);
+ status_clear(ptr);
+ }else{
+ status_disable(ptr);
+ }
+ break;
#ifdef X0212_ENABLE
- case 2:
- if (0xa1 <= c && c <= 0xfe){
- ptr->stat = 1;
- status_push_ch(ptr, c);
- }else{
- status_disable(ptr);
- }
+ case 2:
+ if (0xa1 <= c && c <= 0xfe){
+ ptr->stat = 1;
+ status_push_ch(ptr, c);
+ }else{
+ status_disable(ptr);
+ }
#endif /* X0212_ENABLE */
}
}
#ifdef UTF8_INPUT_ENABLE
-void w_status(struct input_code *ptr, nkf_char c)
+static void
+w_status(struct input_code *ptr, nkf_char c)
{
switch (ptr->stat){
- case -1:
- status_check(ptr, c);
- break;
- case 0:
- if (c <= DEL){
- break;
-#ifdef NUMCHAR_OPTION
- }else if (is_unicode_capsule(c)){
- break;
-#endif
- }else if (0xc0 <= c && c <= 0xdf){
- ptr->stat = 1;
- status_push_ch(ptr, c);
- }else if (0xe0 <= c && c <= 0xef){
- ptr->stat = 2;
- status_push_ch(ptr, c);
- }else if (0xf0 <= c && c <= 0xf4){
- ptr->stat = 3;
- status_push_ch(ptr, c);
- }else{
- status_disable(ptr);
- }
- break;
- case 1:
- case 2:
- if (0x80 <= c && c <= 0xbf){
- status_push_ch(ptr, c);
- if (ptr->index > ptr->stat){
- int bom = (ptr->buf[0] == 0xef && ptr->buf[1] == 0xbb
- && ptr->buf[2] == 0xbf);
- w2e_conv(ptr->buf[0], ptr->buf[1], ptr->buf[2],
- &ptr->buf[0], &ptr->buf[1]);
- if (!bom){
- code_score(ptr);
- }
- status_clear(ptr);
- }
- }else{
- status_disable(ptr);
- }
- break;
- case 3:
+ case -1:
+ status_check(ptr, c);
+ break;
+ case 0:
+ if (c <= DEL){
+ break;
+ }else if (nkf_char_unicode_p(c)){
+ break;
+ }else if (0xc0 <= c && c <= 0xdf){
+ ptr->stat = 1;
+ status_push_ch(ptr, c);
+ }else if (0xe0 <= c && c <= 0xef){
+ ptr->stat = 2;
+ status_push_ch(ptr, c);
+ }else if (0xf0 <= c && c <= 0xf4){
+ ptr->stat = 3;
+ status_push_ch(ptr, c);
+ }else{
+ status_disable(ptr);
+ }
+ break;
+ case 1:
+ case 2:
if (0x80 <= c && c <= 0xbf){
+ status_push_ch(ptr, c);
+ if (ptr->index > ptr->stat){
+ int bom = (ptr->buf[0] == 0xef && ptr->buf[1] == 0xbb
+ && ptr->buf[2] == 0xbf);
+ w2e_conv(ptr->buf[0], ptr->buf[1], ptr->buf[2],
+ &ptr->buf[0], &ptr->buf[1]);
+ if (!bom){
+ code_score(ptr);
+ }
+ status_clear(ptr);
+ }
+ }else{
+ status_disable(ptr);
+ }
+ break;
+ case 3:
+ if (0x80 <= c && c <= 0xbf){
if (ptr->index < ptr->stat){
status_push_ch(ptr, c);
} else {
- status_clear(ptr);
+ status_clear(ptr);
}
- }else{
- status_disable(ptr);
- }
- break;
+ }else{
+ status_disable(ptr);
+ }
+ break;
}
}
#endif
-void code_status(nkf_char c)
+static void
+code_status(nkf_char c)
{
int action_flag = 1;
struct input_code *result = 0;
struct input_code *p = input_code_list;
while (p->name){
- if (!p->status_func) {
+ if (!p->status_func) {
++p;
continue;
}
- if (!p->status_func)
+ if (!p->status_func)
continue;
- (p->status_func)(p, c);
- if (p->stat > 0){
- action_flag = 0;
- }else if(p->stat == 0){
- if (result){
- action_flag = 0;
- }else{
- result = p;
- }
- }
- ++p;
+ (p->status_func)(p, c);
+ if (p->stat > 0){
+ action_flag = 0;
+ }else if(p->stat == 0){
+ if (result){
+ action_flag = 0;
+ }else{
+ result = p;
+ }
+ }
+ ++p;
}
if (action_flag){
- if (result && !estab_f){
- set_iconv(TRUE, result->iconv_func);
- }else if (c <= DEL){
- struct input_code *ptr = input_code_list;
- while (ptr->name){
- status_reset(ptr);
- ++ptr;
- }
- }
+ if (result && !estab_f){
+ set_iconv(TRUE, result->iconv_func);
+ }else if (c <= DEL){
+ struct input_code *ptr = input_code_list;
+ while (ptr->name){
+ status_reset(ptr);
+ ++ptr;
+ }
+ }
}
}
#ifndef WIN32DLL
-nkf_char std_getc(FILE *f)
+static nkf_char
+std_getc(FILE *f)
{
if (std_gc_ndx){
- return std_gc_buf[--std_gc_ndx];
+ return std_gc_buf[--std_gc_ndx];
}
return getc(f);
}
#endif /*WIN32DLL*/
-nkf_char std_ungetc(nkf_char c, FILE *f)
+static nkf_char
+std_ungetc(nkf_char c, FILE *f)
{
if (std_gc_ndx == STD_GC_BUFSIZE){
- return EOF;
+ return EOF;
}
std_gc_buf[std_gc_ndx++] = c;
return c;
}
#ifndef WIN32DLL
-void std_putc(nkf_char c)
+static void
+std_putc(nkf_char c)
{
if(c!=EOF)
- putchar(c);
+ putchar(c);
}
#endif /*WIN32DLL*/
static unsigned char hold_buf[HOLD_SIZE*2];
static int hold_count = 0;
-nkf_char push_hold_buf(nkf_char c2)
+static nkf_char
+push_hold_buf(nkf_char c2)
{
if (hold_count >= HOLD_SIZE*2)
- return (EOF);
+ return (EOF);
hold_buf[hold_count++] = (unsigned char)c2;
return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);
}
-nkf_char
-h_conv(FILE *f, nkf_char c2, nkf_char c1)
+static int
+h_conv(FILE *f, int c1, int c2)
{
- nkf_char ret, c3, c0;
+ int ret, c4, c3;
int hold_index;
@@ -2814,33 +2935,33 @@
/** and it must be after 2 byte 8bit code */
hold_count = 0;
+ push_hold_buf(c1);
push_hold_buf(c2);
- push_hold_buf(c1);
- while ((c1 = (*i_getc)(f)) != EOF) {
- if (c1 == ESC){
- (*i_ungetc)(c1,f);
- break;
- }
- code_status(c1);
- if (push_hold_buf(c1) == EOF || estab_f){
- break;
- }
+ while ((c2 = (*i_getc)(f)) != EOF) {
+ if (c2 == ESC){
+ (*i_ungetc)(c2,f);
+ break;
+ }
+ code_status(c2);
+ if (push_hold_buf(c2) == EOF || estab_f) {
+ break;
+ }
}
- if (!estab_f){
- struct input_code *p = input_code_list;
- struct input_code *result = p;
- if (c1 == EOF){
- code_status(c1);
- }
- while (p->name){
- if (p->status_func && p->score < result->score){
- result = p;
- }
- ++p;
- }
- set_iconv(TRUE, result->iconv_func);
+ if (!estab_f) {
+ struct input_code *p = input_code_list;
+ struct input_code *result = p;
+ if (c2 == EOF) {
+ code_status(c2);
+ }
+ while (p->name) {
+ if (p->status_func && p->score < result->score) {
+ result = p;
+ }
+ p++;
+ }
+ set_iconv(TRUE, result->iconv_func);
}
@@ -2853,68 +2974,63 @@
** Kanji codes by oconv and leave estab_f unchanged.
**/
- ret = c1;
+ ret = c2;
hold_index = 0;
while (hold_index < hold_count){
- c2 = hold_buf[hold_index++];
- if (c2 <= DEL
-#ifdef NUMCHAR_OPTION
- || is_unicode_capsule(c2)
-#endif
- ){
- (*iconv)(0, c2, 0);
- continue;
- }else if (iconv == s_iconv && 0xa1 <= c2 && c2 <= 0xdf){
- (*iconv)(JIS_X_0201, c2, 0);
- continue;
- }
- if (hold_index < hold_count){
- c1 = hold_buf[hold_index++];
- }else{
- c1 = (*i_getc)(f);
- if (c1 == EOF){
- c3 = EOF;
- break;
- }
- code_status(c1);
- }
- c0 = 0;
- switch ((*iconv)(c2, c1, 0)) { /* can be EUC/SJIS/UTF-8 */
+ c1 = hold_buf[hold_index++];
+ if (c1 <= DEL){
+ (*iconv)(0, c1, 0);
+ continue;
+ }else if (iconv == s_iconv && 0xa1 <= c1 && c1 <= 0xdf){
+ (*iconv)(JIS_X_0201_1976_K, c1, 0);
+ continue;
+ }
+ if (hold_index < hold_count){
+ c2 = hold_buf[hold_index++];
+ }else{
+ c2 = (*i_getc)(f);
+ if (c2 == EOF){
+ c4 = EOF;
+ break;
+ }
+ code_status(c2);
+ }
+ c3 = 0;
+ switch ((*iconv)(c1, c2, 0)) { /* can be EUC/SJIS/UTF-8 */
case -2:
/* 4 bytes UTF-8 */
- if (hold_index < hold_count){
- c0 = hold_buf[hold_index++];
- } else if ((c0 = (*i_getc)(f)) == EOF) {
+ if (hold_index < hold_count){
+ c3 = hold_buf[hold_index++];
+ } else if ((c3 = (*i_getc)(f)) == EOF) {
ret = EOF;
break;
} else {
- code_status(c0);
- c0 <<= 8;
+ code_status(c3);
if (hold_index < hold_count){
- c3 = hold_buf[hold_index++];
- } else if ((c3 = (*i_getc)(f)) == EOF) {
- c0 = ret = EOF;
+ c4 = hold_buf[hold_index++];
+ } else if ((c4 = (*i_getc)(f)) == EOF) {
+ c3 = ret = EOF;
break;
} else {
- code_status(c3);
- (*iconv)(c2, c1, c0|c3);
+ code_status(c4);
+ (*iconv)(c1, c2, (c3<<8)|c4);
}
- }
+ }
break;
case -1:
/* 3 bytes EUC or UTF-8 */
- if (hold_index < hold_count){
- c0 = hold_buf[hold_index++];
- } else if ((c0 = (*i_getc)(f)) == EOF) {
+ if (hold_index < hold_count){
+ c3 = hold_buf[hold_index++];
+ } else if ((c3 = (*i_getc)(f)) == EOF) {
ret = EOF;
break;
} else {
- code_status(c0);
- }
- (*iconv)(c2, c1, c0);
- break;
+ code_status(c3);
+ }
+ (*iconv)(c1, c2, c3);
+ break;
}
- if (c0 == EOF) break;
+ if (c3 == EOF) break;
}
return ret;
}
@@ -2922,7 +3038,8 @@
/*
* Check and Ignore BOM
*/
-void check_bom(FILE *f)
+static void
+check_bom(FILE *f)
{
int c2;
switch(c2 = (*i_getc)(f)){
@@ -3036,22 +3153,26 @@
nkf_char buf[3];
} broken_state;
-static void init_broken_state(void)
+static void
+init_broken_state(void)
{
memset(&broken_state, 0, sizeof(broken_state));
}
-static void push_broken_buf(nkf_char c)
+static void
+push_broken_buf(c)
{
broken_state.buf[broken_state.count++] = c;
}
-static nkf_char pop_broken_buf(void)
+static nkf_char
+pop_broken_buf(void)
{
return broken_state.buf[--broken_state.count];
}
-nkf_char broken_getc(FILE *f)
+static nkf_char
+broken_getc(FILE *f)
{
nkf_char c, c1;
@@ -3060,7 +3181,7 @@
}
c = (*i_bgetc)(f);
if (c=='$' && broken_state.status != ESC
- && (input_mode==ASCII || input_mode==JIS_X_0201)) {
+ && (input_mode == ASCII || input_mode == JIS_X_0201_1976_K)) {
c1= (*i_bgetc)(f);
broken_state.status = 0;
if (c1=='@'|| c1=='B') {
@@ -3072,7 +3193,7 @@
return c;
}
} else if (c=='(' && broken_state.status != ESC
- && (input_mode==JIS_X_0208 || input_mode==JIS_X_0201)) { /* ) */
+ && (input_mode == JIS_X_0208 || input_mode == JIS_X_0201_1976_K)) {
c1= (*i_bgetc)(f);
broken_state.status = 0;
if (c1=='J'|| c1=='B') {
@@ -3089,14 +3210,16 @@
}
}
-nkf_char broken_ungetc(nkf_char c, FILE *f)
+static nkf_char
+broken_ungetc(nkf_char c, FILE *f)
{
if (broken_state.count < 2)
push_broken_buf(c);
return c;
}
-void eol_conv(nkf_char c2, nkf_char c1)
+static void
+eol_conv(nkf_char c2, nkf_char c1)
{
if (guess_f && input_eol != EOF) {
if (c2 == 0 && c1 == LF) {
@@ -3117,210 +3240,212 @@
}
/*
- Return value of fold_conv()
+ Return value of fold_conv()
- LF add newline and output char
- CR add newline and output nothing
- SP space
- 0 skip
- 1 (or else) normal output
+ LF add newline and output char
+ CR add newline and output nothing
+ SP space
+ 0 skip
+ 1 (or else) normal output
- fold state in prev (previous character)
+ fold state in prev (previous character)
- >0x80 Japanese (X0208/X0201)
- <0x80 ASCII
- LF new line
- SP space
+ >0x80 Japanese (X0208/X0201)
+ <0x80 ASCII
+ LF new line
+ SP space
- This fold algorthm does not preserve heading space in a line.
- This is the main difference from fmt.
-*/
+ This fold algorthm does not preserve heading space in a line.
+ This is the main difference from fmt.
+ */
#define char_size(c2,c1) (c2?2:1)
-void fold_conv(nkf_char c2, nkf_char c1)
+static void
+fold_conv(nkf_char c2, nkf_char c1)
{
nkf_char prev0;
nkf_char fold_state;
if (c1== CR && !fold_preserve_f) {
- fold_state=0; /* ignore cr */
+ fold_state=0; /* ignore cr */
}else if (c1== LF&&f_prev==CR && fold_preserve_f) {
- f_prev = LF;
- fold_state=0; /* ignore cr */
+ f_prev = LF;
+ fold_state=0; /* ignore cr */
} else if (c1== BS) {
- if (f_line>0) f_line--;
- fold_state = 1;
+ if (f_line>0) f_line--;
+ fold_state = 1;
} else if (c2==EOF && f_line != 0) { /* close open last line */
- fold_state = LF;
+ fold_state = LF;
} else if ((c1==LF && !fold_preserve_f)
- || ((c1==CR||(c1==LF&&f_prev!=CR))
- && fold_preserve_f)) {
- /* new line */
- if (fold_preserve_f) {
- f_prev = c1;
- f_line = 0;
- fold_state = CR;
+ || ((c1==CR||(c1==LF&&f_prev!=CR))
+ && fold_preserve_f)) {
+ /* new line */
+ if (fold_preserve_f) {
+ f_prev = c1;
+ f_line = 0;
+ fold_state = CR;
} else if ((f_prev == c1 && !fold_preserve_f)
- || (f_prev == LF && fold_preserve_f)
- ) { /* duplicate newline */
- if (f_line) {
- f_line = 0;
- fold_state = LF; /* output two newline */
- } else {
- f_line = 0;
- fold_state = 1;
- }
- } else {
- if (f_prev&0x80) { /* Japanese? */
- f_prev = c1;
- fold_state = 0; /* ignore given single newline */
- } else if (f_prev==SP) {
- fold_state = 0;
- } else {
- f_prev = c1;
- if (++f_line<=fold_len)
- fold_state = SP;
- else {
- f_line = 0;
- fold_state = CR; /* fold and output nothing */
- }
- }
- }
+ || (f_prev == LF && fold_preserve_f)
+ ) { /* duplicate newline */
+ if (f_line) {
+ f_line = 0;
+ fold_state = LF; /* output two newline */
+ } else {
+ f_line = 0;
+ fold_state = 1;
+ }
+ } else {
+ if (f_prev&0x80) { /* Japanese? */
+ f_prev = c1;
+ fold_state = 0; /* ignore given single newline */
+ } else if (f_prev==SP) {
+ fold_state = 0;
+ } else {
+ f_prev = c1;
+ if (++f_line<=fold_len)
+ fold_state = SP;
+ else {
+ f_line = 0;
+ fold_state = CR; /* fold and output nothing */
+ }
+ }
+ }
} else if (c1=='\f') {
- f_prev = LF;
- f_line = 0;
- fold_state = LF; /* output newline and clear */
+ f_prev = LF;
+ f_line = 0;
+ fold_state = LF; /* output newline and clear */
} else if ( (c2==0 && c1==SP)||
- (c2==0 && c1==TAB)||
- (c2=='!'&& c1=='!')) {
- /* X0208 kankaku or ascii space */
- if (f_prev == SP) {
- fold_state = 0; /* remove duplicate spaces */
- } else {
- f_prev = SP;
- if (++f_line<=fold_len)
- fold_state = SP; /* output ASCII space only */
- else {
- f_prev = SP; f_line = 0;
- fold_state = CR; /* fold and output nothing */
- }
- }
+ (c2==0 && c1==TAB)||
+ (c2=='!'&& c1=='!')) {
+ /* X0208 kankaku or ascii space */
+ if (f_prev == SP) {
+ fold_state = 0; /* remove duplicate spaces */
+ } else {
+ f_prev = SP;
+ if (++f_line<=fold_len)
+ fold_state = SP; /* output ASCII space only */
+ else {
+ f_prev = SP; f_line = 0;
+ fold_state = CR; /* fold and output nothing */
+ }
+ }
} else {
- prev0 = f_prev; /* we still need this one... , but almost done */
- f_prev = c1;
- if (c2 || c2==JIS_X_0201)
- f_prev |= 0x80; /* this is Japanese */
- f_line += char_size(c2,c1);
- if (f_line<=fold_len) { /* normal case */
- fold_state = 1;
- } else {
- if (f_line>fold_len+fold_margin) { /* too many kinsoku suspension */
- f_line = char_size(c2,c1);
- fold_state = LF; /* We can't wait, do fold now */
- } else if (c2==JIS_X_0201) {
- /* simple kinsoku rules return 1 means no folding */
- if (c1==(0xde&0x7f)) fold_state = 1; /* $B!+(B*/
- else if (c1==(0xdf&0x7f)) fold_state = 1; /* $B!,(B*/
- else if (c1==(0xa4&0x7f)) fold_state = 1; /* $B!#(B*/
- else if (c1==(0xa3&0x7f)) fold_state = 1; /* $B!$(B*/
- else if (c1==(0xa1&0x7f)) fold_state = 1; /* $B!W(B*/
- else if (c1==(0xb0&0x7f)) fold_state = 1; /* - */
- else if (SP<=c1 && c1<=(0xdf&0x7f)) { /* X0201 */
+ prev0 = f_prev; /* we still need this one... , but almost done */
+ f_prev = c1;
+ if (c2 || c2 == JIS_X_0201_1976_K)
+ f_prev |= 0x80; /* this is Japanese */
+ f_line += char_size(c2,c1);
+ if (f_line<=fold_len) { /* normal case */
+ fold_state = 1;
+ } else {
+ if (f_line>fold_len+fold_margin) { /* too many kinsoku suspension */
+ f_line = char_size(c2,c1);
+ fold_state = LF; /* We can't wait, do fold now */
+ } else if (c2 == JIS_X_0201_1976_K) {
+ /* simple kinsoku rules return 1 means no folding */
+ if (c1==(0xde&0x7f)) fold_state = 1; /* $B!+(B*/
+ else if (c1==(0xdf&0x7f)) fold_state = 1; /* $B!,(B*/
+ else if (c1==(0xa4&0x7f)) fold_state = 1; /* $B!#(B*/
+ else if (c1==(0xa3&0x7f)) fold_state = 1; /* $B!$(B*/
+ else if (c1==(0xa1&0x7f)) fold_state = 1; /* $B!W(B*/
+ else if (c1==(0xb0&0x7f)) fold_state = 1; /* - */
+ else if (SP<=c1 && c1<=(0xdf&0x7f)) { /* X0201 */
f_line = 1;
fold_state = LF;/* add one new f_line before this character */
} else {
f_line = 1;
fold_state = LF;/* add one new f_line before this character */
}
- } else if (c2==0) {
- /* kinsoku point in ASCII */
+ } else if (c2==0) {
+ /* kinsoku point in ASCII */
if ( c1==')'|| /* { [ ( */
- c1==']'||
- c1=='}'||
- c1=='.'||
- c1==','||
- c1=='!'||
- c1=='?'||
- c1=='/'||
- c1==':'||
- c1==';') {
+ c1==']'||
+ c1=='}'||
+ c1=='.'||
+ c1==','||
+ c1=='!'||
+ c1=='?'||
+ c1=='/'||
+ c1==':'||
+ c1==';') {
fold_state = 1;
- /* just after special */
+ /* just after special */
} else if (!is_alnum(prev0)) {
f_line = char_size(c2,c1);
fold_state = LF;
} else if ((prev0==SP) || /* ignored new f_line */
- (prev0==LF)|| /* ignored new f_line */
- (prev0&0x80)) { /* X0208 - ASCII */
+ (prev0==LF)|| /* ignored new f_line */
+ (prev0&0x80)) { /* X0208 - ASCII */
f_line = char_size(c2,c1);
- fold_state = LF;/* add one new f_line before this character */
- } else {
- fold_state = 1; /* default no fold in ASCII */
- }
- } else {
- if (c2=='!') {
- if (c1=='"') fold_state = 1; /* $B!"(B */
- else if (c1=='#') fold_state = 1; /* $B!#(B */
- else if (c1=='W') fold_state = 1; /* $B!W(B */
- else if (c1=='K') fold_state = 1; /* $B!K(B */
- else if (c1=='$') fold_state = 1; /* $B!$(B */
- else if (c1=='%') fold_state = 1; /* $B!%(B */
- else if (c1=='\'') fold_state = 1; /* $B!\(B */
- else if (c1=='(') fold_state = 1; /* $B!((B */
- else if (c1==')') fold_state = 1; /* $B!)(B */
- else if (c1=='*') fold_state = 1; /* $B!*(B */
- else if (c1=='+') fold_state = 1; /* $B!+(B */
- else if (c1==',') fold_state = 1; /* $B!,(B */
- /* default no fold in kinsoku */
+ fold_state = LF;/* add one new f_line before this character */
+ } else {
+ fold_state = 1; /* default no fold in ASCII */
+ }
+ } else {
+ if (c2=='!') {
+ if (c1=='"') fold_state = 1; /* $B!"(B */
+ else if (c1=='#') fold_state = 1; /* $B!#(B */
+ else if (c1=='W') fold_state = 1; /* $B!W(B */
+ else if (c1=='K') fold_state = 1; /* $B!K(B */
+ else if (c1=='$') fold_state = 1; /* $B!$(B */
+ else if (c1=='%') fold_state = 1; /* $B!%(B */
+ else if (c1=='\'') fold_state = 1; /* $B!\(B */
+ else if (c1=='(') fold_state = 1; /* $B!((B */
+ else if (c1==')') fold_state = 1; /* $B!)(B */
+ else if (c1=='*') fold_state = 1; /* $B!*(B */
+ else if (c1=='+') fold_state = 1; /* $B!+(B */
+ else if (c1==',') fold_state = 1; /* $B!,(B */
+ /* default no fold in kinsoku */
else {
fold_state = LF;
f_line = char_size(c2,c1);
/* add one new f_line before this character */
}
- } else {
+ } else {
f_line = char_size(c2,c1);
- fold_state = LF;
- /* add one new f_line before this character */
- }
- }
- }
+ fold_state = LF;
+ /* add one new f_line before this character */
+ }
+ }
+ }
}
/* terminator process */
switch(fold_state) {
- case LF:
- OCONV_NEWLINE((*o_fconv));
- (*o_fconv)(c2,c1);
- break;
- case 0:
- return;
- case CR:
- OCONV_NEWLINE((*o_fconv));
- break;
- case TAB:
- case SP:
- (*o_fconv)(0,SP);
- break;
- default:
- (*o_fconv)(c2,c1);
+ case LF:
+ OCONV_NEWLINE((*o_fconv));
+ (*o_fconv)(c2,c1);
+ break;
+ case 0:
+ return;
+ case CR:
+ OCONV_NEWLINE((*o_fconv));
+ break;
+ case TAB:
+ case SP:
+ (*o_fconv)(0,SP);
+ break;
+ default:
+ (*o_fconv)(c2,c1);
}
}
-nkf_char z_prev2=0,z_prev1=0;
+static nkf_char z_prev2=0,z_prev1=0;
-void z_conv(nkf_char c2, nkf_char c1)
+static void
+z_conv(nkf_char c2, nkf_char c1)
{
/* if (c2) c1 &= 0x7f; assertion */
- if (c2 == JIS_X_0201 && (c1 == 0x20 || c1 == 0x7D || c1 == 0x7E)) {
+ if (c2 == JIS_X_0201_1976_K && (c1 == 0x20 || c1 == 0x7D || c1 == 0x7E)) {
(*o_zconv)(c2,c1);
return;
}
if (x0201_f) {
- if (z_prev2 == JIS_X_0201) {
- if (c2 == JIS_X_0201) {
+ if (z_prev2 == JIS_X_0201_1976_K) {
+ if (c2 == JIS_X_0201_1976_K) {
if (c1 == (0xde&0x7f)) { /* $BByE@(B */
z_prev2 = 0;
(*o_zconv)(dv[(z_prev1-SP)*2], dv[(z_prev1-SP)*2+1]);
@@ -3334,7 +3459,7 @@
z_prev2 = 0;
(*o_zconv)(cv[(z_prev1-SP)*2], cv[(z_prev1-SP)*2+1]);
}
- if (c2 == JIS_X_0201) {
+ if (c2 == JIS_X_0201_1976_K) {
if (dv[(c1-SP)*2] || ev[(c1-SP)*2]) {
/* wait for $BByE@(B or $BH>ByE@(B */
z_prev1 = c1;
@@ -3348,28 +3473,28 @@
}
if (c2 == EOF) {
- (*o_zconv)(c2, c1);
- return;
+ (*o_zconv)(c2, c1);
+ return;
}
if (alpha_f&1 && c2 == 0x23) {
/* JISX0208 Alphabet */
- c2 = 0;
+ c2 = 0;
} else if (c2 == 0x21) {
/* JISX0208 Kigou */
- if (0x21==c1) {
- if (alpha_f&2) {
- c2 = 0;
- c1 = SP;
- } else if (alpha_f&4) {
- (*o_zconv)(0, SP);
- (*o_zconv)(0, SP);
- return;
- }
- } else if (alpha_f&1 && 0x20<c1 && c1<0x7f && fv[c1-0x20]) {
- c2 = 0;
- c1 = fv[c1-0x20];
- }
+ if (0x21==c1) {
+ if (alpha_f&2) {
+ c2 = 0;
+ c1 = SP;
+ } else if (alpha_f&4) {
+ (*o_zconv)(0, SP);
+ (*o_zconv)(0, SP);
+ return;
+ }
+ } else if (alpha_f&1 && 0x20<c1 && c1<0x7f && fv[c1-0x20]) {
+ c2 = 0;
+ c1 = fv[c1-0x20];
+ }
}
if (alpha_f&8 && c2 == 0) {
@@ -3390,7 +3515,7 @@
if (alpha_f & 16) {
/* JIS X 0208 Katakana to JIS X 0201 Katakana */
if (c2 == 0x21) {
- nkf_char c = 0;
+ char c = 0;
switch (c1) {
case 0x23:
/* U+3002 (0x8142) Ideographic Full Stop -> U+FF61 (0xA1) Halfwidth Ideographic Full Stop */
@@ -3426,7 +3551,7 @@
break;
}
if (c) {
- (*o_zconv)(JIS_X_0201, c);
+ (*o_zconv)(JIS_X_0201_1976_K, c);
return;
}
} else if (c2 == 0x25) {
@@ -3448,9 +3573,9 @@
};
if (fullwidth_to_halfwidth[c1-0x20]){
c2 = fullwidth_to_halfwidth[c1-0x20];
- (*o_zconv)(JIS_X_0201, c2>>8);
+ (*o_zconv)(JIS_X_0201_1976_K, c2>>8);
if (c2 & 0xFF) {
- (*o_zconv)(JIS_X_0201, c2&0xFF);
+ (*o_zconv)(JIS_X_0201_1976_K, c2&0xFF);
}
return;
}
@@ -3461,25 +3586,26 @@
#define rot13(c) ( \
- ( c < 'A') ? c: \
- (c <= 'M') ? (c + 13): \
- (c <= 'Z') ? (c - 13): \
- (c < 'a') ? (c): \
- (c <= 'm') ? (c + 13): \
- (c <= 'z') ? (c - 13): \
- (c) \
-)
+ ( c < 'A') ? c: \
+ (c <= 'M') ? (c + 13): \
+ (c <= 'Z') ? (c - 13): \
+ (c < 'a') ? (c): \
+ (c <= 'm') ? (c + 13): \
+ (c <= 'z') ? (c - 13): \
+ (c) \
+ )
#define rot47(c) ( \
- ( c < '!') ? c: \
- ( c <= 'O') ? (c + 47) : \
- ( c <= '~') ? (c - 47) : \
- c \
-)
+ ( c < '!') ? c: \
+ ( c <= 'O') ? (c + 47) : \
+ ( c <= '~') ? (c - 47) : \
+ c \
+ )
-void rot_conv(nkf_char c2, nkf_char c1)
+static void
+rot_conv(nkf_char c2, nkf_char c1)
{
- if (c2==0 || c2==JIS_X_0201 || c2==ISO_8859_1) {
+ if (c2 == 0 || c2 == JIS_X_0201_1976_K || c2 == ISO_8859_1) {
c1 = rot13(c1);
} else if (c2) {
c1 = rot47(c1);
@@ -3488,62 +3614,64 @@
(*o_rot_conv)(c2,c1);
}
-void hira_conv(nkf_char c2, nkf_char c1)
+static void
+hira_conv(nkf_char c2, nkf_char c1)
{
if (hira_f & 1) {
- if (c2 == 0x25) {
- if (0x20 < c1 && c1 < 0x74) {
- c2 = 0x24;
- (*o_hira_conv)(c2,c1);
- return;
- } else if (c1 == 0x74 && nkf_enc_unicode_p(output_encoding)) {
- c2 = 0;
- c1 = CLASS_UNICODE | 0x3094;
- (*o_hira_conv)(c2,c1);
- return;
- }
- } else if (c2 == 0x21 && (c1 == 0x33 || c1 == 0x34)) {
- c1 += 2;
- (*o_hira_conv)(c2,c1);
- return;
- }
+ if (c2 == 0x25) {
+ if (0x20 < c1 && c1 < 0x74) {
+ c2 = 0x24;
+ (*o_hira_conv)(c2,c1);
+ return;
+ } else if (c1 == 0x74 && nkf_enc_unicode_p(output_encoding)) {
+ c2 = 0;
+ c1 = nkf_char_unicode_new(0x3094);
+ (*o_hira_conv)(c2,c1);
+ return;
+ }
+ } else if (c2 == 0x21 && (c1 == 0x33 || c1 == 0x34)) {
+ c1 += 2;
+ (*o_hira_conv)(c2,c1);
+ return;
+ }
}
if (hira_f & 2) {
- if (c2 == 0 && c1 == (CLASS_UNICODE | 0x3094)) {
- c2 = 0x25;
- c1 = 0x74;
- } else if (c2 == 0x24 && 0x20 < c1 && c1 < 0x74) {
- c2 = 0x25;
- } else if (c2 == 0x21 && (c1 == 0x35 || c1 == 0x36)) {
- c1 -= 2;
- }
+ if (c2 == 0 && c1 == nkf_char_unicode_new(0x3094)) {
+ c2 = 0x25;
+ c1 = 0x74;
+ } else if (c2 == 0x24 && 0x20 < c1 && c1 < 0x74) {
+ c2 = 0x25;
+ } else if (c2 == 0x21 && (c1 == 0x35 || c1 == 0x36)) {
+ c1 -= 2;
+ }
}
(*o_hira_conv)(c2,c1);
}
-void iso2022jp_check_conv(nkf_char c2, nkf_char c1)
+static void
+iso2022jp_check_conv(nkf_char c2, nkf_char c1)
{
#define RANGE_NUM_MAX 18
static const nkf_char range[RANGE_NUM_MAX][2] = {
- {0x222f, 0x2239,},
- {0x2242, 0x2249,},
- {0x2251, 0x225b,},
- {0x226b, 0x2271,},
- {0x227a, 0x227d,},
- {0x2321, 0x232f,},
- {0x233a, 0x2340,},
- {0x235b, 0x2360,},
- {0x237b, 0x237e,},
- {0x2474, 0x247e,},
- {0x2577, 0x257e,},
- {0x2639, 0x2640,},
- {0x2659, 0x267e,},
- {0x2742, 0x2750,},
- {0x2772, 0x277e,},
- {0x2841, 0x287e,},
- {0x4f54, 0x4f7e,},
- {0x7425, 0x747e},
+ {0x222f, 0x2239,},
+ {0x2242, 0x2249,},
+ {0x2251, 0x225b,},
+ {0x226b, 0x2271,},
+ {0x227a, 0x227d,},
+ {0x2321, 0x232f,},
+ {0x233a, 0x2340,},
+ {0x235b, 0x2360,},
+ {0x237b, 0x237e,},
+ {0x2474, 0x247e,},
+ {0x2577, 0x257e,},
+ {0x2639, 0x2640,},
+ {0x2659, 0x267e,},
+ {0x2742, 0x2750,},
+ {0x2772, 0x277e,},
+ {0x2841, 0x287e,},
+ {0x4f54, 0x4f7e,},
+ {0x7425, 0x747e},
};
nkf_char i;
nkf_char start, end, c;
@@ -3598,7 +3726,7 @@
};
static const nkf_char mime_encode[] = {
- EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201,
+ EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201_1976_K,
#if defined(UTF8_INPUT_ENABLE)
UTF_8, UTF_8,
#endif
@@ -3631,18 +3759,21 @@
#define MAXRECOVER 20
-static void mime_input_buf_unshift(nkf_char c)
+static void
+mime_input_buf_unshift(nkf_char c)
{
mime_input_buf(--mime_input_state.top) = (unsigned char)c;
}
-nkf_char mime_ungetc(nkf_char c, FILE *f)
+static nkf_char
+mime_ungetc(nkf_char c, FILE *f)
{
mime_input_buf_unshift(c);
return c;
}
-nkf_char mime_ungetc_buf(nkf_char c, FILE *f)
+static nkf_char
+mime_ungetc_buf(nkf_char c, FILE *f)
{
if (mimebuf_f)
(*i_mungetc_buf)(c,f);
@@ -3651,15 +3782,17 @@
return c;
}
-nkf_char mime_getc_buf(FILE *f)
+static nkf_char
+mime_getc_buf(FILE *f)
{
/* we don't keep eof of mime_input_buf, becase it contains ?= as
a terminator. It was checked in mime_integrity. */
return ((mimebuf_f)?
- (*i_mgetc_buf)(f):mime_input_buf(mime_input_state.input++));
+ (*i_mgetc_buf)(f):mime_input_buf(mime_input_state.input++));
}
-void switch_mime_getc(void)
+static void
+switch_mime_getc(void)
{
if (i_getc!=mime_getc) {
i_mgetc = i_getc; i_getc = mime_getc;
@@ -3671,7 +3804,8 @@
}
}
-void unswitch_mime_getc(void)
+static void
+unswitch_mime_getc(void)
{
if(mime_f==STRICT_MIME) {
i_mgetc = i_mgetc_buf;
@@ -3683,7 +3817,8 @@
mime_iconv_back = NULL;
}
-nkf_char mime_integrity(FILE *f, const unsigned char *p)
+static nkf_char
+mime_integrity(FILE *f, const unsigned char *p)
{
nkf_char c,d;
unsigned int q;
@@ -3696,22 +3831,22 @@
d = 0;
q = mime_input_state.input;
while((c=(*i_getc)(f))!=EOF) {
- if (((mime_input_state.input-mime_input_state.top)&MIME_BUF_MASK)==0) {
+ if (((mime_input_state.input-mime_input_state.top)&MIME_BUF_MASK)==0) {
break; /* buffer full */
}
- if (c=='=' && d=='?') {
- /* checked. skip header, start decode */
- mime_input_buf(mime_input_state.input++) = (unsigned char)c;
- /* mime_last_input = mime_input_state.input; */
- mime_input_state.input = q;
+ if (c=='=' && d=='?') {
+ /* checked. skip header, start decode */
+ mime_input_buf(mime_input_state.input++) = (unsigned char)c;
+ /* mime_last_input = mime_input_state.input; */
+ mime_input_state.input = q;
switch_mime_getc();
- return 1;
- }
- if (!( (c=='+'||c=='/'|| c=='=' || c=='?' || is_alnum(c))))
- break;
- /* Should we check length mod 4? */
- mime_input_buf(mime_input_state.input++) = (unsigned char)c;
- d=c;
+ return 1;
+ }
+ if (!( (c=='+'||c=='/'|| c=='=' || c=='?' || is_alnum(c))))
+ break;
+ /* Should we check length mod 4? */
+ mime_input_buf(mime_input_state.input++) = (unsigned char)c;
+ d=c;
}
/* In case of Incomplete MIME, no MIME decode */
mime_input_buf(mime_input_state.input++) = (unsigned char)c;
@@ -3721,7 +3856,8 @@
return 1;
}
-nkf_char mime_begin_strict(FILE *f)
+static nkf_char
+mime_begin_strict(FILE *f)
{
nkf_char c1 = 0;
int i,j,k;
@@ -3735,24 +3871,24 @@
r[0]='='; r[1]='?';
for(i=2;p[i]>SP;i++) { /* start at =? */
- if (((r[i] = c1 = (*i_getc)(f))==EOF) || nkf_toupper(c1) != p[i]) {
- /* pattern fails, try next one */
- q = p;
- while (mime_pattern[++j]) {
+ if (((r[i] = c1 = (*i_getc)(f))==EOF) || nkf_toupper(c1) != p[i]) {
+ /* pattern fails, try next one */
+ q = p;
+ while (mime_pattern[++j]) {
p = mime_pattern[j];
- for(k=2;k<i;k++) /* assume length(p) > i */
- if (p[k]!=q[k]) break;
- if (k==i && nkf_toupper(c1)==p[k]) break;
- }
+ for(k=2;k<i;k++) /* assume length(p) > i */
+ if (p[k]!=q[k]) break;
+ if (k==i && nkf_toupper(c1)==p[k]) break;
+ }
p = mime_pattern[j];
- if (p) continue; /* found next one, continue */
- /* all fails, output from recovery buffer */
- (*i_ungetc)(c1,f);
- for(j=0;j<i;j++) {
- (*oconv)(0,r[j]);
- }
- return c1;
- }
+ if (p) continue; /* found next one, continue */
+ /* all fails, output from recovery buffer */
+ (*i_ungetc)(c1,f);
+ for(j=0;j<i;j++) {
+ (*oconv)(0,r[j]);
+ }
+ return c1;
+ }
}
mime_decode_mode = p[i-2];
@@ -3761,18 +3897,19 @@
clr_code_score(find_inputcode_byfunc(mime_priority_func[j]), SCORE_iMIME);
if (mime_decode_mode=='B') {
- mimebuf_f = unbuf_f;
- if (!unbuf_f) {
- /* do MIME integrity check */
- return mime_integrity(f,mime_pattern[j]);
- }
+ mimebuf_f = unbuf_f;
+ if (!unbuf_f) {
+ /* do MIME integrity check */
+ return mime_integrity(f,mime_pattern[j]);
+ }
}
switch_mime_getc();
mimebuf_f = TRUE;
return c1;
}
-nkf_char mime_begin(FILE *f)
+static nkf_char
+mime_begin(FILE *f)
{
nkf_char c1;
int i,k;
@@ -3784,43 +3921,43 @@
k = mime_input_state.last;
mime_input_buf(mime_input_state.last++)='='; mime_input_buf(mime_input_state.last++)='?';
for(i=2;i<MAXRECOVER;i++) { /* start at =? */
- /* We accept any character type even if it is breaked by new lines */
- c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
- if (c1==LF||c1==SP||c1==CR||
- c1=='-'||c1=='_'||is_alnum(c1)) continue;
- if (c1=='=') {
- /* Failed. But this could be another MIME preemble */
- (*i_ungetc)(c1,f);
- mime_input_state.last--;
- break;
- }
- if (c1!='?') break;
- else {
- /* c1=='?' */
- c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
- if (!(++i<MAXRECOVER) || c1==EOF) break;
- if (c1=='b'||c1=='B') {
- mime_decode_mode = 'B';
- } else if (c1=='q'||c1=='Q') {
- mime_decode_mode = 'Q';
- } else {
- break;
- }
- c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
- if (!(++i<MAXRECOVER) || c1==EOF) break;
- if (c1!='?') {
- mime_decode_mode = FALSE;
- }
- break;
- }
+ /* We accept any character type even if it is breaked by new lines */
+ c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
+ if (c1==LF||c1==SP||c1==CR||
+ c1=='-'||c1=='_'||is_alnum(c1)) continue;
+ if (c1=='=') {
+ /* Failed. But this could be another MIME preemble */
+ (*i_ungetc)(c1,f);
+ mime_input_state.last--;
+ break;
+ }
+ if (c1!='?') break;
+ else {
+ /* c1=='?' */
+ c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
+ if (!(++i<MAXRECOVER) || c1==EOF) break;
+ if (c1=='b'||c1=='B') {
+ mime_decode_mode = 'B';
+ } else if (c1=='q'||c1=='Q') {
+ mime_decode_mode = 'Q';
+ } else {
+ break;
+ }
+ c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
+ if (!(++i<MAXRECOVER) || c1==EOF) break;
+ if (c1!='?') {
+ mime_decode_mode = FALSE;
+ }
+ break;
+ }
}
switch_mime_getc();
if (!mime_decode_mode) {
- /* false MIME premble, restart from mime_buffer */
- mime_decode_mode = 1; /* no decode, but read from the mime_buffer */
- /* Since we are in MIME mode until buffer becomes empty, */
- /* we never go into mime_begin again for a while. */
- return c1;
+ /* false MIME premble, restart from mime_buffer */
+ mime_decode_mode = 1; /* no decode, but read from the mime_buffer */
+ /* Since we are in MIME mode until buffer becomes empty, */
+ /* we never go into mime_begin again for a while. */
+ return c1;
}
/* discard mime preemble, and goto MIME mode */
mime_input_state.last = k;
@@ -3829,20 +3966,23 @@
}
#ifdef CHECK_OPTION
-void no_putc(nkf_char c)
+static void
+no_putc(nkf_char c)
{
;
}
-void debug(const char *str)
+static void
+debug(const char *str)
{
if (debug_f){
- fprintf(stderr, "%s\n", str ? str : "NULL");
+ fprintf(stderr, "%s\n", str ? str : "NULL");
}
}
#endif
-void set_input_codename(char *codename)
+static void
+set_input_codename(char *codename)
{
if (!input_codename) {
input_codename = codename;
@@ -3851,7 +3991,8 @@
}
}
-static char* get_guessed_code(void)
+static char*
+get_guessed_code(void)
{
if (input_codename && !*input_codename) {
input_codename = "BINARY";
@@ -3878,7 +4019,8 @@
}
#if !defined(PERL_XS) && !defined(WIN32DLL)
-void print_guessed_code(char *filename)
+static void
+print_guessed_code(char *filename)
{
if (filename != NULL) printf("%s: ", filename);
if (input_codename && !*input_codename) {
@@ -3902,50 +4044,56 @@
#ifdef INPUT_OPTION
-nkf_char hex_getc(nkf_char ch, FILE *f, nkf_char (*g)(FILE *f), nkf_char (*u)(nkf_char c, FILE *f))
+static nkf_char
+hex_getc(nkf_char ch, FILE *f, nkf_char (*g)(FILE *f), nkf_char (*u)(nkf_char c, FILE *f))
{
nkf_char c1, c2, c3;
c1 = (*g)(f);
if (c1 != ch){
- return c1;
+ return c1;
}
c2 = (*g)(f);
if (!nkf_isxdigit(c2)){
- (*u)(c2, f);
- return c1;
+ (*u)(c2, f);
+ return c1;
}
c3 = (*g)(f);
if (!nkf_isxdigit(c3)){
- (*u)(c2, f);
- (*u)(c3, f);
- return c1;
+ (*u)(c2, f);
+ (*u)(c3, f);
+ return c1;
}
return (hex2bin(c2) << 4) | hex2bin(c3);
}
-nkf_char cap_getc(FILE *f)
+static nkf_char
+cap_getc(FILE *f)
{
return hex_getc(':', f, i_cgetc, i_cungetc);
}
-nkf_char cap_ungetc(nkf_char c, FILE *f)
+static nkf_char
+cap_ungetc(nkf_char c, FILE *f)
{
return (*i_cungetc)(c, f);
}
-nkf_char url_getc(FILE *f)
+static nkf_char
+url_getc(FILE *f)
{
return hex_getc('%', f, i_ugetc, i_uungetc);
}
-nkf_char url_ungetc(nkf_char c, FILE *f)
+static nkf_char
+url_ungetc(nkf_char c, FILE *f)
{
return (*i_uungetc)(c, f);
}
#endif
#ifdef NUMCHAR_OPTION
-nkf_char numchar_getc(FILE *f)
+static nkf_char
+numchar_getc(FILE *f)
{
nkf_char (*g)(FILE *) = i_ngetc;
nkf_char (*u)(nkf_char c ,FILE *f) = i_nungetc;
@@ -3955,50 +4103,51 @@
buf[i] = (*g)(f);
if (buf[i] == '&'){
- buf[++i] = (*g)(f);
- if (buf[i] == '#'){
- c = 0;
- buf[++i] = (*g)(f);
- if (buf[i] == 'x' || buf[i] == 'X'){
- for (j = 0; j < 7; j++){
- buf[++i] = (*g)(f);
- if (!nkf_isxdigit(buf[i])){
- if (buf[i] != ';'){
- c = -1;
- }
- break;
- }
- c <<= 4;
- c |= hex2bin(buf[i]);
- }
- }else{
- for (j = 0; j < 8; j++){
- if (j){
- buf[++i] = (*g)(f);
- }
- if (!nkf_isdigit(buf[i])){
- if (buf[i] != ';'){
- c = -1;
- }
- break;
- }
- c *= 10;
- c += hex2bin(buf[i]);
- }
- }
- }
+ buf[++i] = (*g)(f);
+ if (buf[i] == '#'){
+ c = 0;
+ buf[++i] = (*g)(f);
+ if (buf[i] == 'x' || buf[i] == 'X'){
+ for (j = 0; j < 7; j++){
+ buf[++i] = (*g)(f);
+ if (!nkf_isxdigit(buf[i])){
+ if (buf[i] != ';'){
+ c = -1;
+ }
+ break;
+ }
+ c <<= 4;
+ c |= hex2bin(buf[i]);
+ }
+ }else{
+ for (j = 0; j < 8; j++){
+ if (j){
+ buf[++i] = (*g)(f);
+ }
+ if (!nkf_isdigit(buf[i])){
+ if (buf[i] != ';'){
+ c = -1;
+ }
+ break;
+ }
+ c *= 10;
+ c += hex2bin(buf[i]);
+ }
+ }
+ }
}
if (c != -1){
- return CLASS_UNICODE | c;
+ return nkf_char_unicode_new(c);
}
while (i > 0){
- (*u)(buf[i], f);
- --i;
+ (*u)(buf[i], f);
+ --i;
}
return buf[0];
}
-nkf_char numchar_ungetc(nkf_char c, FILE *f)
+static nkf_char
+numchar_ungetc(nkf_char c, FILE *f)
{
return (*i_nungetc)(c, f);
}
@@ -4007,7 +4156,8 @@
#ifdef UNICODE_NORMALIZATION
/* Normalization Form C */
-nkf_char nfc_getc(FILE *f)
+static nkf_char
+nfc_getc(FILE *f)
{
nkf_char (*g)(FILE *f) = i_nfc_getc;
nkf_char (*u)(nkf_char c ,FILE *f) = i_nfc_ungetc;
@@ -4043,35 +4193,37 @@
return buf[0];
}
-nkf_char nfc_ungetc(nkf_char c, FILE *f)
+static nkf_char
+nfc_ungetc(nkf_char c, FILE *f)
{
return (*i_nfc_ungetc)(c, f);
}
#endif /* UNICODE_NORMALIZATION */
-static nkf_char base64decode(nkf_char c)
+static nkf_char
+base64decode(nkf_char c)
{
int i;
if (c > '@') {
- if (c < '[') {
- i = c - 'A'; /* A..Z 0-25 */
+ if (c < '[') {
+ i = c - 'A'; /* A..Z 0-25 */
} else if (c == '_') {
i = '?' /* 63 */ ; /* _ 63 */
- } else {
- i = c - 'G' /* - 'a' + 26 */ ; /* a..z 26-51 */
+ } else {
+ i = c - 'G' /* - 'a' + 26 */ ; /* a..z 26-51 */
}
} else if (c > '/') {
- i = c - '0' + '4' /* - '0' + 52 */ ; /* 0..9 52-61 */
+ i = c - '0' + '4' /* - '0' + 52 */ ; /* 0..9 52-61 */
} else if (c == '+' || c == '-') {
- i = '>' /* 62 */ ; /* + and - 62 */
+ i = '>' /* 62 */ ; /* + and - 62 */
} else {
- i = '?' /* 63 */ ; /* / 63 */
+ i = '?' /* 63 */ ; /* / 63 */
}
return (i);
}
-nkf_char
+static nkf_char
mime_getc(FILE *f)
{
nkf_char c1, c2, c3, c4, cc;
@@ -4082,7 +4234,7 @@
nkf_char lwsp_size = 128;
if (mime_input_state.top != mime_input_state.last) { /* Something is in FIFO */
- return mime_input_buf(mime_input_state.top++);
+ return mime_input_buf(mime_input_state.top++);
}
if (mime_decode_mode==1 ||mime_decode_mode==FALSE) {
mime_decode_mode=FALSE;
@@ -4091,26 +4243,26 @@
}
if (mimebuf_f == FIXED_MIME)
- exit_mode = mime_decode_mode;
+ exit_mode = mime_decode_mode;
else
- exit_mode = FALSE;
+ exit_mode = FALSE;
if (mime_decode_mode == 'Q') {
- if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
-restart_mime_q:
- if (c1=='_' && mimebuf_f != FIXED_MIME) return SP;
+ if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
+ restart_mime_q:
+ if (c1=='_' && mimebuf_f != FIXED_MIME) return SP;
if (c1<=SP || DEL<=c1) {
mime_decode_mode = exit_mode; /* prepare for quit */
return c1;
}
- if (c1!='=' && (c1!='?' || mimebuf_f == FIXED_MIME)) {
+ if (c1!='=' && (c1!='?' || mimebuf_f == FIXED_MIME)) {
return c1;
}
- mime_decode_mode = exit_mode; /* prepare for quit */
- if ((c2 = (*i_mgetc)(f)) == EOF) return (EOF);
- if (c1=='?'&&c2=='=' && mimebuf_f != FIXED_MIME) {
- /* end Q encoding */
- input_mode = exit_mode;
+ mime_decode_mode = exit_mode; /* prepare for quit */
+ if ((c2 = (*i_mgetc)(f)) == EOF) return (EOF);
+ if (c1=='?'&&c2=='=' && mimebuf_f != FIXED_MIME) {
+ /* end Q encoding */
+ input_mode = exit_mode;
lwsp_count = 0;
lwsp_buf = malloc((lwsp_size+5)*sizeof(char));
if (lwsp_buf==NULL) {
@@ -4168,57 +4320,57 @@
c1 = lwsp_buf[0];
}
free(lwsp_buf);
- return c1;
- }
- if (c1=='='&&c2<SP) { /* this is soft wrap */
- while((c1 = (*i_mgetc)(f)) <=SP) {
+ return c1;
+ }
+ if (c1=='='&&c2<SP) { /* this is soft wrap */
+ while((c1 = (*i_mgetc)(f)) <=SP) {
if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
}
- mime_decode_mode = 'Q'; /* still in MIME */
+ mime_decode_mode = 'Q'; /* still in MIME */
goto restart_mime_q;
}
- if (c1=='?') {
- mime_decode_mode = 'Q'; /* still in MIME */
- (*i_mungetc)(c2,f);
- return c1;
- }
- if ((c3 = (*i_mgetc)(f)) == EOF) return (EOF);
- if (c2<=SP) return c2;
- mime_decode_mode = 'Q'; /* still in MIME */
- return ((hex2bin(c2)<<4) + hex2bin(c3));
+ if (c1=='?') {
+ mime_decode_mode = 'Q'; /* still in MIME */
+ (*i_mungetc)(c2,f);
+ return c1;
+ }
+ if ((c3 = (*i_mgetc)(f)) == EOF) return (EOF);
+ if (c2<=SP) return c2;
+ mime_decode_mode = 'Q'; /* still in MIME */
+ return ((hex2bin(c2)<<4) + hex2bin(c3));
}
if (mime_decode_mode != 'B') {
- mime_decode_mode = FALSE;
- return (*i_mgetc)(f);
+ mime_decode_mode = FALSE;
+ return (*i_mgetc)(f);
}
/* Base64 encoding */
/*
- MIME allows line break in the middle of
- Base64, but we are very pessimistic in decoding
- in unbuf mode because MIME encoded code may broken by
- less or editor's control sequence (such as ESC-[-K in unbuffered
- mode. ignore incomplete MIME.
- */
+ MIME allows line break in the middle of
+ Base64, but we are very pessimistic in decoding
+ in unbuf mode because MIME encoded code may broken by
+ less or editor's control sequence (such as ESC-[-K in unbuffered
+ mode. ignore incomplete MIME.
+ */
mode = mime_decode_mode;
mime_decode_mode = exit_mode; /* prepare for quit */
while ((c1 = (*i_mgetc)(f))<=SP) {
- if (c1==EOF)
- return (EOF);
+ if (c1==EOF)
+ return (EOF);
}
-mime_c2_retry:
+ mime_c2_retry:
if ((c2 = (*i_mgetc)(f))<=SP) {
- if (c2==EOF)
- return (EOF);
+ if (c2==EOF)
+ return (EOF);
if (mime_f != STRICT_MIME) goto mime_c2_retry;
- if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;
- return c2;
+ if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c2;
}
if ((c1 == '?') && (c2 == '=')) {
- input_mode = ASCII;
+ input_mode = ASCII;
lwsp_count = 0;
lwsp_buf = malloc((lwsp_size+5)*sizeof(char));
if (lwsp_buf==NULL) {
@@ -4279,23 +4431,23 @@
c1 = lwsp_buf[0];
}
free(lwsp_buf);
- return c1;
+ return c1;
}
-mime_c3_retry:
+ mime_c3_retry:
if ((c3 = (*i_mgetc)(f))<=SP) {
- if (c3==EOF)
- return (EOF);
+ if (c3==EOF)
+ return (EOF);
if (mime_f != STRICT_MIME) goto mime_c3_retry;
- if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;
- return c3;
+ if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c3;
}
-mime_c4_retry:
+ mime_c4_retry:
if ((c4 = (*i_mgetc)(f))<=SP) {
- if (c4==EOF)
- return (EOF);
+ if (c4==EOF)
+ return (EOF);
if (mime_f != STRICT_MIME) goto mime_c4_retry;
- if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;
- return c4;
+ if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c4;
}
mime_decode_mode = mode; /* still in MIME sigh... */
@@ -4308,22 +4460,22 @@
t4 = 0x3f & base64decode(c4);
cc = ((t1 << 2) & 0x0fc) | ((t2 >> 4) & 0x03);
if (c2 != '=') {
- mime_input_buf(mime_input_state.last++) = (unsigned char)cc;
- cc = ((t2 << 4) & 0x0f0) | ((t3 >> 2) & 0x0f);
- if (c3 != '=') {
- mime_input_buf(mime_input_state.last++) = (unsigned char)cc;
- cc = ((t3 << 6) & 0x0c0) | (t4 & 0x3f);
- if (c4 != '=')
- mime_input_buf(mime_input_state.last++) = (unsigned char)cc;
- }
+ mime_input_buf(mime_input_state.last++) = (unsigned char)cc;
+ cc = ((t2 << 4) & 0x0f0) | ((t3 >> 2) & 0x0f);
+ if (c3 != '=') {
+ mime_input_buf(mime_input_state.last++) = (unsigned char)cc;
+ cc = ((t3 << 6) & 0x0c0) | (t4 & 0x3f);
+ if (c4 != '=')
+ mime_input_buf(mime_input_state.last++) = (unsigned char)cc;
+ }
} else {
- return c1;
+ return c1;
}
return mime_input_buf(mime_input_state.top++);
}
static const char basis_64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define MIMEOUT_BUF_LENGTH (60)
static struct {
@@ -4334,7 +4486,8 @@
/*nkf_char mime_lastchar2, mime_lastchar1;*/
-static void open_mime(nkf_char mode)
+static void
+open_mime(nkf_char mode)
{
const unsigned char *p;
int i;
@@ -4350,7 +4503,7 @@
i = 0;
if (base64_count>45) {
if (mimeout_state.count>0 && nkf_isblank(mimeout_state.buf[i])){
- (*o_mputc)(mimeout_state.buf[i]);
+ (*o_mputc)(mimeout_state.buf[i]);
i++;
}
PUT_NEWLINE((*o_mputc));
@@ -4358,7 +4511,7 @@
base64_count = 1;
if (mimeout_state.count>0
&& (mimeout_state.buf[i]==SP || mimeout_state.buf[i]==TAB
- || mimeout_state.buf[i]==CR || mimeout_state.buf[i]==LF)) {
+ || mimeout_state.buf[i]==CR || mimeout_state.buf[i]==LF)) {
i++;
}
}
@@ -4372,8 +4525,8 @@
}
}
while(*p) {
- (*o_mputc)(*p++);
- base64_count ++;
+ (*o_mputc)(*p++);
+ base64_count ++;
}
j = mimeout_state.count;
mimeout_state.count = 0;
@@ -4382,25 +4535,26 @@
}
}
-static void mime_prechar(nkf_char c2, nkf_char c1)
+static void
+mime_prechar(nkf_char c2, nkf_char c1)
{
if (mimeout_mode > 0){
- if (c2 == EOF){
- if (base64_count + mimeout_state.count/3*4> 73){
- (*o_base64conv)(EOF,0);
- OCONV_NEWLINE((*o_base64conv));
- (*o_base64conv)(0,SP);
- base64_count = 1;
- }
- } else {
- if (base64_count + mimeout_state.count/3*4> 66) {
- (*o_base64conv)(EOF,0);
- OCONV_NEWLINE((*o_base64conv));
- (*o_base64conv)(0,SP);
- base64_count = 1;
- mimeout_mode = -1;
- }
- }
+ if (c2 == EOF){
+ if (base64_count + mimeout_state.count/3*4> 73){
+ (*o_base64conv)(EOF,0);
+ OCONV_NEWLINE((*o_base64conv));
+ (*o_base64conv)(0,SP);
+ base64_count = 1;
+ }
+ } else {
+ if (base64_count + mimeout_state.count/3*4> 66) {
+ (*o_base64conv)(EOF,0);
+ OCONV_NEWLINE((*o_base64conv));
+ (*o_base64conv)(0,SP);
+ base64_count = 1;
+ mimeout_mode = -1;
+ }
+ }
} else if (c2) {
if (c2 != EOF && base64_count + mimeout_state.count/3*4> 60) {
mimeout_mode = (output_mode==ASCII ||output_mode == ISO_8859_1) ? 'Q' : 'B';
@@ -4414,7 +4568,8 @@
}
}
-static void close_mime(void)
+static void
+close_mime(void)
{
(*o_mputc)('?');
(*o_mputc)('=');
@@ -4422,7 +4577,8 @@
mimeout_mode = 0;
}
-static void eof_mime(void)
+static void
+eof_mime(void)
{
switch(mimeout_mode) {
case 'Q':
@@ -4448,7 +4604,8 @@
}
}
-static void mimeout_addchar(nkf_char c)
+static void
+mimeout_addchar(nkf_char c)
{
switch(mimeout_mode) {
case 'Q':
@@ -4464,60 +4621,61 @@
(*o_mputc)(c);
base64_count++;
}
- break;
+ break;
case 'B':
- mimeout_state.state=c;
- (*o_mputc)(basis_64[c>>2]);
- mimeout_mode=2;
- base64_count ++;
- break;
+ mimeout_state.state=c;
+ (*o_mputc)(basis_64[c>>2]);
+ mimeout_mode=2;
+ base64_count ++;
+ break;
case 2:
- (*o_mputc)(basis_64[((mimeout_state.state & 0x3)<< 4) | ((c & 0xF0) >> 4)]);
- mimeout_state.state=c;
- mimeout_mode=1;
- base64_count ++;
- break;
+ (*o_mputc)(basis_64[((mimeout_state.state & 0x3)<< 4) | ((c & 0xF0) >> 4)]);
+ mimeout_state.state=c;
+ mimeout_mode=1;
+ base64_count ++;
+ break;
case 1:
- (*o_mputc)(basis_64[((mimeout_state.state & 0xF) << 2) | ((c & 0xC0) >>6)]);
- (*o_mputc)(basis_64[c & 0x3F]);
- mimeout_mode='B';
- base64_count += 2;
- break;
+ (*o_mputc)(basis_64[((mimeout_state.state & 0xF) << 2) | ((c & 0xC0) >>6)]);
+ (*o_mputc)(basis_64[c & 0x3F]);
+ mimeout_mode='B';
+ base64_count += 2;
+ break;
default:
(*o_mputc)(c);
base64_count++;
- break;
+ break;
}
}
-static void mime_putc(nkf_char c)
+static void
+mime_putc(nkf_char c)
{
int i, j;
nkf_char lastchar;
if (mimeout_f == FIXED_MIME){
- if (mimeout_mode == 'Q'){
- if (base64_count > 71){
- if (c!=CR && c!=LF) {
- (*o_mputc)('=');
- PUT_NEWLINE((*o_mputc));
- }
- base64_count = 0;
- }
- }else{
- if (base64_count > 71){
- eof_mime();
- PUT_NEWLINE((*o_mputc));
- base64_count = 0;
- }
- if (c == EOF) { /* c==EOF */
- eof_mime();
- }
- }
- if (c != EOF) { /* c==EOF */
- mimeout_addchar(c);
- }
- return;
+ if (mimeout_mode == 'Q'){
+ if (base64_count > 71){
+ if (c!=CR && c!=LF) {
+ (*o_mputc)('=');
+ PUT_NEWLINE((*o_mputc));
+ }
+ base64_count = 0;
+ }
+ }else{
+ if (base64_count > 71){
+ eof_mime();
+ PUT_NEWLINE((*o_mputc));
+ base64_count = 0;
+ }
+ if (c == EOF) { /* c==EOF */
+ eof_mime();
+ }
+ }
+ if (c != EOF) { /* c==EOF */
+ mimeout_addchar(c);
+ }
+ return;
}
/* mimeout_f != FIXED_MIME */
@@ -4550,24 +4708,24 @@
mimeout_addchar(mimeout_state.buf[i]);
}
}
- return;
+ return;
}
if (mimeout_state.count > 0){
- lastchar = mimeout_state.buf[mimeout_state.count - 1];
+ lastchar = mimeout_state.buf[mimeout_state.count - 1];
}else{
- lastchar = -1;
+ lastchar = -1;
}
if (mimeout_mode=='Q') {
- if (c <= DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) {
+ if (c <= DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) {
if (c == CR || c == LF) {
close_mime();
(*o_mputc)(c);
base64_count = 0;
return;
- } else if (c <= SP) {
- close_mime();
+ } else if (c <= SP) {
+ close_mime();
if (base64_count > 70) {
PUT_NEWLINE((*o_mputc));
base64_count = 0;
@@ -4576,7 +4734,7 @@
(*o_mputc)(SP);
base64_count++;
}
- } else {
+ } else {
if (base64_count > 70) {
close_mime();
PUT_NEWLINE((*o_mputc));
@@ -4591,129 +4749,129 @@
}
(*o_mputc)(c);
base64_count++;
- }
- return;
+ }
+ return;
}
if (mimeout_mode <= 0) {
- if (c <= DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) {
- if (nkf_isspace(c)) {
+ if (c <= DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) {
+ if (nkf_isspace(c)) {
int flag = 0;
if (mimeout_mode == -1) {
flag = 1;
}
- if (c==CR || c==LF) {
+ if (c==CR || c==LF) {
if (flag) {
open_mime(output_mode);
output_mode = 0;
} else {
base64_count = 0;
}
- }
- for (i=0;i<mimeout_state.count;i++) {
- (*o_mputc)(mimeout_state.buf[i]);
- if (mimeout_state.buf[i] == CR || mimeout_state.buf[i] == LF){
- base64_count = 0;
- }else{
- base64_count++;
- }
- }
+ }
+ for (i=0;i<mimeout_state.count;i++) {
+ (*o_mputc)(mimeout_state.buf[i]);
+ if (mimeout_state.buf[i] == CR || mimeout_state.buf[i] == LF){
+ base64_count = 0;
+ }else{
+ base64_count++;
+ }
+ }
if (flag) {
eof_mime();
base64_count = 0;
mimeout_mode = 0;
- }
+ }
mimeout_state.buf[0] = (char)c;
mimeout_state.count = 1;
- }else{
- if (base64_count > 1
- && base64_count + mimeout_state.count > 76
+ }else{
+ if (base64_count > 1
+ && base64_count + mimeout_state.count > 76
&& mimeout_state.buf[0] != CR && mimeout_state.buf[0] != LF){
- PUT_NEWLINE((*o_mputc));
- base64_count = 0;
- if (!nkf_isspace(mimeout_state.buf[0])){
- (*o_mputc)(SP);
- base64_count++;
- }
- }
- mimeout_state.buf[mimeout_state.count++] = (char)c;
- if (mimeout_state.count>MIMEOUT_BUF_LENGTH) {
- open_mime(output_mode);
- }
- }
- return;
- }else{
- if (lastchar==CR || lastchar == LF){
- for (i=0;i<mimeout_state.count;i++) {
- (*o_mputc)(mimeout_state.buf[i]);
- }
- base64_count = 0;
- mimeout_state.count = 0;
- }
- if (lastchar==SP) {
- for (i=0;i<mimeout_state.count-1;i++) {
- (*o_mputc)(mimeout_state.buf[i]);
- base64_count++;
- }
- mimeout_state.buf[0] = SP;
- mimeout_state.count = 1;
- }
- open_mime(output_mode);
- }
+ PUT_NEWLINE((*o_mputc));
+ base64_count = 0;
+ if (!nkf_isspace(mimeout_state.buf[0])){
+ (*o_mputc)(SP);
+ base64_count++;
+ }
+ }
+ mimeout_state.buf[mimeout_state.count++] = (char)c;
+ if (mimeout_state.count>MIMEOUT_BUF_LENGTH) {
+ open_mime(output_mode);
+ }
+ }
+ return;
+ }else{
+ if (lastchar==CR || lastchar == LF){
+ for (i=0;i<mimeout_state.count;i++) {
+ (*o_mputc)(mimeout_state.buf[i]);
+ }
+ base64_count = 0;
+ mimeout_state.count = 0;
+ }
+ if (lastchar==SP) {
+ for (i=0;i<mimeout_state.count-1;i++) {
+ (*o_mputc)(mimeout_state.buf[i]);
+ base64_count++;
+ }
+ mimeout_state.buf[0] = SP;
+ mimeout_state.count = 1;
+ }
+ open_mime(output_mode);
+ }
}else{
- /* mimeout_mode == 'B', 1, 2 */
- if ( c<=DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) {
- if (lastchar == CR || lastchar == LF){
- if (nkf_isblank(c)) {
- for (i=0;i<mimeout_state.count;i++) {
- mimeout_addchar(mimeout_state.buf[i]);
- }
- mimeout_state.count = 0;
- } else if (SP<c && c<DEL) {
- eof_mime();
- for (i=0;i<mimeout_state.count;i++) {
- (*o_mputc)(mimeout_state.buf[i]);
- }
- base64_count = 0;
- mimeout_state.count = 0;
- }
- mimeout_state.buf[mimeout_state.count++] = (char)c;
+ /* mimeout_mode == 'B', 1, 2 */
+ if ( c<=DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) {
+ if (lastchar == CR || lastchar == LF){
+ if (nkf_isblank(c)) {
+ for (i=0;i<mimeout_state.count;i++) {
+ mimeout_addchar(mimeout_state.buf[i]);
+ }
+ mimeout_state.count = 0;
+ } else if (SP<c && c<DEL) {
+ eof_mime();
+ for (i=0;i<mimeout_state.count;i++) {
+ (*o_mputc)(mimeout_state.buf[i]);
+ }
+ base64_count = 0;
+ mimeout_state.count = 0;
+ }
+ mimeout_state.buf[mimeout_state.count++] = (char)c;
return;
- }
- if (c==SP || c==TAB || c==CR || c==LF) {
- for (i=0;i<mimeout_state.count;i++) {
- if (SP<mimeout_state.buf[i] && mimeout_state.buf[i]<DEL) {
- eof_mime();
- for (i=0;i<mimeout_state.count;i++) {
- (*o_mputc)(mimeout_state.buf[i]);
- base64_count++;
- }
- mimeout_state.count = 0;
- }
- }
- mimeout_state.buf[mimeout_state.count++] = (char)c;
- if (mimeout_state.count>MIMEOUT_BUF_LENGTH) {
- eof_mime();
- for (i=0;i<mimeout_state.count;i++) {
- (*o_mputc)(mimeout_state.buf[i]);
- base64_count++;
- }
- mimeout_state.count = 0;
- }
- return;
}
- if (mimeout_state.count>0 && SP<c && c!='=') {
- mimeout_state.buf[mimeout_state.count++] = (char)c;
- if (mimeout_state.count>MIMEOUT_BUF_LENGTH) {
- j = mimeout_state.count;
- mimeout_state.count = 0;
- for (i=0;i<j;i++) {
- mimeout_addchar(mimeout_state.buf[i]);
- }
- }
- return;
- }
- }
+ if (c==SP || c==TAB || c==CR || c==LF) {
+ for (i=0;i<mimeout_state.count;i++) {
+ if (SP<mimeout_state.buf[i] && mimeout_state.buf[i]<DEL) {
+ eof_mime();
+ for (i=0;i<mimeout_state.count;i++) {
+ (*o_mputc)(mimeout_state.buf[i]);
+ base64_count++;
+ }
+ mimeout_state.count = 0;
+ }
+ }
+ mimeout_state.buf[mimeout_state.count++] = (char)c;
+ if (mimeout_state.count>MIMEOUT_BUF_LENGTH) {
+ eof_mime();
+ for (i=0;i<mimeout_state.count;i++) {
+ (*o_mputc)(mimeout_state.buf[i]);
+ base64_count++;
+ }
+ mimeout_state.count = 0;
+ }
+ return;
+ }
+ if (mimeout_state.count>0 && SP<c && c!='=') {
+ mimeout_state.buf[mimeout_state.count++] = (char)c;
+ if (mimeout_state.count>MIMEOUT_BUF_LENGTH) {
+ j = mimeout_state.count;
+ mimeout_state.count = 0;
+ for (i=0;i<j;i++) {
+ mimeout_addchar(mimeout_state.buf[i]);
+ }
+ }
+ return;
+ }
+ }
}
if (mimeout_state.count>0) {
j = mimeout_state.count;
@@ -4735,7 +4893,8 @@
mimeout_addchar(c);
}
-void base64_conv(nkf_char c2, nkf_char c1)
+static void
+base64_conv(nkf_char c2, nkf_char c1)
{
mime_prechar(c2, c1);
(*o_base64conv)(c2,c1);
@@ -4750,34 +4909,36 @@
size_t output_buffer_size;
}
-nkf_iconv_t nkf_iconv_new(char *tocode, char *fromcode)
+static nkf_iconv_t
+nkf_iconv_new(char *tocode, char *fromcode)
{
nkf_iconv_t converter;
converter->input_buffer_size = IOBUF_SIZE;
converter->input_buffer = malloc(converter->input_buffer_size);
if (converter->input_buffer == NULL)
- perror("can't malloc");
+ perror("can't malloc");
converter->output_buffer_size = IOBUF_SIZE * 2;
converter->output_buffer = malloc(converter->output_buffer_size);
if (converter->output_buffer == NULL)
- perror("can't malloc");
+ perror("can't malloc");
converter->cd = iconv_open(tocode, fromcode);
if (converter->cd == (iconv_t)-1)
{
- switch (errno) {
- case EINVAL:
- perror(fprintf("iconv doesn't support %s to %s conversion.", fromcode, tocode));
- return -1;
- default:
- perror("can't iconv_open");
- }
+ switch (errno) {
+ case EINVAL:
+ perror(fprintf("iconv doesn't support %s to %s conversion.", fromcode, tocode));
+ return -1;
+ default:
+ perror("can't iconv_open");
+ }
}
}
-size_t nkf_iconv_convert(nkf_iconv_t *converter, FILE *input)
+static size_t
+nkf_iconv_convert(nkf_iconv_t *converter, FILE *input)
{
size_t invalid = (size_t)0;
char *input_buffer = converter->input_buffer;
@@ -4787,61 +4948,63 @@
int c;
do {
- if (c != EOF) {
- while ((c = (*i_getc)(f)) != EOF) {
- input_buffer[input_length++] = c;
- if (input_length < converter->input_buffer_size) break;
- }
- }
+ if (c != EOF) {
+ while ((c = (*i_getc)(f)) != EOF) {
+ input_buffer[input_length++] = c;
+ if (input_length < converter->input_buffer_size) break;
+ }
+ }
- size_t ret = iconv(converter->cd, &input_buffer, &input_length, &output_buffer, &output_length);
- while (output_length-- > 0) {
- (*o_putc)(output_buffer[converter->output_buffer_size-output_length]);
- }
- if (ret == (size_t) - 1) {
- switch (errno) {
- case EINVAL:
- if (input_buffer != converter->input_buffer)
- memmove(converter->input_buffer, input_buffer, input_length);
- break;
- case E2BIG:
- converter->output_buffer_size *= 2;
- output_buffer = realloc(converter->outbuf, converter->output_buffer_size);
- if (output_buffer == NULL) {
- perror("can't realloc");
- return -1;
- }
- converter->output_buffer = output_buffer;
- break;
- default:
- perror("can't iconv");
- return -1;
- }
- } else {
- invalid += ret;
- }
+ size_t ret = iconv(converter->cd, &input_buffer, &input_length, &output_buffer, &output_length);
+ while (output_length-- > 0) {
+ (*o_putc)(output_buffer[converter->output_buffer_size-output_length]);
+ }
+ if (ret == (size_t) - 1) {
+ switch (errno) {
+ case EINVAL:
+ if (input_buffer != converter->input_buffer)
+ memmove(converter->input_buffer, input_buffer, input_length);
+ break;
+ case E2BIG:
+ converter->output_buffer_size *= 2;
+ output_buffer = realloc(converter->outbuf, converter->output_buffer_size);
+ if (output_buffer == NULL) {
+ perror("can't realloc");
+ return -1;
+ }
+ converter->output_buffer = output_buffer;
+ break;
+ default:
+ perror("can't iconv");
+ return -1;
+ }
+ } else {
+ invalid += ret;
+ }
} while (1);
return invalid;
}
-void nkf_iconv_close(nkf_iconv_t *convert)
+static void
+nkf_iconv_close(nkf_iconv_t *convert)
{
- free(converter->inbuf);
- free(converter->outbuf);
- iconv_close(converter->cd);
+ free(converter->inbuf);
+ free(converter->outbuf);
+ iconv_close(converter->cd);
}
#endif
-void reinit(void)
+static void
+reinit(void)
{
{
- struct input_code *p = input_code_list;
- while (p->name){
- status_reinit(p++);
- }
+ struct input_code *p = input_code_list;
+ while (p->name){
+ status_reinit(p++);
+ }
}
unbuf_f = FALSE;
estab_f = FALSE;
@@ -4897,10 +5060,10 @@
x0213_f = FALSE;
#endif
{
- int i;
- for (i = 0; i < 256; i++){
- prefix_table[i] = 0;
- }
+ int i;
+ for (i = 0; i < 256; i++){
+ prefix_table[i] = 0;
+ }
}
hold_count = 0;
mimeout_state.count = 0;
@@ -4933,7 +5096,6 @@
i_mungetc_buf = std_ungetc;
output_mode = ASCII;
input_mode = ASCII;
- shift_mode = FALSE;
mime_decode_mode = FALSE;
file_out_f = FALSE;
eolmode_f = 0;
@@ -4953,12 +5115,17 @@
#endif /*WIN32DLL*/
}
-void module_connection(void)
+static int
+module_connection(void)
{
if (input_encoding) set_input_encoding(input_encoding);
if (!output_encoding) {
output_encoding = nkf_default_encoding();
}
+ if (!output_encoding) {
+ if (noout_f || guess_f) output_encoding = nkf_enc_from_index(ISO_2022_JP);
+ else return -1;
+ }
set_output_encoding(output_encoding);
oconv = nkf_enc_to_oconv(output_encoding);
o_putc = std_putc;
@@ -4968,7 +5135,7 @@
/* output redicrection */
#ifdef CHECK_OPTION
if (noout_f || guess_f){
- o_putc = no_putc;
+ o_putc = no_putc;
}
#endif
if (mimeout_f) {
@@ -5005,24 +5172,24 @@
/* input redicrection */
#ifdef INPUT_OPTION
if (cap_f){
- i_cgetc = i_getc; i_getc = cap_getc;
- i_cungetc = i_ungetc; i_ungetc= cap_ungetc;
+ i_cgetc = i_getc; i_getc = cap_getc;
+ i_cungetc = i_ungetc; i_ungetc= cap_ungetc;
}
if (url_f){
- i_ugetc = i_getc; i_getc = url_getc;
- i_uungetc = i_ungetc; i_ungetc= url_ungetc;
+ i_ugetc = i_getc; i_getc = url_getc;
+ i_uungetc = i_ungetc; i_ungetc= url_ungetc;
}
#endif
#ifdef NUMCHAR_OPTION
if (numchar_f){
- i_ngetc = i_getc; i_getc = numchar_getc;
- i_nungetc = i_ungetc; i_ungetc= numchar_ungetc;
+ i_ngetc = i_getc; i_getc = numchar_getc;
+ i_nungetc = i_ungetc; i_ungetc= numchar_ungetc;
}
#endif
#ifdef UNICODE_NORMALIZATION
if (nfc_f){
- i_nfc_getc = i_getc; i_getc = nfc_getc;
- i_nfc_ungetc = i_ungetc; i_ungetc= nfc_ungetc;
+ i_nfc_getc = i_getc; i_getc = nfc_getc;
+ i_nfc_ungetc = i_ungetc; i_ungetc= nfc_ungetc;
}
#endif
if (mime_f && mimebuf_f==FIXED_MIME) {
@@ -5034,17 +5201,18 @@
i_bungetc = i_ungetc; i_ungetc = broken_ungetc;
}
if (input_encoding) {
- set_iconv(-TRUE, nkf_enc_to_iconv(input_encoding));
+ set_iconv(-TRUE, nkf_enc_to_iconv(input_encoding));
} else {
- set_iconv(FALSE, e_iconv);
+ set_iconv(FALSE, e_iconv);
}
{
- struct input_code *p = input_code_list;
- while (p->name){
- status_reinit(p++);
- }
+ struct input_code *p = input_code_list;
+ while (p->name){
+ status_reinit(p++);
+ }
}
+ return 0;
}
/*
@@ -5052,22 +5220,38 @@
*/
#if !defined(PERL_XS) && !defined(WIN32DLL)
-nkf_char noconvert(FILE *f)
+static nkf_char
+noconvert(FILE *f)
{
nkf_char c;
if (nop_f == 2)
module_connection();
while ((c = (*i_getc)(f)) != EOF)
- (*o_putc)(c);
+ (*o_putc)(c);
(*o_putc)(EOF);
return 1;
}
#endif
-nkf_char kanji_convert(FILE *f)
+#define NEXT continue /* no output, get next */
+#define SKIP c2=0;continue /* no output, get next */
+#define MORE c2=c1;continue /* need one more byte */
+#define SEND ; /* output c1 and c2, get next */
+#define LAST break /* end of loop, go closing */
+#define set_input_mode(mode) do { \
+ input_mode = mode; \
+ shift_mode = 0; \
+ set_input_codename("ISO-2022-JP"); \
+ debug("ISO-2022-JP"); \
+} while (0)
+
+static int
+kanji_convert(FILE *f)
{
- nkf_char c3, c2=0, c1, c0=0;
+ nkf_char c1=0, c2=0, c3=0, c4=0;
+ int shift_mode = 0; /* 0, 1, 2, 3 */
+ char g2 = 0;
int is_8bit = FALSE;
if (input_encoding && !nkf_enc_asciicompat(input_encoding)) {
@@ -5076,325 +5260,278 @@
input_mode = ASCII;
output_mode = ASCII;
- shift_mode = FALSE;
-#define NEXT continue /* no output, get next */
-#define SEND ; /* output c1 and c2, get next */
-#define LAST break /* end of loop, go closing */
-
- module_connection();
+ if (module_connection() < 0) {
+#if !defined(PERL_XS) && !defined(WIN32DLL)
+ fprintf(stderr, "no output encoding given\n");
+#endif
+ return -1;
+ }
check_bom(f);
+#ifdef UTF8_INPUT_ENABLE
+ if(iconv == w_iconv32){
+ while ((c1 = (*i_getc)(f)) != EOF &&
+ (c2 = (*i_getc)(f)) != EOF &&
+ (c3 = (*i_getc)(f)) != EOF &&
+ (c4 = (*i_getc)(f)) != EOF) {
+ nkf_iconv_utf_32(c1, c2, c3, c4);
+ }
+ (*i_ungetc)(EOF, f);
+ }
+ else if (iconv == w_iconv16) {
+ while ((c1 = (*i_getc)(f)) != EOF &&
+ (c2 = (*i_getc)(f)) != EOF) {
+ if (nkf_iconv_utf_16(c1, c2, 0, 0) == -2 &&
+ (c3 = (*i_getc)(f)) != EOF &&
+ (c4 = (*i_getc)(f)) != EOF) {
+ nkf_iconv_utf_16(c1, c2, c3, c4);
+ }
+ }
+ (*i_ungetc)(EOF, f);
+ }
+#endif
+
while ((c1 = (*i_getc)(f)) != EOF) {
#ifdef INPUT_CODE_FIX
if (!input_encoding)
#endif
code_status(c1);
- if (c2) {
- /* second byte */
- if (c2 > ((input_encoding && nkf_enc_cp5022x_p(input_encoding)) ? 0x92 : DEL)) {
- /* in case of 8th bit is on */
- if (!estab_f&&!mime_decode_mode) {
- /* in case of not established yet */
- /* It is still ambiguious */
- if (h_conv(f, c2, c1)==EOF)
- LAST;
- else
- c2 = 0;
- NEXT;
- } else {
+ if (c2) {
+ /* second byte */
+ if (c2 > DEL) {
+ /* in case of 8th bit is on */
+ if (!estab_f&&!mime_decode_mode) {
+ /* in case of not established yet */
+ /* It is still ambiguious */
+ if (h_conv(f, c2, c1)==EOF) {
+ LAST;
+ }
+ else {
+ SKIP;
+ }
+ }
+ else {
/* in case of already established */
- if (c1 < AT) {
- /* ignore bogus code and not CP5022x UCD */
- c2 = 0;
- NEXT;
+ if (c1 < 0x40) {
+ /* ignore bogus code */
+ SKIP;
} else {
SEND;
}
}
- } else
- /* second byte, 7 bit code */
- /* it might be kanji shitfted */
- if ((c1 == DEL) || (c1 <= SP)) {
- /* ignore bogus first code */
- c2 = 0;
- NEXT;
- } else
- SEND;
- } else {
- /* first byte */
-#ifdef UTF8_INPUT_ENABLE
- if (iconv == w_iconv16) {
- if (input_endian == ENDIAN_BIG) {
- c2 = c1;
- if ((c1 = (*i_getc)(f)) != EOF) {
- if (0xD8 <= c2 && c2 <= 0xDB) {
- if ((c0 = (*i_getc)(f)) != EOF) {
- c0 <<= 8;
- if ((c3 = (*i_getc)(f)) != EOF) {
- c0 |= c3;
- } else c2 = EOF;
- } else c2 = EOF;
- }
- } else c2 = EOF;
- } else {
- if ((c2 = (*i_getc)(f)) != EOF) {
- if (0xD8 <= c2 && c2 <= 0xDB) {
- if ((c3 = (*i_getc)(f)) != EOF) {
- if ((c0 = (*i_getc)(f)) != EOF) {
- c0 <<= 8;
- c0 |= c3;
- } else c2 = EOF;
- } else c2 = EOF;
- }
- } else c2 = EOF;
- }
+ }
+ else {
+ /* 2nd byte of 7 bit code or SJIS */
SEND;
- } else if(iconv == w_iconv32){
- int c3 = c1;
- if((c2 = (*i_getc)(f)) != EOF &&
- (c1 = (*i_getc)(f)) != EOF &&
- (c0 = (*i_getc)(f)) != EOF){
- switch(input_endian){
- case ENDIAN_BIG:
- c1 = (c2&0xFF)<<16 | (c1&0xFF)<<8 | (c0&0xFF);
- break;
- case ENDIAN_LITTLE:
- c1 = (c3&0xFF) | (c2&0xFF)<<8 | (c1&0xFF)<<16;
- break;
- case ENDIAN_2143:
- c1 = (c3&0xFF)<<16 | (c1&0xFF) | (c0&0xFF)<<8;
- break;
- case ENDIAN_3412:
- c1 = (c3&0xFF)<<8 | (c2&0xFF) | (c0&0xFF)<<16;
- break;
+ }
+ }
+ else {
+ /* first byte */
+ if (input_mode == JIS_X_0208 && DEL <= c1 && c1 < 0x92) {
+ /* CP5022x */
+ MORE;
+ } else if (c1 > DEL) {
+ /* 8 bit code */
+ if (!estab_f && !iso8859_f) {
+ /* not established yet */
+ MORE;
+ } else { /* estab_f==TRUE */
+ if (iso8859_f) {
+ c2 = ISO_8859_1;
+ c1 &= 0x7f;
+ SEND;
}
- c2 = 0;
- }else{
- c2 = EOF;
- }
- SEND;
- } else
-#endif
-#ifdef NUMCHAR_OPTION
- if (is_unicode_capsule(c1)){
- SEND;
- } else
-#endif
- if (c1 > ((input_encoding && nkf_enc_cp5022x_p(input_encoding)) ? 0x92 : DEL)) {
- /* 8 bit code */
- if (!estab_f && !iso8859_f) {
- /* not established yet */
- c2 = c1;
- NEXT;
- } else { /* estab_f==TRUE */
- if (iso8859_f) {
- c2 = ISO_8859_1;
- c1 &= 0x7f;
- SEND;
- } else if (SSP<=c1 && c1<0xe0 && iconv == s_iconv) {
- /* SJIS X0201 Case... */
- if (iso2022jp_f && !x0201_f) {
- (*oconv)(GETA1, GETA2);
- NEXT;
- } else {
- c2 = JIS_X_0201;
- c1 &= 0x7f;
- SEND;
- }
- } else if (c1==SSO && iconv != s_iconv) {
- /* EUC X0201 Case */
- c1 = (*i_getc)(f); /* skip SSO */
- code_status(c1);
- if (SSP<=c1 && c1<0xe0) {
- if (iso2022jp_f && !x0201_f) {
- (*oconv)(GETA1, GETA2);
- NEXT;
- } else {
- c2 = JIS_X_0201;
- c1 &= 0x7f;
- SEND;
- }
- } else { /* bogus code, skip SSO and one byte */
- NEXT;
- }
- } else if (ms_ucs_map_f == UCS_MAP_CP10001 &&
- (c1 == 0xFD || c1 == 0xFE)) {
- /* CP10001 */
- c2 = JIS_X_0201;
+ else if ((iconv == s_iconv && 0xA0 <= c1 && c1 <= 0xDF) ||
+ (ms_ucs_map_f == UCS_MAP_CP10001 && (c1 == 0xFD || c1 == 0xFE))) {
+ /* JIS X 0201 */
+ c2 = JIS_X_0201_1976_K;
c1 &= 0x7f;
SEND;
- } else {
- /* already established */
- c2 = c1;
- NEXT;
- }
- }
- } else if ((c1 > SP) && (c1 != DEL)) {
- /* in case of Roman characters */
- if (shift_mode) {
- /* output 1 shifted byte */
- if (iso8859_f) {
- c2 = ISO_8859_1;
- SEND;
- } else if (SP <= c1 && c1 < (0xe0&0x7f)){
- /* output 1 shifted byte */
- if (iso2022jp_f && !x0201_f) {
- (*oconv)(GETA1, GETA2);
- NEXT;
- } else {
- c2 = JIS_X_0201;
- SEND;
- }
- } else {
- /* look like bogus code */
- NEXT;
- }
- } else if (input_mode == JIS_X_0208 || input_mode == JIS_X_0212 ||
+ }
+ else {
+ /* already established */
+ MORE;
+ }
+ }
+ } else if (SP < c1 && c1 < DEL) {
+ /* in case of Roman characters */
+ if (shift_mode) {
+ /* output 1 shifted byte */
+ if (iso8859_f) {
+ c2 = ISO_8859_1;
+ SEND;
+ } else if (nkf_byte_jisx0201_katakana_p(c1)){
+ /* output 1 shifted byte */
+ c2 = JIS_X_0201_1976_K;
+ SEND;
+ } else {
+ /* look like bogus code */
+ SKIP;
+ }
+ } else if (input_mode == JIS_X_0208 || input_mode == JIS_X_0212 ||
input_mode == JIS_X_0213_1 || input_mode == JIS_X_0213_2) {
- /* in case of Kanji shifted */
- c2 = c1;
- NEXT;
- } else if (c1 == '=' && mime_f && !mime_decode_mode) {
- /* Check MIME code */
- if ((c1 = (*i_getc)(f)) == EOF) {
- (*oconv)(0, '=');
- LAST;
- } else if (c1 == '?') {
- /* =? is mime conversion start sequence */
+ /* in case of Kanji shifted */
+ MORE;
+ } else if (c1 == '=' && mime_f && !mime_decode_mode) {
+ /* Check MIME code */
+ if ((c1 = (*i_getc)(f)) == EOF) {
+ (*oconv)(0, '=');
+ LAST;
+ } else if (c1 == '?') {
+ /* =? is mime conversion start sequence */
if(mime_f == STRICT_MIME) {
/* check in real detail */
if (mime_begin_strict(f) == EOF)
LAST;
- else
- NEXT;
+ SKIP;
} else if (mime_begin(f) == EOF)
- LAST;
- else
- NEXT;
- } else {
- (*oconv)(0, '=');
- (*i_ungetc)(c1,f);
- NEXT;
- }
- } else {
- /* normal ASCII code */
- SEND;
- }
- } else if (c1 == SI && (!is_8bit || mime_decode_mode)) {
- shift_mode = FALSE;
- NEXT;
- } else if (c1 == SO && (!is_8bit || mime_decode_mode)) {
- shift_mode = TRUE;
- NEXT;
- } else if (c1 == ESC && (!is_8bit || mime_decode_mode)) {
- if ((c1 = (*i_getc)(f)) == EOF) {
- /* (*oconv)(0, ESC); don't send bogus code */
- LAST;
- } else if (c1 == '$') {
- if ((c1 = (*i_getc)(f)) == EOF) {
- /*
- (*oconv)(0, ESC); don't send bogus code
- (*oconv)(0, '$'); */
- LAST;
- } else if (c1 == '@'|| c1 == 'B') {
- /* This is kanji introduction */
- input_mode = JIS_X_0208;
- shift_mode = FALSE;
- set_input_codename("ISO-2022-JP");
-#ifdef CHECK_OPTION
- debug("ISO-2022-JP");
-#endif
- NEXT;
- } else if (c1 == '(') {
- if ((c1 = (*i_getc)(f)) == EOF) {
- /* don't send bogus code
- (*oconv)(0, ESC);
- (*oconv)(0, '$');
- (*oconv)(0, '(');
- */
- LAST;
- } else if (c1 == '@'|| c1 == 'B') {
- /* This is kanji introduction */
- input_mode = JIS_X_0208;
- shift_mode = FALSE;
- NEXT;
+ LAST;
+ SKIP;
+ } else {
+ (*oconv)(0, '=');
+ (*i_ungetc)(c1,f);
+ SKIP;
+ }
+ } else {
+ /* normal ASCII code */
+ SEND;
+ }
+ } else if (c1 == SI && (!is_8bit || mime_decode_mode)) {
+ shift_mode = 0;
+ SKIP;
+ } else if (c1 == SO && (!is_8bit || mime_decode_mode)) {
+ shift_mode = 1;
+ SKIP;
+ } else if (c1 == ESC && (!is_8bit || mime_decode_mode)) {
+ if ((c1 = (*i_getc)(f)) == EOF) {
+ /* (*oconv)(0, ESC); don't send bogus code */
+ LAST;
+ }
+ else if (c1 == '&') {
+ /* IRR */
+ if ((c1 = (*i_getc)(f)) == EOF) {
+ LAST;
+ } else {
+ SKIP;
+ }
+ }
+ else if (c1 == '$') {
+ /* GZDMx */
+ if ((c1 = (*i_getc)(f)) == EOF) {
+ /* don't send bogus code
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$'); */
+ LAST;
+ } else if (c1 == '@' || c1 == 'B') {
+ /* JIS X 0208 */
+ set_input_mode(JIS_X_0208);
+ SKIP;
+ } else if (c1 == '(') {
+ /* GZDM4 */
+ if ((c1 = (*i_getc)(f)) == EOF) {
+ /* don't send bogus code
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$');
+ (*oconv)(0, '(');
+ */
+ LAST;
+ } else if (c1 == '@'|| c1 == 'B') {
+ /* JIS X 0208 */
+ set_input_mode(JIS_X_0208);
+ SKIP;
#ifdef X0212_ENABLE
- } else if (c1 == 'D'){
- input_mode = JIS_X_0212;
- shift_mode = FALSE;
- NEXT;
+ } else if (c1 == 'D'){
+ set_input_mode(JIS_X_0212);
+ SKIP;
#endif /* X0212_ENABLE */
- } else if (c1 == 0x4F){
- input_mode = JIS_X_0213_1;
- shift_mode = FALSE;
- NEXT;
- } else if (c1 == 0x50){
- input_mode = JIS_X_0213_2;
- shift_mode = FALSE;
- NEXT;
- } else {
- /* could be some special code */
- (*oconv)(0, ESC);
- (*oconv)(0, '$');
- (*oconv)(0, '(');
- (*oconv)(0, c1);
- NEXT;
- }
- } else if (broken_f&0x2) {
- /* accept any ESC-(-x as broken code ... */
- input_mode = JIS_X_0208;
- shift_mode = FALSE;
- NEXT;
- } else {
- (*oconv)(0, ESC);
- (*oconv)(0, '$');
- (*oconv)(0, c1);
- NEXT;
- }
- } else if (c1 == '(') {
- if ((c1 = (*i_getc)(f)) == EOF) {
- /* don't send bogus code
- (*oconv)(0, ESC);
- (*oconv)(0, '('); */
- LAST;
- } else {
- if (c1 == 'I') {
- /* This is X0201 kana introduction */
- input_mode = JIS_X_0201; shift_mode = JIS_X_0201;
- NEXT;
- } else if (c1 == 'B' || c1 == 'J' || c1 == 'H') {
- /* This is X0208 kanji introduction */
- input_mode = ASCII; shift_mode = FALSE;
- NEXT;
- } else if (broken_f&0x2) {
- input_mode = ASCII; shift_mode = FALSE;
- NEXT;
- } else {
- (*oconv)(0, ESC);
- (*oconv)(0, '(');
- /* maintain various input_mode here */
- SEND;
- }
- }
- } else if ( c1 == 'N' || c1 == 'n'){
- /* SS2 */
- c3 = (*i_getc)(f); /* skip SS2 */
- if ( (SP<=c3 && c3 < 0x60) || (0xa0<=c3 && c3 < 0xe0)){
- c1 = c3;
- c2 = JIS_X_0201;
- SEND;
- }else{
- (*i_ungetc)(c3, f);
- /* lonely ESC */
- (*oconv)(0, ESC);
- SEND;
- }
- } else {
- /* lonely ESC */
- (*oconv)(0, ESC);
- SEND;
- }
+ } else if (c1 == 'O' || c1 == 'Q'){
+ set_input_mode(JIS_X_0213_1);
+ SKIP;
+ } else if (c1 == 'P'){
+ set_input_mode(JIS_X_0213_2);
+ SKIP;
+ } else {
+ /* could be some special code */
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$');
+ (*oconv)(0, '(');
+ (*oconv)(0, c1);
+ SKIP;
+ }
+ } else if (broken_f&0x2) {
+ /* accept any ESC-(-x as broken code ... */
+ input_mode = JIS_X_0208;
+ shift_mode = 0;
+ SKIP;
+ } else {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$');
+ (*oconv)(0, c1);
+ SKIP;
+ }
+ } else if (c1 == '(') {
+ /* GZD4 */
+ if ((c1 = (*i_getc)(f)) == EOF) {
+ /* don't send bogus code
+ (*oconv)(0, ESC);
+ (*oconv)(0, '('); */
+ LAST;
+ }
+ else if (c1 == 'I') {
+ /* JIS X 0201 Katakana */
+ set_input_mode(JIS_X_0201_1976_K);
+ SKIP;
+ }
+ else if (c1 == 'B' || c1 == 'J' || c1 == 'H') {
+ /* ISO-646IRV:1983 or JIS X 0201 Roman or JUNET */
+ set_input_mode(ASCII);
+ SKIP;
+ }
+ else if (broken_f&0x2) {
+ set_input_mode(ASCII);
+ SKIP;
+ }
+ else {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '(');
+ SEND;
+ }
+ }
+ else if (c1 == '.') {
+ /* G2D6 */
+ if ((c1 = (*i_getc)(f)) == EOF) {
+ LAST;
+ }
+ else if (c1 == 'A') {
+ /* ISO-8859-1 */
+ g2 = ISO_8859_1;
+ SKIP;
+ }
+ else {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '.');
+ SEND;
+ }
+ }
+ else if (c1 == 'N') {
+ /* SS2 */
+ c1 = (*i_getc)(f);
+ if (g2 == ISO_8859_1) {
+ c2 = ISO_8859_1;
+ SEND;
+ }else{
+ (*i_ungetc)(c1, f);
+ /* lonely ESC */
+ (*oconv)(0, ESC);
+ SEND;
+ }
+ }
+ else {
+ /* lonely ESC */
+ (*oconv)(0, ESC);
+ SEND;
+ }
} else if (c1 == ESC && iconv == s_iconv) {
/* ESC in Shift_JIS */
if ((c1 = (*i_getc)(f)) == EOF) {
@@ -5403,32 +5540,33 @@
} else if (c1 == '$') {
/* J-PHONE emoji */
if ((c1 = (*i_getc)(f)) == EOF) {
+ LAST;
+ } else if (('E' <= c1 && c1 <= 'G') ||
+ ('O' <= c1 && c1 <= 'Q')) {
/*
- (*oconv)(0, ESC); don't send bogus code
- (*oconv)(0, '$'); */
- LAST;
- } else {
- if (('E' <= c1 && c1 <= 'G') ||
- ('O' <= c1 && c1 <= 'Q')) {
- /*
- NUM : 0 1 2 3 4 5
- BYTE: G E F O P Q
- C%7 : 1 6 0 2 3 4
- C%7 : 0 1 2 3 4 5 6
- NUM : 2 0 3 4 5 X 1
- */
- static const char jphone_emoji_first_table[7] = {2, 0, 3, 4, 5, 0, 1};
- c0 = (jphone_emoji_first_table[c1 % 7] << 8) - SP + 0xE000 + CLASS_UNICODE;
- while ((c1 = (*i_getc)(f)) != EOF) {
- if (SP <= c1 && c1 <= 'z') {
- (*oconv)(0, c1 + c0);
- } else break; /* c1 == SO */
- }
+ NUM : 0 1 2 3 4 5
+ BYTE: G E F O P Q
+ C%7 : 1 6 0 2 3 4
+ C%7 : 0 1 2 3 4 5 6
+ NUM : 2 0 3 4 5 X 1
+ */
+ static const int jphone_emoji_first_table[7] =
+ {0xE1E0, 0xDFE0, 0xE2E0, 0xE3E0, 0xE4E0, 0xDFE0, 0xE0E0};
+ c3 = nkf_char_unicode_new(jphone_emoji_first_table[c1 % 7]);
+ if ((c1 = (*i_getc)(f)) == EOF) LAST;
+ while (SP <= c1 && c1 <= 'z') {
+ (*oconv)(0, c1 + c3);
+ if ((c1 = (*i_getc)(f)) == EOF) LAST;
}
+ SKIP;
}
- if (c1 == EOF) LAST;
- NEXT;
- } else {
+ else {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$');
+ SEND;
+ }
+ }
+ else {
/* lonely ESC */
(*oconv)(0, ESC);
SEND;
@@ -5466,33 +5604,29 @@
SEND;
}
}
- } else if (c1 == DEL && input_mode == JIS_X_0208) {
- /* CP5022x */
- c2 = c1;
- NEXT;
} else
- SEND;
- }
- /* send: */
+ SEND;
+ }
+ /* send: */
switch(input_mode){
case ASCII:
- switch ((*iconv)(c2, c1, c0)) { /* can be EUC / SJIS / UTF-8 / UTF-16 */
+ switch ((*iconv)(c2, c1, 0)) { /* can be EUC / SJIS / UTF-8 */
case -2:
/* 4 bytes UTF-8 */
- if ((c0 = (*i_getc)(f)) != EOF) {
- code_status(c0);
- c0 <<= 8;
- if ((c3 = (*i_getc)(f)) != EOF) {
- code_status(c3);
- (*iconv)(c2, c1, c0|c3);
+ if ((c3 = (*i_getc)(f)) != EOF) {
+ code_status(c3);
+ c3 <<= 8;
+ if ((c4 = (*i_getc)(f)) != EOF) {
+ code_status(c4);
+ (*iconv)(c2, c1, c3|c4);
}
}
break;
case -1:
/* 3 bytes EUC or UTF-8 */
- if ((c0 = (*i_getc)(f)) != EOF) {
- code_status(c0);
- (*iconv)(c2, c1, c0);
+ if ((c3 = (*i_getc)(f)) != EOF) {
+ code_status(c3);
+ (*iconv)(c2, c1, c3);
}
break;
}
@@ -5503,8 +5637,7 @@
0x7F <= c2 && c2 <= 0x92 &&
0x21 <= c1 && c1 <= 0x7E) {
/* CP932 UDC */
- if(c1 == 0x7F) return 0;
- c1 = (c2 - 0x7F) * 94 + c1 - 0x21 + 0xE000 + CLASS_UNICODE;
+ c1 = nkf_char_unicode_new((c2 - 0x7F) * 94 + c1 - 0x21 + 0xE000);
c2 = 0;
}
(*oconv)(c2, c1); /* this is JIS, not SJIS/EUC case */
@@ -5521,10 +5654,10 @@
(*oconv)(input_mode, c1); /* other special case */
}
- c2 = 0;
- c0 = 0;
- continue;
- /* goto next_word */
+ c2 = 0;
+ c3 = 0;
+ continue;
+ /* goto next_word */
}
/* epilogue */
@@ -5544,19 +5677,26 @@
#endif
}
}
- return 1;
+ return 0;
}
-void options(unsigned char *cp)
+/*
+ * int options(unsigned char *cp)
+ *
+ * return values:
+ * 0: success
+ * -1: ArgumentError
+ */
+static int
+options(unsigned char *cp)
{
nkf_char i, j;
unsigned char *p;
unsigned char *cp_back = NULL;
- char codeset[32];
nkf_encoding *enc;
if (option_mode==1)
- return;
+ return 0;
while(*cp && *cp++!='-');
while (*cp || cp_back) {
if(!*cp){
@@ -5565,188 +5705,188 @@
continue;
}
p = 0;
- switch (*cp++) {
- case '-': /* literal options */
+ switch (*cp++) {
+ case '-': /* literal options */
if (!*cp || *cp == SP) { /* ignore the rest of arguments */
option_mode = 1;
- return;
+ return 0;
}
- for (i=0;i<sizeof(long_option)/sizeof(long_option[0]);i++) {
- p = (unsigned char *)long_option[i].name;
- for (j=0;*p && *p != '=' && *p == cp[j];p++, j++);
+ for (i=0;i<sizeof(long_option)/sizeof(long_option[0]);i++) {
+ p = (unsigned char *)long_option[i].name;
+ for (j=0;*p && *p != '=' && *p == cp[j];p++, j++);
if (*p == cp[j] || cp[j] == SP){
p = &cp[j] + 1;
break;
}
p = 0;
- }
+ }
if (p == 0) {
+#if !defined(PERL_XS) && !defined(WIN32DLL)
fprintf(stderr, "unknown long option: --%s\n", cp);
- return;
+#endif
+ return -1;
}
while(*cp && *cp != SP && cp++);
- if (long_option[i].alias[0]){
+ if (long_option[i].alias[0]){
cp_back = cp;
cp = (unsigned char *)long_option[i].alias;
}else{
- if (strcmp(long_option[i].name, "ic=") == 0){
- nkf_str_upcase((char *)p, codeset, 32);
- enc = nkf_enc_find(codeset);
+ if (strcmp(long_option[i].name, "ic=") == 0){
+ enc = nkf_enc_find((char *)p);
if (!enc) continue;
input_encoding = enc;
- continue;
+ continue;
}
- if (strcmp(long_option[i].name, "oc=") == 0){
- nkf_str_upcase((char *)p, codeset, 32);
- enc = nkf_enc_find(codeset);
- if (enc == 0) continue;
+ if (strcmp(long_option[i].name, "oc=") == 0){
+ enc = nkf_enc_find((char *)p);
+ if (enc <= 0) continue;
output_encoding = enc;
- continue;
+ continue;
}
- if (strcmp(long_option[i].name, "guess=") == 0){
+ if (strcmp(long_option[i].name, "guess=") == 0){
if (p[0] == '0' || p[0] == '1') {
guess_f = 1;
} else {
guess_f = 2;
}
- continue;
- }
+ continue;
+ }
#ifdef OVERWRITE
- if (strcmp(long_option[i].name, "overwrite") == 0){
- file_out_f = TRUE;
- overwrite_f = TRUE;
+ if (strcmp(long_option[i].name, "overwrite") == 0){
+ file_out_f = TRUE;
+ overwrite_f = TRUE;
preserve_time_f = TRUE;
- continue;
- }
- if (strcmp(long_option[i].name, "overwrite=") == 0){
- file_out_f = TRUE;
- overwrite_f = TRUE;
+ continue;
+ }
+ if (strcmp(long_option[i].name, "overwrite=") == 0){
+ file_out_f = TRUE;
+ overwrite_f = TRUE;
preserve_time_f = TRUE;
backup_f = TRUE;
backup_suffix = malloc(strlen((char *) p) + 1);
strcpy(backup_suffix, (char *) p);
- continue;
- }
- if (strcmp(long_option[i].name, "in-place") == 0){
- file_out_f = TRUE;
- overwrite_f = TRUE;
+ continue;
+ }
+ if (strcmp(long_option[i].name, "in-place") == 0){
+ file_out_f = TRUE;
+ overwrite_f = TRUE;
preserve_time_f = FALSE;
continue;
- }
- if (strcmp(long_option[i].name, "in-place=") == 0){
- file_out_f = TRUE;
- overwrite_f = TRUE;
+ }
+ if (strcmp(long_option[i].name, "in-place=") == 0){
+ file_out_f = TRUE;
+ overwrite_f = TRUE;
preserve_time_f = FALSE;
backup_f = TRUE;
backup_suffix = malloc(strlen((char *) p) + 1);
strcpy(backup_suffix, (char *) p);
continue;
- }
+ }
#endif
#ifdef INPUT_OPTION
- if (strcmp(long_option[i].name, "cap-input") == 0){
- cap_f = TRUE;
- continue;
- }
- if (strcmp(long_option[i].name, "url-input") == 0){
- url_f = TRUE;
- continue;
- }
+ if (strcmp(long_option[i].name, "cap-input") == 0){
+ cap_f = TRUE;
+ continue;
+ }
+ if (strcmp(long_option[i].name, "url-input") == 0){
+ url_f = TRUE;
+ continue;
+ }
#endif
#ifdef NUMCHAR_OPTION
- if (strcmp(long_option[i].name, "numchar-input") == 0){
- numchar_f = TRUE;
- continue;
- }
+ if (strcmp(long_option[i].name, "numchar-input") == 0){
+ numchar_f = TRUE;
+ continue;
+ }
#endif
#ifdef CHECK_OPTION
- if (strcmp(long_option[i].name, "no-output") == 0){
- noout_f = TRUE;
- continue;
- }
- if (strcmp(long_option[i].name, "debug") == 0){
- debug_f = TRUE;
- continue;
- }
+ if (strcmp(long_option[i].name, "no-output") == 0){
+ noout_f = TRUE;
+ continue;
+ }
+ if (strcmp(long_option[i].name, "debug") == 0){
+ debug_f = TRUE;
+ continue;
+ }
#endif
- if (strcmp(long_option[i].name, "cp932") == 0){
+ if (strcmp(long_option[i].name, "cp932") == 0){
#ifdef SHIFTJIS_CP932
- cp51932_f = TRUE;
- cp932inv_f = -TRUE;
+ cp51932_f = TRUE;
+ cp932inv_f = -TRUE;
#endif
#ifdef UTF8_OUTPUT_ENABLE
- ms_ucs_map_f = UCS_MAP_CP932;
+ ms_ucs_map_f = UCS_MAP_CP932;
#endif
- continue;
- }
- if (strcmp(long_option[i].name, "no-cp932") == 0){
+ continue;
+ }
+ if (strcmp(long_option[i].name, "no-cp932") == 0){
#ifdef SHIFTJIS_CP932
- cp51932_f = FALSE;
- cp932inv_f = FALSE;
+ cp51932_f = FALSE;
+ cp932inv_f = FALSE;
#endif
#ifdef UTF8_OUTPUT_ENABLE
- ms_ucs_map_f = UCS_MAP_ASCII;
+ ms_ucs_map_f = UCS_MAP_ASCII;
#endif
- continue;
- }
+ continue;
+ }
#ifdef SHIFTJIS_CP932
- if (strcmp(long_option[i].name, "cp932inv") == 0){
- cp932inv_f = -TRUE;
- continue;
- }
+ if (strcmp(long_option[i].name, "cp932inv") == 0){
+ cp932inv_f = -TRUE;
+ continue;
+ }
#endif
#ifdef X0212_ENABLE
- if (strcmp(long_option[i].name, "x0212") == 0){
- x0212_f = TRUE;
- continue;
- }
+ if (strcmp(long_option[i].name, "x0212") == 0){
+ x0212_f = TRUE;
+ continue;
+ }
#endif
#ifdef EXEC_IO
- if (strcmp(long_option[i].name, "exec-in") == 0){
- exec_f = 1;
- return;
- }
- if (strcmp(long_option[i].name, "exec-out") == 0){
- exec_f = -1;
- return;
- }
+ if (strcmp(long_option[i].name, "exec-in") == 0){
+ exec_f = 1;
+ return 0;
+ }
+ if (strcmp(long_option[i].name, "exec-out") == 0){
+ exec_f = -1;
+ return 0;
+ }
#endif
#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE)
- if (strcmp(long_option[i].name, "no-cp932ext") == 0){
+ if (strcmp(long_option[i].name, "no-cp932ext") == 0){
no_cp932ext_f = TRUE;
- continue;
- }
+ continue;
+ }
if (strcmp(long_option[i].name, "no-best-fit-chars") == 0){
no_best_fit_chars_f = TRUE;
continue;
}
- if (strcmp(long_option[i].name, "fb-skip") == 0){
+ if (strcmp(long_option[i].name, "fb-skip") == 0){
encode_fallback = NULL;
- continue;
- }
- if (strcmp(long_option[i].name, "fb-html") == 0){
+ continue;
+ }
+ if (strcmp(long_option[i].name, "fb-html") == 0){
encode_fallback = encode_fallback_html;
- continue;
- }
- if (strcmp(long_option[i].name, "fb-xml") == 0){
+ continue;
+ }
+ if (strcmp(long_option[i].name, "fb-xml") == 0){
encode_fallback = encode_fallback_xml;
- continue;
- }
- if (strcmp(long_option[i].name, "fb-java") == 0){
+ continue;
+ }
+ if (strcmp(long_option[i].name, "fb-java") == 0){
encode_fallback = encode_fallback_java;
- continue;
- }
- if (strcmp(long_option[i].name, "fb-perl") == 0){
+ continue;
+ }
+ if (strcmp(long_option[i].name, "fb-perl") == 0){
encode_fallback = encode_fallback_perl;
- continue;
- }
- if (strcmp(long_option[i].name, "fb-subchar") == 0){
+ continue;
+ }
+ if (strcmp(long_option[i].name, "fb-subchar") == 0){
encode_fallback = encode_fallback_subchar;
- continue;
- }
- if (strcmp(long_option[i].name, "fb-subchar=") == 0){
+ continue;
+ }
+ if (strcmp(long_option[i].name, "fb-subchar=") == 0){
encode_fallback = encode_fallback_subchar;
unicode_subchar = 0;
if (p[0] != '0'){
@@ -5770,14 +5910,14 @@
}
w16e_conv(unicode_subchar, &i, &j);
unicode_subchar = i<<8 | j;
- continue;
- }
+ continue;
+ }
#endif
#ifdef UTF8_OUTPUT_ENABLE
- if (strcmp(long_option[i].name, "ms-ucs-map") == 0){
- ms_ucs_map_f = UCS_MAP_MS;
- continue;
- }
+ if (strcmp(long_option[i].name, "ms-ucs-map") == 0){
+ ms_ucs_map_f = UCS_MAP_MS;
+ continue;
+ }
#endif
#ifdef UNICODE_NORMALIZATION
if (strcmp(long_option[i].name, "utf8mac-input") == 0){
@@ -5785,24 +5925,28 @@
continue;
}
#endif
- if (strcmp(long_option[i].name, "prefix=") == 0){
- if (nkf_isgraph(p[0])){
- for (i = 1; nkf_isgraph(p[i]); i++){
- prefix_table[p[i]] = p[0];
- }
- }
- continue;
- }
- }
- continue;
- case 'b': /* buffered mode */
- unbuf_f = FALSE;
- continue;
- case 'u': /* non bufferd mode */
- unbuf_f = TRUE;
- continue;
- case 't': /* transparent mode */
- if (*cp=='1') {
+ if (strcmp(long_option[i].name, "prefix=") == 0){
+ if (nkf_isgraph(p[0])){
+ for (i = 1; nkf_isgraph(p[i]); i++){
+ prefix_table[p[i]] = p[0];
+ }
+ }
+ continue;
+ }
+#if !defined(PERL_XS) && !defined(WIN32DLL)
+ fprintf(stderr, "unsupported long option: --%s\n", long_option[i].name);
+#endif
+ return -1;
+ }
+ continue;
+ case 'b': /* buffered mode */
+ unbuf_f = FALSE;
+ continue;
+ case 'u': /* non bufferd mode */
+ unbuf_f = TRUE;
+ continue;
+ case 't': /* transparent mode */
+ if (*cp=='1') {
/* alias of -t */
cp++;
nop_f = TRUE;
@@ -5815,62 +5959,62 @@
*/
cp++;
nop_f = 2;
- } else
+ } else
nop_f = TRUE;
- continue;
- case 'j': /* JIS output */
- case 'n':
- output_encoding = nkf_enc_from_index(ISO_2022_JP);
- continue;
- case 'e': /* AT&T EUC output */
- output_encoding = nkf_enc_from_index(EUC_JP);
- continue;
- case 's': /* SJIS output */
- output_encoding = nkf_enc_from_index(WINDOWS_31J);
- continue;
- case 'l': /* ISO8859 Latin-1 support, no conversion */
- iso8859_f = TRUE; /* Only compatible with ISO-2022-JP */
- input_encoding = nkf_enc_from_index(ISO_8859_1);
- continue;
- case 'i': /* Kanji IN ESC-$-@/B */
- if (*cp=='@'||*cp=='B')
- kanji_intro = *cp++;
- continue;
- case 'o': /* ASCII IN ESC-(-J/B */
- if (*cp=='J'||*cp=='B'||*cp=='H')
- ascii_intro = *cp++;
- continue;
- case 'h':
- /*
- bit:1 katakana->hiragana
- bit:2 hiragana->katakana
- */
- if ('9'>= *cp && *cp>='0')
- hira_f |= (*cp++ -'0');
- else
- hira_f |= 1;
- continue;
- case 'r':
- rot_f = TRUE;
- continue;
+ continue;
+ case 'j': /* JIS output */
+ case 'n':
+ output_encoding = nkf_enc_from_index(ISO_2022_JP);
+ continue;
+ case 'e': /* AT&T EUC output */
+ output_encoding = nkf_enc_from_index(EUCJP_NKF);
+ continue;
+ case 's': /* SJIS output */
+ output_encoding = nkf_enc_from_index(WINDOWS_31J);
+ continue;
+ case 'l': /* ISO8859 Latin-1 support, no conversion */
+ iso8859_f = TRUE; /* Only compatible with ISO-2022-JP */
+ input_encoding = nkf_enc_from_index(ISO_8859_1);
+ continue;
+ case 'i': /* Kanji IN ESC-$-@/B */
+ if (*cp=='@'||*cp=='B')
+ kanji_intro = *cp++;
+ continue;
+ case 'o': /* ASCII IN ESC-(-J/B */
+ if (*cp=='J'||*cp=='B'||*cp=='H')
+ ascii_intro = *cp++;
+ continue;
+ case 'h':
+ /*
+ bit:1 katakana->hiragana
+ bit:2 hiragana->katakana
+ */
+ if ('9'>= *cp && *cp>='0')
+ hira_f |= (*cp++ -'0');
+ else
+ hira_f |= 1;
+ continue;
+ case 'r':
+ rot_f = TRUE;
+ continue;
#if defined(MSDOS) || defined(__OS2__)
- case 'T':
- binmode_f = FALSE;
- continue;
+ case 'T':
+ binmode_f = FALSE;
+ continue;
#endif
#ifndef PERL_XS
- case 'V':
- show_configuration();
- exit(1);
- break;
- case 'v':
- usage();
- exit(1);
- break;
+ case 'V':
+ show_configuration();
+ exit(1);
+ break;
+ case 'v':
+ usage();
+ exit(1);
+ break;
#endif
#ifdef UTF8_OUTPUT_ENABLE
- case 'w': /* UTF-8 output */
- if (cp[0] == '8') {
+ case 'w': /* UTF-8 output */
+ if (cp[0] == '8') {
cp++;
if (cp[0] == '0'){
cp++;
@@ -5896,10 +6040,10 @@
output_endian = ENDIAN_LITTLE;
} else if (cp[0] == 'B') {
cp++;
- } else {
+ } else {
output_encoding = nkf_enc_from_index(enc_idx);
continue;
- }
+ }
if (cp[0] == '0'){
cp++;
enc_idx = enc_idx == UTF_16
@@ -5913,10 +6057,10 @@
}
output_encoding = nkf_enc_from_index(enc_idx);
}
- continue;
+ continue;
#endif
#ifdef UTF8_INPUT_ENABLE
- case 'W': /* UTF input */
+ case 'W': /* UTF input */
if (cp[0] == '8') {
cp++;
input_encoding = nkf_enc_from_index(UTF_8);
@@ -5946,58 +6090,58 @@
: (output_endian == ENDIAN_LITTLE ? UTF_32LE : UTF_32BE);
input_encoding = nkf_enc_from_index(enc_idx);
}
- continue;
+ continue;
#endif
- /* Input code assumption */
+ /* Input code assumption */
case 'J': /* ISO-2022-JP input */
input_encoding = nkf_enc_from_index(ISO_2022_JP);
continue;
case 'E': /* EUC-JP input */
- input_encoding = nkf_enc_from_index(EUC_JP);
+ input_encoding = nkf_enc_from_index(EUCJP_NKF);
continue;
case 'S': /* Windows-31J input */
input_encoding = nkf_enc_from_index(WINDOWS_31J);
continue;
- case 'Z': /* Convert X0208 alphabet to asii */
- /* alpha_f
+ case 'Z': /* Convert X0208 alphabet to asii */
+ /* alpha_f
bit:0 Convert JIS X 0208 Alphabet to ASCII
bit:1 Convert Kankaku to one space
bit:2 Convert Kankaku to two spaces
bit:3 Convert HTML Entity
bit:4 Convert JIS X 0208 Katakana to JIS X 0201 Katakana
- */
+ */
while ('0'<= *cp && *cp <='9') {
alpha_f |= 1 << (*cp++ - '0');
}
- if (!alpha_f) alpha_f = 1;
- continue;
- case 'x': /* Convert X0201 kana to X0208 or X0201 Conversion */
- x0201_f = FALSE; /* No X0201->X0208 conversion */
- /* accept X0201
- ESC-(-I in JIS, EUC, MS Kanji
- SI/SO in JIS, EUC, MS Kanji
- SSO in EUC, JIS, not in MS Kanji
- MS Kanji (0xa0-0xdf)
- output X0201
- ESC-(-I in JIS (0x20-0x5f)
- SSO in EUC (0xa0-0xdf)
- 0xa0-0xd in MS Kanji (0xa0-0xdf)
- */
- continue;
- case 'X': /* Convert X0201 kana to X0208 */
- x0201_f = TRUE;
- continue;
- case 'F': /* prserve new lines */
+ if (!alpha_f) alpha_f = 1;
+ continue;
+ case 'x': /* Convert X0201 kana to X0208 or X0201 Conversion */
+ x0201_f = FALSE; /* No X0201->X0208 conversion */
+ /* accept X0201
+ ESC-(-I in JIS, EUC, MS Kanji
+ SI/SO in JIS, EUC, MS Kanji
+ SS2 in EUC, JIS, not in MS Kanji
+ MS Kanji (0xa0-0xdf)
+ output X0201
+ ESC-(-I in JIS (0x20-0x5f)
+ SS2 in EUC (0xa0-0xdf)
+ 0xa0-0xd in MS Kanji (0xa0-0xdf)
+ */
+ continue;
+ case 'X': /* Convert X0201 kana to X0208 */
+ x0201_f = TRUE;
+ continue;
+ case 'F': /* prserve new lines */
fold_preserve_f = TRUE;
- case 'f': /* folding -f60 or -f */
- fold_f = TRUE;
- fold_len = 0;
- while('0'<= *cp && *cp <='9') { /* we don't use atoi here */
+ case 'f': /* folding -f60 or -f */
+ fold_f = TRUE;
+ fold_len = 0;
+ while('0'<= *cp && *cp <='9') { /* we don't use atoi here */
fold_len *= 10;
fold_len += *cp++ - '0';
}
- if (!(0<fold_len && fold_len<BUFSIZ))
- fold_len = DEFAULT_FOLD;
+ if (!(0<fold_len && fold_len<BUFSIZ))
+ fold_len = DEFAULT_FOLD;
if (*cp=='-') {
fold_margin = 0;
cp++;
@@ -6006,99 +6150,103 @@
fold_margin += *cp++ - '0';
}
}
- continue;
- case 'm': /* MIME support */
- /* mime_decode_f = TRUE; */ /* this has too large side effects... */
- if (*cp=='B'||*cp=='Q') {
- mime_decode_mode = *cp++;
- mimebuf_f = FIXED_MIME;
- } else if (*cp=='N') {
- mime_f = TRUE; cp++;
- } else if (*cp=='S') {
- mime_f = STRICT_MIME; cp++;
- } else if (*cp=='0') {
- mime_decode_f = FALSE;
- mime_f = FALSE; cp++;
- } else {
- mime_f = STRICT_MIME;
- }
- continue;
- case 'M': /* MIME output */
- if (*cp=='B') {
- mimeout_mode = 'B';
- mimeout_f = FIXED_MIME; cp++;
- } else if (*cp=='Q') {
- mimeout_mode = 'Q';
- mimeout_f = FIXED_MIME; cp++;
- } else {
+ continue;
+ case 'm': /* MIME support */
+ /* mime_decode_f = TRUE; */ /* this has too large side effects... */
+ if (*cp=='B'||*cp=='Q') {
+ mime_decode_mode = *cp++;
+ mimebuf_f = FIXED_MIME;
+ } else if (*cp=='N') {
+ mime_f = TRUE; cp++;
+ } else if (*cp=='S') {
+ mime_f = STRICT_MIME; cp++;
+ } else if (*cp=='0') {
+ mime_decode_f = FALSE;
+ mime_f = FALSE; cp++;
+ } else {
+ mime_f = STRICT_MIME;
+ }
+ continue;
+ case 'M': /* MIME output */
+ if (*cp=='B') {
+ mimeout_mode = 'B';
+ mimeout_f = FIXED_MIME; cp++;
+ } else if (*cp=='Q') {
+ mimeout_mode = 'Q';
+ mimeout_f = FIXED_MIME; cp++;
+ } else {
mimeout_f = TRUE;
}
- continue;
- case 'B': /* Broken JIS support */
- /* bit:0 no ESC JIS
- bit:1 allow any x on ESC-(-x or ESC-$-x
- bit:2 reset to ascii on NL
- */
- if ('9'>= *cp && *cp>='0')
- broken_f |= 1<<(*cp++ -'0');
- else
- broken_f |= TRUE;
- continue;
+ continue;
+ case 'B': /* Broken JIS support */
+ /* bit:0 no ESC JIS
+ bit:1 allow any x on ESC-(-x or ESC-$-x
+ bit:2 reset to ascii on NL
+ */
+ if ('9'>= *cp && *cp>='0')
+ broken_f |= 1<<(*cp++ -'0');
+ else
+ broken_f |= TRUE;
+ continue;
#ifndef PERL_XS
- case 'O':/* for Output file */
- file_out_f = TRUE;
- continue;
+ case 'O':/* for Output file */
+ file_out_f = TRUE;
+ continue;
#endif
- case 'c':/* add cr code */
- eolmode_f = CRLF;
- continue;
- case 'd':/* delete cr code */
- eolmode_f = LF;
- continue;
+ case 'c':/* add cr code */
+ eolmode_f = CRLF;
+ continue;
+ case 'd':/* delete cr code */
+ eolmode_f = LF;
+ continue;
case 'I': /* ISO-2022-JP output */
iso2022jp_f = TRUE;
continue;
- case 'L': /* line mode */
- if (*cp=='u') { /* unix */
- eolmode_f = LF; cp++;
- } else if (*cp=='m') { /* mac */
- eolmode_f = CR; cp++;
- } else if (*cp=='w') { /* windows */
- eolmode_f = CRLF; cp++;
- } else if (*cp=='0') { /* no conversion */
- eolmode_f = 0; cp++;
- }
- continue;
+ case 'L': /* line mode */
+ if (*cp=='u') { /* unix */
+ eolmode_f = LF; cp++;
+ } else if (*cp=='m') { /* mac */
+ eolmode_f = CR; cp++;
+ } else if (*cp=='w') { /* windows */
+ eolmode_f = CRLF; cp++;
+ } else if (*cp=='0') { /* no conversion */
+ eolmode_f = 0; cp++;
+ }
+ continue;
#ifndef PERL_XS
- case 'g':
- if ('2' <= *cp && *cp <= '9') {
- guess_f = 2;
- cp++;
- } else if (*cp == '0' || *cp == '1') {
+ case 'g':
+ if ('2' <= *cp && *cp <= '9') {
+ guess_f = 2;
+ cp++;
+ } else if (*cp == '0' || *cp == '1') {
guess_f = 1;
- cp++;
- } else {
+ cp++;
+ } else {
guess_f = 1;
- }
- continue;
+ }
+ continue;
#endif
- case SP:
- /* module muliple options in a string are allowed for Perl moudle */
+ case SP:
+ /* module muliple options in a string are allowed for Perl moudle */
while(*cp && *cp++!='-');
- continue;
- default:
+ continue;
+ default:
+#if !defined(PERL_XS) && !defined(WIN32DLL)
fprintf(stderr, "unknown option: -%c\n", *(cp-1));
- /* bogus option but ignored */
- continue;
- }
+#endif
+ /* bogus option but ignored */
+ return -1;
+ }
}
+ return 0;
}
#ifdef WIN32DLL
#include "nkf32dll.c"
#elif defined(PERL_XS)
#else /* WIN32DLL */
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
FILE *fin;
unsigned char *cp;
@@ -6109,37 +6257,38 @@
#ifdef EASYWIN /*Easy Win */
_BufferSize.y = 400;/*Set Scroll Buffer Size*/
#endif
+#ifdef DEFAULT_CODE_LOCALE
setlocale(LC_CTYPE, "");
-
+#endif
for (argc--,argv++; (argc > 0) && **argv == '-'; argc--, argv++) {
- cp = (unsigned char *)*argv;
- options(cp);
+ cp = (unsigned char *)*argv;
+ options(cp);
#ifdef EXEC_IO
- if (exec_f){
- int fds[2], pid;
- if (pipe(fds) < 0 || (pid = fork()) < 0){
- abort();
- }
- if (pid == 0){
- if (exec_f > 0){
- close(fds[0]);
- dup2(fds[1], 1);
- }else{
- close(fds[1]);
- dup2(fds[0], 0);
- }
- execvp(argv[1], &argv[1]);
- }
- if (exec_f > 0){
- close(fds[1]);
- dup2(fds[0], 0);
- }else{
- close(fds[0]);
- dup2(fds[1], 1);
- }
- argc = 0;
- break;
- }
+ if (exec_f){
+ int fds[2], pid;
+ if (pipe(fds) < 0 || (pid = fork()) < 0){
+ abort();
+ }
+ if (pid == 0){
+ if (exec_f > 0){
+ close(fds[0]);
+ dup2(fds[1], 1);
+ }else{
+ close(fds[1]);
+ dup2(fds[0], 0);
+ }
+ execvp(argv[1], &argv[1]);
+ }
+ if (exec_f > 0){
+ close(fds[1]);
+ dup2(fds[0], 0);
+ }else{
+ close(fds[0]);
+ dup2(fds[1], 1);
+ }
+ argc = 0;
+ break;
+ }
#endif
}
@@ -6164,158 +6313,156 @@
#ifdef EXEC_IO
exec_f = exec_f_back;
#endif
-#ifdef X0212_ENABLE
x0212_f = x0212_f_back;
-#endif
x0213_f = x0213_f_back;
}
if (binmode_f == TRUE)
#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__))
- if (freopen("","wb",stdout) == NULL)
- return (-1);
+ if (freopen("","wb",stdout) == NULL)
+ return (-1);
#else
setbinmode(stdout);
#endif
if (unbuf_f)
- setbuf(stdout, (char *) NULL);
+ setbuf(stdout, (char *) NULL);
else
- setvbuffer(stdout, (char *) stdobuf, IOBUF_SIZE);
+ setvbuffer(stdout, (char *) stdobuf, IOBUF_SIZE);
if (argc == 0) {
- if (binmode_f == TRUE)
+ if (binmode_f == TRUE)
#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__))
- if (freopen("","rb",stdin) == NULL) return (-1);
+ if (freopen("","rb",stdin) == NULL) return (-1);
#else
- setbinmode(stdin);
+ setbinmode(stdin);
#endif
- setvbuffer(stdin, (char *) stdibuf, IOBUF_SIZE);
- if (nop_f)
- noconvert(stdin);
- else {
- kanji_convert(stdin);
- if (guess_f) print_guessed_code(NULL);
- }
+ setvbuffer(stdin, (char *) stdibuf, IOBUF_SIZE);
+ if (nop_f)
+ noconvert(stdin);
+ else {
+ kanji_convert(stdin);
+ if (guess_f) print_guessed_code(NULL);
+ }
} else {
- int nfiles = argc;
+ int nfiles = argc;
int is_argument_error = FALSE;
- while (argc--) {
+ while (argc--) {
input_codename = NULL;
input_eol = 0;
#ifdef CHECK_OPTION
iconv_for_check = 0;
#endif
- if ((fin = fopen((origfname = *argv++), "r")) == NULL) {
+ if ((fin = fopen((origfname = *argv++), "r")) == NULL) {
perror(*(argv-1));
is_argument_error = TRUE;
continue;
- } else {
+ } else {
#ifdef OVERWRITE
- int fd = 0;
- int fd_backup = 0;
+ int fd = 0;
+ int fd_backup = 0;
#endif
-/* reopen file for stdout */
- if (file_out_f == TRUE) {
+ /* reopen file for stdout */
+ if (file_out_f == TRUE) {
#ifdef OVERWRITE
- if (overwrite_f){
- outfname = malloc(strlen(origfname)
- + strlen(".nkftmpXXXXXX")
- + 1);
- if (!outfname){
- perror(origfname);
- return -1;
- }
- strcpy(outfname, origfname);
+ if (overwrite_f){
+ outfname = malloc(strlen(origfname)
+ + strlen(".nkftmpXXXXXX")
+ + 1);
+ if (!outfname){
+ perror(origfname);
+ return -1;
+ }
+ strcpy(outfname, origfname);
#ifdef MSDOS
- {
- int i;
- for (i = strlen(outfname); i; --i){
- if (outfname[i - 1] == '/'
- || outfname[i - 1] == '\\'){
- break;
- }
- }
- outfname[i] = '\0';
- }
- strcat(outfname, "ntXXXXXX");
- mktemp(outfname);
+ {
+ int i;
+ for (i = strlen(outfname); i; --i){
+ if (outfname[i - 1] == '/'
+ || outfname[i - 1] == '\\'){
+ break;
+ }
+ }
+ outfname[i] = '\0';
+ }
+ strcat(outfname, "ntXXXXXX");
+ mktemp(outfname);
fd = open(outfname, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,
- S_IREAD | S_IWRITE);
+ S_IREAD | S_IWRITE);
#else
- strcat(outfname, ".nkftmpXXXXXX");
- fd = mkstemp(outfname);
+ strcat(outfname, ".nkftmpXXXXXX");
+ fd = mkstemp(outfname);
#endif
- if (fd < 0
- || (fd_backup = dup(fileno(stdout))) < 0
- || dup2(fd, fileno(stdout)) < 0
- ){
- perror(origfname);
- return -1;
- }
- }else
+ if (fd < 0
+ || (fd_backup = dup(fileno(stdout))) < 0
+ || dup2(fd, fileno(stdout)) < 0
+ ){
+ perror(origfname);
+ return -1;
+ }
+ }else
#endif
- if(argc == 1) {
- outfname = *argv++;
- argc--;
- } else {
- outfname = "nkf.out";
- }
+ if(argc == 1) {
+ outfname = *argv++;
+ argc--;
+ } else {
+ outfname = "nkf.out";
+ }
- if(freopen(outfname, "w", stdout) == NULL) {
- perror (outfname);
- return (-1);
- }
- if (binmode_f == TRUE) {
+ if(freopen(outfname, "w", stdout) == NULL) {
+ perror (outfname);
+ return (-1);
+ }
+ if (binmode_f == TRUE) {
#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__))
- if (freopen("","wb",stdout) == NULL)
- return (-1);
+ if (freopen("","wb",stdout) == NULL)
+ return (-1);
#else
- setbinmode(stdout);
+ setbinmode(stdout);
#endif
- }
- }
- if (binmode_f == TRUE)
+ }
+ }
+ if (binmode_f == TRUE)
#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__))
- if (freopen("","rb",fin) == NULL)
- return (-1);
+ if (freopen("","rb",fin) == NULL)
+ return (-1);
#else
- setbinmode(fin);
+ setbinmode(fin);
#endif
- setvbuffer(fin, (char *) stdibuf, IOBUF_SIZE);
- if (nop_f)
- noconvert(fin);
- else {
- char *filename = NULL;
- kanji_convert(fin);
- if (nfiles > 1) filename = origfname;
- if (guess_f) print_guessed_code(filename);
- }
- fclose(fin);
+ setvbuffer(fin, (char *) stdibuf, IOBUF_SIZE);
+ if (nop_f)
+ noconvert(fin);
+ else {
+ char *filename = NULL;
+ kanji_convert(fin);
+ if (nfiles > 1) filename = origfname;
+ if (guess_f) print_guessed_code(filename);
+ }
+ fclose(fin);
#ifdef OVERWRITE
- if (overwrite_f) {
- struct stat sb;
+ if (overwrite_f) {
+ struct stat sb;
#if defined(MSDOS) && !defined(__MINGW32__) && !defined(__WIN32__) && !defined(__WATCOMC__) && !defined(__EMX__) && !defined(__OS2__) && !defined(__DJGPP__)
- time_t tb[2];
+ time_t tb[2];
#else
- struct utimbuf tb;
+ struct utimbuf tb;
#endif
- fflush(stdout);
- close(fd);
- if (dup2(fd_backup, fileno(stdout)) < 0){
- perror("dup2");
- }
- if (stat(origfname, &sb)) {
- fprintf(stderr, "Can't stat %s\n", origfname);
- }
- /* $B%Q!<%_%C%7%g%s$rI|85(B */
- if (chmod(outfname, sb.st_mode)) {
- fprintf(stderr, "Can't set permission %s\n", outfname);
- }
+ fflush(stdout);
+ close(fd);
+ if (dup2(fd_backup, fileno(stdout)) < 0){
+ perror("dup2");
+ }
+ if (stat(origfname, &sb)) {
+ fprintf(stderr, "Can't stat %s\n", origfname);
+ }
+ /* $B%Q!<%_%C%7%g%s$rI|85(B */
+ if (chmod(outfname, sb.st_mode)) {
+ fprintf(stderr, "Can't set permission %s\n", outfname);
+ }
- /* $B%?%$%`%9%?%s%W$rI|85(B */
+ /* $B%?%$%`%9%?%s%W$rI|85(B */
if(preserve_time_f){
#if defined(MSDOS) && !defined(__MINGW32__) && !defined(__WIN32__) && !defined(__WATCOMC__) && !defined(__EMX__) && !defined(__OS2__) && !defined(__DJGPP__)
tb[0] = tb[1] = sb.st_mtime;
@@ -6340,6 +6487,7 @@
fprintf(stderr, "Can't rename %s to %s\n",
origfname, backup_filename);
}
+ free(backup_filename);
}else{
#ifdef MSDOS
if (unlink(origfname)){
@@ -6347,27 +6495,27 @@
}
#endif
}
- if (rename(outfname, origfname)) {
- perror(origfname);
- fprintf(stderr, "Can't rename %s to %s\n",
- outfname, origfname);
- }
- free(outfname);
- }
+ if (rename(outfname, origfname)) {
+ perror(origfname);
+ fprintf(stderr, "Can't rename %s to %s\n",
+ outfname, origfname);
+ }
+ free(outfname);
+ }
#endif
- }
- }
+ }
+ }
if (is_argument_error)
return(-1);
}
#ifdef EASYWIN /*Easy Win */
if (file_out_f == FALSE)
- scanf("%d",&end_check);
+ scanf("%d",&end_check);
else
- fclose(stdout);
+ fclose(stdout);
#else /* for Other OS */
if (file_out_f == TRUE)
- fclose(stdout);
+ fclose(stdout);
#endif /*Easy Win */
return (0);
}
Modified: MacRuby/trunk/ext/nkf/nkf.c
===================================================================
--- MacRuby/trunk/ext/nkf/nkf.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/nkf/nkf.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -3,11 +3,11 @@
*
* original nkf2.x is maintained at http://sourceforge.jp/projects/nkf/
*
- * $Id: nkf.c 16149 2008-04-22 12:20:36Z naruse $
+ * $Id: nkf.c 16493 2008-05-20 13:10:28Z naruse $
*
*/
-#define RUBY_NKF_REVISION "$Revision: 16149 $"
+#define RUBY_NKF_REVISION "$Revision: 16493 $"
#define RUBY_NKF_VERSION NKF_VERSION " (" NKF_RELEASE_DATE ")"
#include "ruby/ruby.h"
@@ -143,6 +143,15 @@
nkf_split_options(RSTRING_PTR(opt));
if (!output_encoding) rb_raise(rb_eArgError, "no output encoding given");
+ switch (nkf_enc_to_index(output_encoding)) {
+ case UTF_8_BOM: output_encoding = nkf_enc_from_index(UTF_8); break;
+ case UTF_16BE_BOM: output_encoding = nkf_enc_from_index(UTF_16BE); break;
+ case UTF_16LE_BOM: output_encoding = nkf_enc_from_index(UTF_16LE); break;
+ case UTF_32BE_BOM: output_encoding = nkf_enc_from_index(UTF_32BE); break;
+ case UTF_32LE_BOM: output_encoding = nkf_enc_from_index(UTF_32LE); break;
+ }
+ output_bom_f = FALSE;
+
incsize = INCSIZE;
input_ctr = 0;
@@ -480,8 +489,8 @@
rb_define_const(mNKF, "EUC", rb_enc_from_encoding(rb_nkf_enc_get("EUC-JP")));
rb_define_const(mNKF, "SJIS", rb_enc_from_encoding(rb_nkf_enc_get("Shift_JIS")));
rb_define_const(mNKF, "UTF8", rb_enc_from_encoding(rb_utf8_encoding()));
- rb_define_const(mNKF, "UTF16", rb_enc_from_encoding(rb_nkf_enc_get("UTF-16")));
- rb_define_const(mNKF, "UTF32", rb_enc_from_encoding(rb_nkf_enc_get("UTF-32")));
+ rb_define_const(mNKF, "UTF16", rb_enc_from_encoding(rb_nkf_enc_get("UTF-16BE")));
+ rb_define_const(mNKF, "UTF32", rb_enc_from_encoding(rb_nkf_enc_get("UTF-32BE")));
/* Full version string of nkf */
rb_define_const(mNKF, "VERSION", rb_str_new2(RUBY_NKF_VERSION));
Modified: MacRuby/trunk/ext/openssl/ossl_bn.c
===================================================================
--- MacRuby/trunk/ext/openssl/ossl_bn.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/openssl/ossl_bn.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,5 +1,5 @@
/*
- * $Id: ossl_bn.c 14377 2007-12-21 02:31:11Z akr $
+ * $Id: ossl_bn.c 16689 2008-05-29 17:41:56Z knu $
* 'OpenSSL for Ruby' project
* Copyright (C) 2001-2002 Technorama team <oss-ruby at technorama.net>
* All rights reserved.
@@ -515,7 +515,7 @@
bottom = (odd == Qtrue) ? 1 : 0; \
/* FALLTHROUGH */ \
case 2: \
- top = FIX2INT(fill); \
+ top = NUM2INT(fill); \
} \
b = NUM2INT(bits); \
if (!(result = BN_new())) { \
Modified: MacRuby/trunk/ext/openssl/ossl_pkcs5.c
===================================================================
--- MacRuby/trunk/ext/openssl/ossl_pkcs5.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/openssl/ossl_pkcs5.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -27,7 +27,7 @@
{
#ifdef HAVE_PKCS5_PBKDF2_HMAC
VALUE str;
- const EVP_MD md;
+ const EVP_MD *md;
int len = NUM2INT(keylen);
StringValue(pass);
Modified: MacRuby/trunk/ext/openssl/ossl_pkey_dh.c
===================================================================
--- MacRuby/trunk/ext/openssl/ossl_pkey_dh.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/openssl/ossl_pkey_dh.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,5 +1,5 @@
/*
- * $Id: ossl_pkey_dh.c 15610 2008-02-26 07:07:26Z technorama $
+ * $Id: ossl_pkey_dh.c 16689 2008-05-29 17:41:56Z knu $
* 'OpenSSL for Ruby' project
* Copyright (C) 2001-2002 Michal Rokos <m.rokos at sh.cvut.cz>
* All rights reserved.
@@ -116,9 +116,9 @@
VALUE size, gen, obj;
if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) {
- g = FIX2INT(gen);
+ g = NUM2INT(gen);
}
- dh = dh_generate(FIX2INT(size), g);
+ dh = dh_generate(NUM2INT(size), g);
obj = dh_instance(klass, dh);
if (obj == Qfalse) {
DH_free(dh);
@@ -158,7 +158,7 @@
}
else if (FIXNUM_P(arg)) {
if (!NIL_P(gen)) {
- g = FIX2INT(gen);
+ g = NUM2INT(gen);
}
if (!(dh = dh_generate(FIX2INT(arg), g))) {
ossl_raise(eDHError, NULL);
Modified: MacRuby/trunk/ext/openssl/ossl_pkey_dsa.c
===================================================================
--- MacRuby/trunk/ext/openssl/ossl_pkey_dsa.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/openssl/ossl_pkey_dsa.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,5 +1,5 @@
/*
- * $Id: ossl_pkey_dsa.c 15610 2008-02-26 07:07:26Z technorama $
+ * $Id: ossl_pkey_dsa.c 16689 2008-05-29 17:41:56Z knu $
* 'OpenSSL for Ruby' project
* Copyright (C) 2001-2002 Michal Rokos <m.rokos at sh.cvut.cz>
* All rights reserved.
@@ -110,7 +110,7 @@
static VALUE
ossl_dsa_s_generate(VALUE klass, VALUE size)
{
- DSA *dsa = dsa_generate(FIX2INT(size)); /* err handled by dsa_instance */
+ DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */
VALUE obj = dsa_instance(klass, dsa);
if (obj == Qfalse) {
Modified: MacRuby/trunk/ext/openssl/ossl_rand.c
===================================================================
--- MacRuby/trunk/ext/openssl/ossl_rand.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/openssl/ossl_rand.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,5 +1,5 @@
/*
- * $Id: ossl_rand.c 14696 2007-12-25 11:31:51Z technorama $
+ * $Id: ossl_rand.c 16692 2008-05-29 18:15:50Z knu $
* 'OpenSSL for Ruby' project
* Copyright (C) 2001-2002 Michal Rokos <m.rokos at sh.cvut.cz>
* All rights reserved.
@@ -96,9 +96,10 @@
ossl_rand_bytes(VALUE self, VALUE len)
{
VALUE str;
+ int n = NUM2INT(len);
- str = rb_str_new(0, FIX2INT(len));
- if (!RAND_bytes(RSTRING_PTR(str), FIX2INT(len))) {
+ str = rb_str_new(0, n);
+ if (!RAND_bytes(RSTRING_PTR(str), n)) {
ossl_raise(eRandomError, NULL);
}
@@ -114,9 +115,10 @@
ossl_rand_pseudo_bytes(VALUE self, VALUE len)
{
VALUE str;
+ int n = NUM2INT(len);
- str = rb_str_new(0, FIX2INT(len));
- if (!RAND_pseudo_bytes(RSTRING_PTR(str), FIX2INT(len))) {
+ str = rb_str_new(0, n);
+ if (!RAND_pseudo_bytes(RSTRING_PTR(str), n)) {
ossl_raise(eRandomError, NULL);
}
@@ -147,9 +149,11 @@
static VALUE
ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
{
+ long n = NUM2INT(len);
+
SafeStringValue(filename);
- if (!RAND_egd_bytes(RSTRING_PTR(filename), FIX2INT(len))) {
+ if (!RAND_egd_bytes(RSTRING_PTR(filename), n)) {
ossl_raise(eRandomError, NULL);
}
return Qtrue;
Modified: MacRuby/trunk/ext/openssl/ossl_x509store.c
===================================================================
--- MacRuby/trunk/ext/openssl/ossl_x509store.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/openssl/ossl_x509store.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,5 +1,5 @@
/*
- * $Id: ossl_x509store.c 12153 2007-04-05 19:03:28Z technorama $
+ * $Id: ossl_x509store.c 16689 2008-05-29 17:41:56Z knu $
* 'OpenSSL for Ruby' project
* Copyright (C) 2001-2002 Michal Rokos <m.rokos at sh.cvut.cz>
* All rights reserved.
@@ -458,7 +458,7 @@
X509_STORE_CTX *ctx;
GetX509StCtx(self, ctx);
- X509_STORE_CTX_set_error(ctx, FIX2INT(err));
+ X509_STORE_CTX_set_error(ctx, NUM2INT(err));
return err;
}
Modified: MacRuby/trunk/ext/purelib.rb
===================================================================
--- MacRuby/trunk/ext/purelib.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/purelib.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,3 +1,10 @@
-if nul = $:.find_index {|path| /\A(?:\.\/)*-\z/ =~ path}
+nul = nil
+$:.each_with_index {|path, index|
+ if /\A(?:\.\/)*-\z/ =~ path
+ nul = index
+ break
+ end
+}
+if nul
$:[nul..-1] = ["."]
end
Modified: MacRuby/trunk/ext/stringio/stringio.c
===================================================================
--- MacRuby/trunk/ext/stringio/stringio.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/stringio/stringio.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -622,7 +622,7 @@
char c = RSTRING_PTR(ptr->string)[ptr->pos++];
rb_yield(CHR2FIX(c));
}
- return Qnil;
+ return self;
}
/*
@@ -768,6 +768,25 @@
return c;
}
+/*
+ * call-seq:
+ * strio.each_char {|char| block } -> strio
+ *
+ * See IO#each_char.
+ */
+static VALUE
+strio_each_char(VALUE self)
+{
+ VALUE c;
+
+ RETURN_ENUMERATOR(self, 0, 0);
+
+ while (!NIL_P(c = strio_getc(self))) {
+ rb_yield(c);
+ }
+ return self;
+}
+
/* Boyer-Moore search: copied from regex.c */
static void
bm_init_skip(long *skip, const char *pat, long m)
@@ -1250,10 +1269,12 @@
rb_define_method(StringIO, "path", strio_path, 0);
rb_define_method(StringIO, "each", strio_each, -1);
- rb_define_method(StringIO, "each_byte", strio_each_byte, 0);
- rb_define_method(StringIO, "bytes", strio_each_byte, -1);
rb_define_method(StringIO, "each_line", strio_each, -1);
rb_define_method(StringIO, "lines", strio_each, -1);
+ rb_define_method(StringIO, "each_byte", strio_each_byte, 0);
+ rb_define_method(StringIO, "bytes", strio_each_byte, 0);
+ rb_define_method(StringIO, "each_char", strio_each_char, 0);
+ rb_define_method(StringIO, "chars", strio_each_char, 0);
rb_define_method(StringIO, "getc", strio_getc, 0);
rb_define_method(StringIO, "ungetc", strio_ungetc, 1);
rb_define_method(StringIO, "readchar", strio_readchar, 0);
Modified: MacRuby/trunk/ext/zlib/extconf.rb
===================================================================
--- MacRuby/trunk/ext/zlib/extconf.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ext/zlib/extconf.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,7 +1,7 @@
#
# extconf.rb
#
-# $Id: extconf.rb 11708 2007-02-12 23:01:19Z shyouhei $
+# $Id: extconf.rb 16677 2008-05-29 08:52:31Z nobu $
#
require 'mkmf'
@@ -10,7 +10,7 @@
dir_config 'zlib'
-if %w'z libz zlib zdll'.find {|z| have_library(z, 'deflateReset')} and
+if %w'z libz zlib1 zlib zdll'.find {|z| have_library(z, 'deflateReset')} and
have_header('zlib.h') then
defines = []
@@ -22,7 +22,7 @@
os_code = 'AMIGA'
when /\Aos2[\-_]emx\z/ then
os_code = 'OS2'
- when 'mswin32', 'mingw32', 'bccwin32' then
+ when /mswin|mingw|bccwin/ then
# NOTE: cygwin should be regarded as Unix.
os_code = 'WIN32'
else
Modified: MacRuby/trunk/file.c
===================================================================
--- MacRuby/trunk/file.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/file.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2392,7 +2392,10 @@
return INT2FIX(omask);
}
-#if defined DOSISH
+#ifdef __CYGWIN__
+#undef DOSISH
+#endif
+#if defined __CYGWIN__ || defined DOSISH
#define DOSISH_UNC
#define DOSISH_DRIVE_LETTER
#define isdirsep(x) ((x) == '/' || (x) == '\\')
@@ -2552,6 +2555,7 @@
static char *
ntfs_tail(const char *path)
{
+ while (*path == '.') path++;
while (*path && *path != ':') {
if (istrailinggabage(*path)) {
const char *last = path++;
@@ -2574,13 +2578,13 @@
#define BUFCHECK(cond) do {\
long bdiff = p - buf;\
- while (cond) {\
- buflen *= 2;\
+ if (cond) {\
+ do {buflen *= 2;} while (cond);\
+ rb_str_resize(result, buflen);\
+ buf = RSTRING_PTR(result);\
+ p = buf + bdiff;\
+ pend = buf + buflen;\
}\
- rb_str_resize(result, buflen);\
- buf = RSTRING_PTR(result);\
- p = buf + bdiff;\
- pend = buf + buflen;\
} while (0)
#define BUFINIT() (\
@@ -2605,7 +2609,9 @@
char *buf, *p, *pend, *root;
long buflen, dirlen;
int tainted;
+#if !WITH_OBJC
rb_encoding *extenc = 0;
+#endif
FilePathValue(fname);
s = StringValuePtr(fname);
@@ -2735,8 +2741,11 @@
}
if (p > buf && p[-1] == '/')
--p;
- else
+ else {
+ ++buflen;
+ BUFCHECK(bdiff >= buflen);
*p = '/';
+ }
p[1] = 0;
root = skipprefix(buf);
@@ -2829,19 +2838,23 @@
p += s-b;
}
if (p == skiproot(buf) - 1) p++;
- buflen = p - buf;
#if USE_NTFS
*p = '\0';
- if (!strpbrk(b = buf, "*?")) {
+ if (1 &&
+#ifdef __CYGWIN__
+ !(buf[0] == '/' && !buf[1]) &&
+#endif
+ !strpbrk(b = buf, "*?")) {
size_t len;
WIN32_FIND_DATA wfd;
#ifdef __CYGWIN__
- int lnk_added = 0;
+ int lnk_added = 0, is_symlink = 0;
struct stat st;
char w32buf[MAXPATHLEN], sep = 0;
p = 0;
if (lstat(buf, &st) == 0 && S_ISLNK(st.st_mode)) {
+ is_symlink = 1;
p = strrdirsep(buf);
if (!p) p = skipprefix(buf);
if (p) {
@@ -2854,8 +2867,7 @@
}
if (p) *p = sep;
else p = buf;
- if (b == w32buf) {
- strlcat(w32buf, p, sizeof(w32buf));
+ if (is_symlink && b == w32buf) {
len = strlen(p);
if (len > 4 && STRCASECMP(p + len - 4, ".lnk") != 0) {
lnk_added = 1;
@@ -2871,19 +2883,20 @@
#ifdef __CYGWIN__
if (lnk_added && len > 4 &&
STRCASECMP(wfd.cFileName + len - 4, ".lnk") == 0) {
- len -= 4;
+ wfd.cFileName[len -= 4] = '\0';
}
#endif
if (!p) p = buf;
- buflen = ++p - buf + len;
- rb_str_resize(result, buflen);
+ else ++p;
+ BUFCHECK(bdiff + len >= buflen);
memcpy(p, wfd.cFileName, len + 1);
+ p += len;
}
}
#endif
if (tainted) OBJ_TAINT(result);
- rb_str_set_len(result, buflen);
+ rb_str_set_len(result, p - buf);
#if !WITH_OBJC
rb_enc_check(fname, result);
#endif
@@ -3117,7 +3130,7 @@
if (!p)
p = name;
else
- p++;
+ name = ++p;
e = 0;
while (*p) {
@@ -3147,7 +3160,7 @@
break;
p = CharNext(p);
}
- if (!e || e+1 == p) /* no dot, or the only dot is first or end? */
+ if (!e || e == name || e+1 == p) /* no dot, or the only dot is first or end? */
return rb_str_new(0, 0);
extname = rb_str_new(e, p - e); /* keep the dot, too! */
#if !WITH_OBJC
@@ -3196,6 +3209,7 @@
static VALUE rb_file_join(VALUE ary, VALUE sep);
+#if !WITH_OBJC
static VALUE
file_inspect_join(VALUE ary, VALUE argp, int recur)
{
@@ -3203,6 +3217,7 @@
if (recur) return rb_usascii_str_new2("[...]");
return rb_file_join(arg[0], arg[1]);
}
+#endif
static VALUE
rb_file_join(VALUE ary, VALUE sep)
Modified: MacRuby/trunk/gc.c
===================================================================
--- MacRuby/trunk/gc.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/gc.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -38,6 +38,7 @@
#endif
#if WITH_OBJC
+# include <mach/mach.h>
# if HAVE_AUTO_ZONE_H
# include <auto_zone.h>
# else
@@ -904,7 +905,7 @@
if (!SPECIAL_CONST_P(newval)) {
//printf("rb_objc_wb %p %p\n", dst, newval);
if (!auto_zone_set_write_barrier(__auto_zone, dst, newval))
- rb_bug("destination %p isn't in the auto zone");
+ rb_bug("destination %p isn't in the auto zone", dst);
}
*(void **)dst = newval;
}
@@ -929,17 +930,17 @@
}
void
-rb_objc_retain(void *addr)
+rb_objc_retain(const void *addr)
{
if (addr != NULL && !SPECIAL_CONST_P(addr))
- auto_zone_retain(__auto_zone, addr);
+ auto_zone_retain(__auto_zone, (void *)addr);
}
void
-rb_objc_release(void *addr)
+rb_objc_release(const void *addr)
{
if (addr != NULL && !SPECIAL_CONST_P(addr))
- auto_zone_release(__auto_zone, addr);
+ auto_zone_release(__auto_zone, (void *)addr);
}
void
@@ -2281,8 +2282,7 @@
switch (BUILTIN_TYPE(r->address)) {
case T_NONE:
case T_ICLASS:
- case T_NODE:
- case T_VALUES:
+ case T_NODE:
continue;
case T_CLASS:
if (FL_TEST(r->address, FL_SINGLETON))
@@ -2419,7 +2419,7 @@
CFDictionaryRemoveValue(__os_finalizers, (const void *)obj);
if (rb_objc_is_non_native(obj)) {
- rb_objc_flag_set(obj, FL_FINALIZE, false);
+ rb_objc_flag_set((void *)obj, FL_FINALIZE, false);
}
else {
FL_UNSET(obj, FL_FINALIZE);
@@ -2473,7 +2473,7 @@
rb_ary_push(table, block);
if (rb_objc_is_non_native(obj)) {
- rb_objc_flag_set(obj, FL_FINALIZE, true);
+ rb_objc_flag_set((void *)obj, FL_FINALIZE, true);
}
else {
FL_SET(obj, FL_FINALIZE);
@@ -2504,8 +2504,8 @@
else {
st_add_direct(finalizer_table, obj, rb_ary_new3(1, block));
}
- return block;
#endif
+ return block;
}
void
@@ -2518,7 +2518,7 @@
return;
if (rb_objc_is_non_native(obj)) {
- if (!rb_objc_flag_check(obj, FL_FINALIZE))
+ if (!rb_objc_flag_check((void *)obj, FL_FINALIZE))
return;
}
else {
@@ -2784,8 +2784,7 @@
if ((type == AUTO_OBJECT_SCANNED || type == AUTO_OBJECT_UNSCANNED)
&& !rb_objc_is_placeholder(p0)
&& (rb_objc_is_non_native((VALUE)p0)
- || (BUILTIN_TYPE(p0) < T_VALUES
- && BUILTIN_TYPE(p0) != T_ICLASS)))
+ || (BUILTIN_TYPE(p0) < T_FIXNUM && BUILTIN_TYPE(p0) != T_ICLASS)))
return (VALUE)p0;
}
rb_raise(rb_eRangeError, "%p is not id value", p0);
Modified: MacRuby/trunk/hash.c
===================================================================
--- MacRuby/trunk/hash.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/hash.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
hash.c -
- $Author: matz $
+ $Author: knu $
created at: Mon Nov 22 18:51:18 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -371,7 +371,7 @@
rb_hash_modify_check(VALUE hash)
{
long mask;
- mask = rb_objc_flag_get_mask(hash);
+ mask = rb_objc_flag_get_mask((const void *)hash);
if (mask == 0) {
bool _CFDictionaryIsMutable(void *);
if (!_CFDictionaryIsMutable((void *)hash))
@@ -508,7 +508,7 @@
hash = hash_alloc(klass);
count = CFDictionaryGetCount((CFDictionaryRef)tmp);
if (count == 0)
- return;
+ return hash;
keys = (const void **)alloca(sizeof(void *) * count);
values = (const void **)alloca(sizeof(void *) * count);
@@ -836,8 +836,8 @@
#else
RHASH(hash)->ifnone = ifnone;
FL_UNSET(hash, HASH_PROC_DEFAULT);
+#endif
return ifnone;
-#endif
}
/*
@@ -975,6 +975,7 @@
return Qnil;
}
+#if !WITH_OBJC
struct shift_var {
VALUE key;
VALUE val;
@@ -998,6 +999,7 @@
var->val = value;
return ST_STOP;
}
+#endif
/*
* call-seq:
@@ -1196,11 +1198,13 @@
return result;
}
+#if !WITH_OBJC
static int
clear_i(VALUE key, VALUE value, VALUE dummy)
{
return ST_DELETE;
}
+#endif
/*
* call-seq:
@@ -1652,6 +1656,7 @@
return Qfalse;
}
+#if !WITH_OBJC
static int
rb_hash_search_value(VALUE key, VALUE value, VALUE *data)
{
@@ -1662,6 +1667,7 @@
}
return ST_CONTINUE;
}
+#endif
/*
* call-seq:
@@ -1692,6 +1698,7 @@
#endif
}
+#if !WITH_OBJC
struct equal_data {
VALUE result;
st_table *tbl;
@@ -1727,12 +1734,11 @@
return data->result;
}
+#endif
static VALUE
hash_equal(VALUE hash1, VALUE hash2, int eql)
{
- struct equal_data data;
-
if (hash1 == hash2) return Qtrue;
if (TYPE(hash2) != T_HASH) {
if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
@@ -2079,8 +2085,8 @@
#else
RHASH(hash)->ntbl->type = &identhash;
rb_hash_rehash(hash);
+#endif
return hash;
-#endif
}
/*
@@ -2436,8 +2442,7 @@
long i;
RETURN_ENUMERATOR(ehash, 0, 0);
- rb_secure(4);
- keys = env_keys();
+ keys = env_keys(); /* rb_secure(4); */
for (i=0; i<RARRAY_LEN(keys); i++) {
rb_yield(RARRAY_AT(keys, i));
}
@@ -2467,12 +2472,11 @@
static VALUE
env_each_value(VALUE ehash)
{
- VALUE values = env_values();
+ VALUE values;
long i;
RETURN_ENUMERATOR(ehash, 0, 0);
- rb_secure(4);
- values = env_values();
+ values = env_values(); /* rb_secure(4); */
for (i=0; i<RARRAY_LEN(values); i++) {
rb_yield(RARRAY_AT(values, i));
}
@@ -2515,8 +2519,7 @@
int del = 0;
RETURN_ENUMERATOR(ehash, 0, 0);
- rb_secure(4);
- keys = env_keys();
+ keys = env_keys(); /* rb_secure(4); */
for (i=0; i<RARRAY_LEN(keys); i++) {
VALUE val = rb_f_getenv(Qnil, RARRAY_AT(keys, i));
if (!NIL_P(val)) {
@@ -2585,8 +2588,7 @@
volatile VALUE keys;
long i;
- rb_secure(4);
- keys = env_keys();
+ keys = env_keys(); /* rb_secure(4); */
for (i=0; i<RARRAY_LEN(keys); i++) {
VALUE val = rb_f_getenv(Qnil, RARRAY_AT(keys, i));
if (!NIL_P(val)) {
@@ -2868,8 +2870,7 @@
volatile VALUE keys;
long i;
- rb_secure(4);
- keys = env_keys();
+ keys = env_keys(); /* rb_secure(4); */
if (env == hash) return env;
hash = to_hash(hash);
rb_hash_foreach(hash, env_replace_i, keys);
Modified: MacRuby/trunk/id.c
===================================================================
--- MacRuby/trunk/id.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/id.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
id.c -
- $Author: akr $
+ $Author: ko1 $
created at: Thu Jul 12 04:37:51 2007
Copyright (C) 2004-2007 Koichi Sasada
@@ -63,4 +63,7 @@
idSend = rb_intern("send");
id__send__ = rb_intern("__send__");
+
+ idRespond_to = rb_intern("respond_to?");
+ idInitialize = rb_intern("initialize");
}
Modified: MacRuby/trunk/id.h
===================================================================
--- MacRuby/trunk/id.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/id.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -50,5 +50,6 @@
extern ID idAnswer;
extern ID idSend;
extern ID id__send__;
-
+extern ID idRespond_to;
+extern ID idInitialize;
#endif /* RUBY_ID_H */
Modified: MacRuby/trunk/include/ruby/defines.h
===================================================================
--- MacRuby/trunk/include/ruby/defines.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/include/ruby/defines.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -294,6 +294,7 @@
# include <CoreFoundation/CoreFoundation.h>
# define ASSERT_NO_OBJC() (assert(1 == 0))
void rb_objc_wb(void *dst, void *newval);
+void rb_objc_wb_range(void *dest, size_t len);
void rb_objc_root(void *addr);
# define GC_WB(dst, newval) (rb_objc_wb((void *)dst, (void *)newval))
# define GC_ROOT(dst) (rb_objc_root((void *)dst))
Modified: MacRuby/trunk/include/ruby/encoding.h
===================================================================
--- MacRuby/trunk/include/ruby/encoding.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/include/ruby/encoding.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -20,6 +20,8 @@
#if WITH_OBJC
+#include <wctype.h>
+
typedef CFStringEncoding rb_encoding;
#else
@@ -40,14 +42,14 @@
if (encoding_set_enc_index < ENCODING_INLINE_MAX) \
ENCODING_SET_INLINED(rb_encoding_set_obj, encoding_set_enc_index); \
else \
- rb_enc_internal_set_index(rb_encoding_set_obj, encoding_set_enc_index); \
+ rb_enc_set_index(rb_encoding_set_obj, encoding_set_enc_index); \
} while (0)
#define ENCODING_GET_INLINED(obj) ((RBASIC(obj)->flags & ENCODING_MASK)>>ENCODING_SHIFT)
#define ENCODING_GET(obj) \
(ENCODING_GET_INLINED(obj) != ENCODING_INLINE_MAX ? \
ENCODING_GET_INLINED(obj) : \
- rb_enc_internal_get_index(obj))
+ rb_enc_get_index(obj))
#if WITH_OBJC
# define ENCODING_IS_ASCII8BIT(obj) (1)
@@ -86,20 +88,18 @@
int rb_enc_replicate(const char *, rb_encoding *);
int rb_define_dummy_encoding(const char *);
-int rb_enc_dummy_p(rb_encoding *);
#define rb_enc_to_index(enc) ((enc) ? ((enc)->ruby_encoding_index) : 0)
int rb_enc_get_index(VALUE obj);
+void rb_enc_set_index(VALUE obj, int encindex);
int rb_enc_find_index(const char *name);
int rb_to_encoding_index(VALUE);
rb_encoding* rb_to_encoding(VALUE);
rb_encoding* rb_enc_get(VALUE);
rb_encoding* rb_enc_compatible(VALUE,VALUE);
rb_encoding* rb_enc_check(VALUE,VALUE);
-void rb_enc_associate_index(VALUE, int);
-void rb_enc_associate(VALUE, rb_encoding*);
+VALUE rb_enc_associate_index(VALUE, int);
+VALUE rb_enc_associate(VALUE, rb_encoding*);
void rb_enc_copy(VALUE dst, VALUE src);
-int rb_enc_internal_get_index(VALUE obj);
-void rb_enc_internal_set_index(VALUE obj, int encindex);
VALUE rb_enc_str_new(const char*, long, rb_encoding*);
VALUE rb_enc_reg_new(const char*, long, rb_encoding*, int);
@@ -192,7 +192,7 @@
#define rb_enc_isdigit(c,enc) ONIGENC_IS_CODE_DIGIT(enc,c)
#endif
-#define rb_enc_asciicompat(enc) (!rb_enc_dummy_p(enc) && rb_enc_mbminlen(enc)==1)
+#define rb_enc_asciicompat(enc) (rb_enc_mbminlen(enc)==1 && !rb_enc_dummy_p(enc))
int rb_enc_casefold(char *to, const char *p, const char *e, rb_encoding *enc);
int rb_enc_toupper(int c, rb_encoding *enc);
@@ -211,9 +211,33 @@
rb_encoding *rb_locale_encoding(void);
rb_encoding *rb_default_external_encoding(void);
int rb_usascii_encindex(void);
+int rb_ascii8bit_encindex(void);
VALUE rb_enc_default_external(void);
void rb_enc_set_default_external(VALUE encoding);
VALUE rb_locale_charmap(VALUE klass);
long rb_memsearch(const void*,long,const void*,long,rb_encoding*);
+RUBY_EXTERN VALUE rb_cEncoding;
+
+#define ENC_UNINITIALIZED (&rb_cEncoding)
+#define enc_initialized_p(enc) ((enc)->auxiliary_data != &rb_cEncoding)
+#define ENC_FROM_ENCODING(enc) ((VALUE)(enc)->auxiliary_data)
+
+#define ENC_DUMMY_FLAG FL_USER2
+#define ENC_DUMMY_P(enc) (RBASIC(enc)->flags & ENC_DUMMY_FLAG)
+#define ENC_SET_DUMMY(enc) (RBASIC(enc)->flags |= ENC_DUMMY_FLAG)
+
+#if WITH_OBJC
+# define rb_enc_dummy_p(x) (Qfalse)
+#else
+static inline int
+rb_enc_dummy_p(rb_encoding *enc)
+{
+ if (!enc_initialized_p(enc)) return Qfalse;
+ return ENC_DUMMY_P(ENC_FROM_ENCODING(enc));
+}
+#endif
+
+VALUE rb_str_transcode(VALUE str, VALUE to);
+
#endif /* RUBY_ENCODING_H */
Modified: MacRuby/trunk/include/ruby/intern.h
===================================================================
--- MacRuby/trunk/include/ruby/intern.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/include/ruby/intern.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
intern.h -
- $Author: usa $
+ $Author: nobu $
created at: Thu Jun 10 14:22:17 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -79,8 +79,6 @@
VALUE rb_get_values_at(VALUE, long, int, VALUE*, VALUE(*)(VALUE,long));
#if WITH_OBJC
VALUE rb_ary_elt(VALUE, long);
-void rb_ary_set_named_args(VALUE, bool);
-bool rb_ary_is_named_args(VALUE);
bool rb_objc_ary_is_pure(VALUE);
#endif
/* bignum.c */
@@ -346,6 +344,9 @@
void rb_objc_gc_unregister_thread(void);
void rb_objc_set_associative_ref(void *, void *, void *);
void *rb_objc_get_associative_ref(void *, void *);
+void rb_objc_retain(const void *);
+void rb_objc_release(const void *);
+void rb_gc_malloc_increase(size_t);
# define rb_gc_mark_locations(x,y)
# define rb_mark_tbl(x)
# define rb_mark_set(x)
@@ -617,7 +618,7 @@
VALUE rb_struct_s_members(VALUE);
VALUE rb_struct_members(VALUE);
VALUE rb_struct_alloc_noinit(VALUE);
-VALUE rb_struct_define_without_accessor(char *, VALUE, rb_alloc_func_t, ...);
+VALUE rb_struct_define_without_accessor(const char *, VALUE, rb_alloc_func_t, ...);
/* thread.c */
typedef void rb_unblock_function_t(void *);
typedef VALUE rb_blocking_function_t(void *);
@@ -693,10 +694,14 @@
VALUE rb_mod_objc_ib_outlet(int, VALUE *, VALUE);
VALUE rb_require_framework(int, VALUE *, VALUE);
VALUE rb_objc_resolve_const_value(VALUE, VALUE, ID);
-ID rb_objc_missing_sel(ID mid, int arity);
-void rb_objc_install_ivar_cluster(Class);
-void *rb_objc_get_ivar_cluster(void *);
-void rb_objc_set_ivar_cluster(void *, void *);
+ID rb_objc_missing_sel(ID, int);
+long rb_objc_flag_get_mask(const void *);
+void rb_objc_flag_set(const void *, int, bool);
+bool rb_objc_flag_check(const void *, int);
+long rb_objc_remove_flags(const void *obj);
+void rb_objc_sync_ruby_methods(VALUE, VALUE);
+void rb_objc_methods(VALUE, Class);
+bool rb_objc_is_immutable(VALUE);
#endif
/* version.c */
void ruby_show_version(void);
Added: MacRuby/trunk/include/ruby/mvm.h
===================================================================
--- MacRuby/trunk/include/ruby/mvm.h (rev 0)
+++ MacRuby/trunk/include/ruby/mvm.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,18 @@
+/**********************************************************************
+
+ ruby/mvm.h -
+
+ $Author: nobu $
+ created at: Sat May 31 15:17:36 2008
+
+ Copyright (C) 2008 Yukihiro Matsumoto
+
+**********************************************************************/
+
+#ifndef RUBY_MVM_H
+#define RUBY_MVM_H 1
+
+typedef struct rb_vm_struct rb_vm_t;
+typedef struct rb_thread_struct rb_thread_t;
+
+#endif /* RUBY_MVM_H */
Property changes on: MacRuby/trunk/include/ruby/mvm.h
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: MacRuby/trunk/include/ruby/node.h
===================================================================
--- MacRuby/trunk/include/ruby/node.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/include/ruby/node.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -425,9 +425,15 @@
#define NEW_DXSTR(s) NEW_NODE(NODE_DXSTR,s,0,0)
#define NEW_DSYM(s) NEW_NODE(NODE_DSYM,s,0,0)
#define NEW_EVSTR(n) NEW_NODE(NODE_EVSTR,0,(n),0)
-#define NEW_CALL(r,m,a) NEW_NODE(NODE_CALL,r,m,a)
-#define NEW_FCALL(m,a) NEW_NODE(NODE_FCALL,0,m,a)
-#define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0)
+#if WITH_OBJC
+# define NEW_CALL(r,m,a) process_named_args(NEW_NODE(NODE_CALL,r,m,a))
+# define NEW_FCALL(m,a) process_named_args(NEW_NODE(NODE_FCALL,0,m,a))
+# define NEW_VCALL(m) process_named_args(NEW_NODE(NODE_VCALL,0,m,0))
+#else
+# define NEW_CALL(r,m,a) NEW_NODE(NODE_CALL,r,m,a)
+# define NEW_FCALL(m,a) NEW_NODE(NODE_FCALL,0,m,a)
+# define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0)
+#endif
#define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a)
#define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0)
#define NEW_ARGS(m,o) NEW_NODE(NODE_ARGS,o,m,0)
Modified: MacRuby/trunk/include/ruby/ruby.h
===================================================================
--- MacRuby/trunk/include/ruby/ruby.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/include/ruby/ruby.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,18 +1,18 @@
/**********************************************************************
- ruby.h -
+ ruby/ruby.h -
- $Author: akr $
+ $Author: nobu $
created at: Thu Jun 10 14:26:32 JST 1993
- Copyright (C) 1993-2007 Yukihiro Matsumoto
+ Copyright (C) 1993-2008 Yukihiro Matsumoto
Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
Copyright (C) 2000 Information-technology Promotion Agency, Japan
**********************************************************************/
-#ifndef RUBY_H
-#define RUBY_H 1
+#ifndef RUBY_RUBY_H
+#define RUBY_RUBY_H 1
#if defined(__cplusplus)
extern "C" {
@@ -21,6 +21,7 @@
#endif
#endif
+#ifndef RUBY_LIB
#if RUBY_INCLUDED_AS_FRAMEWORK
#include <MacRuby/ruby/config.h>
#else
@@ -29,6 +30,7 @@
#ifdef RUBY_EXTCONF_H
#include RUBY_EXTCONF_H
#endif
+#endif
#define NORETURN_STYLE_NEW 1
#ifndef NORETURN
@@ -93,12 +95,24 @@
typedef unsigned long ID;
# define SIGNED_VALUE long
# define SIZEOF_VALUE SIZEOF_LONG
+# define PRIdVALUE "ld"
+# define PRIiVALUE "li"
+# define PRIoVALUE "lo"
+# define PRIuVALUE "lu"
+# define PRIxVALUE "lx"
+# define PRIXVALUE "lX"
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
typedef unsigned LONG_LONG VALUE;
typedef unsigned LONG_LONG ID;
# define SIGNED_VALUE LONG_LONG
# define LONG_LONG_VALUE 1
# define SIZEOF_VALUE SIZEOF_LONG_LONG
+# define PRIdVALUE "lld"
+# define PRIiVALUE "lli"
+# define PRIoVALUE "llo"
+# define PRIuVALUE "llu"
+# define PRIxVALUE "llx"
+# define PRIXVALUE "llX"
#else
# error ---->> ruby requires sizeof(void*) == sizeof(long) to be compiled. <<----
#endif
@@ -270,7 +284,6 @@
RUBY_T_SYMBOL = 0x14,
RUBY_T_FIXNUM = 0x15,
- RUBY_T_VALUES = 0x1a,
RUBY_T_UNDEF = 0x1b,
RUBY_T_NODE = 0x1c,
RUBY_T_ICLASS = 0x1d,
@@ -300,7 +313,6 @@
#define T_SYMBOL RUBY_T_SYMBOL
#define T_RATIONAL RUBY_T_RATIONAL
#define T_COMPLEX RUBY_T_COMPLEX
-#define T_VALUES RUBY_T_VALUES
#define T_UNDEF RUBY_T_UNDEF
#define T_NODE RUBY_T_NODE
#define T_MASK RUBY_T_MASK
@@ -460,13 +472,6 @@
RCLASS_IV_INDEX_TBL(rb_obj_class(o)) : \
ROBJECT(o)->as.heap.iv_index_tbl)
-struct RValues {
- struct RBasic basic;
- VALUE v1;
- VALUE v2;
- VALUE v3;
-};
-
typedef struct {
VALUE super;
struct st_table *iv_tbl;
@@ -852,8 +857,8 @@
rb_intern(str))
#endif
-char *rb_class2name(VALUE);
-char *rb_obj_classname(VALUE);
+const char *rb_class2name(VALUE);
+const char *rb_obj_classname(VALUE);
void rb_p(VALUE);
@@ -896,7 +901,7 @@
VALUE rb_each(VALUE);
VALUE rb_yield(VALUE);
VALUE rb_yield_values(int n, ...);
-VALUE rb_yield_values2(int n, VALUE *argv);
+VALUE rb_yield_values2(int n, const VALUE *argv);
VALUE rb_yield_splat(VALUE);
int rb_block_given_p(void);
void rb_need_block(void);
@@ -1198,4 +1203,4 @@
#endif
} /* extern "C" { */
#endif
-#endif /* RUBY_H */
+#endif /* RUBY_RUBY_H */
Modified: MacRuby/trunk/include/ruby/win32.h
===================================================================
--- MacRuby/trunk/include/ruby/win32.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/include/ruby/win32.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -546,6 +546,7 @@
size_t rb_w32_write(int, const void *, size_t);
int rb_w32_utime(const char *, const struct utimbuf *);
int WINAPI rb_w32_Sleep(unsigned long msec);
+int rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout);
/*
== ***CAUTION***
Modified: MacRuby/trunk/include/ruby.h
===================================================================
--- MacRuby/trunk/include/ruby.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/include/ruby.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -1 +1,21 @@
+/**********************************************************************
+
+ ruby/mvm.h -
+
+ $Author$
+ created at: Sun 10 12:06:15 Jun JST 2007
+
+ Copyright (C) 2007-2008 Yukihiro Matsumoto
+
+**********************************************************************/
+
+#ifndef RUBY_H
+#define RUBY_H 1
+
#include <ruby/ruby.h>
+#if RUBY_VM
+#include <ruby/mvm.h>
+#endif
+
+extern void ruby_set_debug_option(const char *);
+#endif /* RUBY_H */
Modified: MacRuby/trunk/insns.def
===================================================================
--- MacRuby/trunk/insns.def 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/insns.def 2008-06-05 08:11:58 UTC (rev 247)
@@ -183,7 +183,8 @@
()
(VALUE val)
{
- val = rb_cvar_get(vm_get_cvar_base(th, GET_ISEQ()), id);
+ NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ val = rb_cvar_get(vm_get_cvar_base(cref), id);
}
/**
@@ -197,7 +198,8 @@
(VALUE val)
()
{
- rb_cvar_set(vm_get_cvar_base(th, GET_ISEQ()), id, val);
+ NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ rb_cvar_set(vm_get_cvar_base(cref), id, val);
}
/**
@@ -317,7 +319,7 @@
()
(VALUE val)
{
- val = vm_get_cbase(th);
+ val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
}
/**
@@ -362,11 +364,10 @@
(VALUE val) // inc += 1 - num;
{
int i;
- VALUE v;
val = rb_str_new(0, 0);
for (i = num - 1; i >= 0; i--) {
- v = TOPN(i);
+ const VALUE v = TOPN(i);
rb_str_append(val, v);
}
POPN(num);
@@ -400,7 +401,7 @@
{
VALUE rb_reg_new_ary(VALUE ary, int options);
int i;
- VALUE ary = rb_ary_new2(cnt);
+ const VALUE ary = rb_ary_new2(cnt);
RBASIC(ary)->klass = 0;
for (i = 0; i < cnt; i++) {
rb_ary_store(ary, cnt-i-1, TOPN(i));
@@ -426,22 +427,6 @@
/**
@c put
- @e put new array, that contains named args (MacRuby only).
- @j n/a yet
- */
-DEFINE_INSN
-newarray_named_args
-(rb_num_t num)
-(...)
-(VALUE val) // inc += 1 - num;
-{
- val = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
- rb_ary_set_named_args(val, true);
- POPN(num);
-}
-
-/**
- @c put
@e dup array
@j \x94z\x97\xF1 ary \x82\xF0 dup \x82\xB5\x82ăX\x83^\x83b\x83N\x82Ƀv\x83b\x83V\x83\x85\x82\xB7\x82\xE9\x81B
*/
@@ -454,16 +439,6 @@
val = rb_ary_dup(ary);
}
-DEFINE_INSN
-duparray_named_args
-(VALUE ary)
-()
-(VALUE val)
-{
- val = rb_ary_dup(ary);
- rb_ary_set_named_args(val, true);
-}
-
/**
@c put
@e expand array to num objects.
@@ -496,7 +471,7 @@
(VALUE ary1, VALUE ary2st)
(VALUE ary)
{
- VALUE ary2 = ary2st;
+ const VALUE ary2 = ary2st;
VALUE tmp1 = rb_check_convert_type(ary1, T_ARRAY, "Array", "to_a");
VALUE tmp2 = rb_check_convert_type(ary2, T_ARRAY, "Array", "to_a");
@@ -585,12 +560,11 @@
(VALUE val) // inc += 1 - num;
{
int i;
- VALUE k, v;
val = rb_hash_new();
for (i = num; i > 0; i -= 2) {
- v = TOPN(i - 2);
- k = TOPN(i - 1);
+ const VALUE v = TOPN(i - 2);
+ const VALUE k = TOPN(i - 1);
rb_hash_aset(val, k, v);
}
POPN(num);
@@ -749,8 +723,8 @@
(VALUE obj)
()
{
- vm_define_method(th, obj, id, body, is_singleton,
- get_cref(GET_ISEQ(), GET_LFP()));
+ NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ vm_define_method(th, obj, id, body, is_singleton, cref);
}
/**
@@ -764,13 +738,11 @@
(VALUE sym1, VALUE sym2)
()
{
- VALUE klass;
-
if (v_p == Qtrue) {
rb_alias_variable(SYM2ID(sym1), SYM2ID(sym2));
}
else {
- klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss;
+ const VALUE klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
rb_alias(klass, SYM2ID(sym1), SYM2ID(sym2));
}
}
@@ -786,7 +758,7 @@
(VALUE sym)
()
{
- VALUE klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss;
+ const VALUE klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
rb_undef(klass, SYM2ID(sym));
INC_VM_STATE_VERSION();
}
@@ -803,7 +775,7 @@
(VALUE val)
{
VALUE klass;
- char *expr_type = 0;
+ const char *expr_type = 0;
val = Qnil;
switch (type) {
@@ -813,7 +785,7 @@
}
break;
case DEFINED_IVAR2:
- klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss;
+ klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
break;
case DEFINED_GVAR:
if (rb_gvar_defined((struct global_entry *)(obj & ~1))) {
@@ -821,7 +793,7 @@
}
break;
case DEFINED_CVAR:
- klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss;
+ klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
if (rb_cvar_defined(klass, SYM2ID(obj))) {
expr_type = "class variable";
}
@@ -1141,7 +1113,7 @@
{
if (OPT_CHECKED_RUN) {
if (reg_cfp->sp != reg_cfp->bp) {
- rb_bug("Stack consistency error (sp: %d, bp: %d)",
+ rb_bug("Stack consistency error (sp: %td, bp: %td)",
VM_SP_CNT(th, reg_cfp->sp), VM_SP_CNT(th, reg_cfp->bp));
}
}
@@ -1732,7 +1704,7 @@
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_LT)) {
- long a = FIX2LONG(recv), b = FIX2LONG(obj);
+ SIGNED_VALUE a = recv, b = obj;
if (a < b) {
val = Qtrue;
@@ -1761,7 +1733,7 @@
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_LE)) {
- long a = FIX2LONG(recv), b = FIX2LONG(obj);
+ SIGNED_VALUE a = recv, b = obj;
if (a <= b) {
val = Qtrue;
@@ -1791,7 +1763,7 @@
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_GT)) {
- long a = FIX2LONG(recv), b = FIX2LONG(obj);
+ SIGNED_VALUE a = recv, b = obj;
if (a > b) {
val = Qtrue;
@@ -1820,7 +1792,7 @@
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_GE)) {
- long a = FIX2LONG(recv), b = FIX2LONG(obj);
+ SIGNED_VALUE a = recv, b = obj;
if (a >= b) {
val = Qtrue;
Modified: MacRuby/trunk/io.c
===================================================================
--- MacRuby/trunk/io.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/io.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
io.c -
- $Author: akr $
+ $Author: mame $
created at: Fri Oct 15 18:08:59 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -271,6 +271,7 @@
rb_io_get_write_io(VALUE io)
{
VALUE write_io;
+ rb_io_check_initialized(RFILE(io)->fptr);
write_io = RFILE(io)->fptr->tied_io_for_writing;
if (write_io) {
return write_io;
@@ -1388,9 +1389,9 @@
{
long bytes = 0;
long n;
+#if !WITH_OBJC
long pos = 0;
rb_encoding *enc = io_input_encoding(fptr);
-#if !WITH_OBJC
int cr = fptr->enc2 ? ENC_CODERANGE_BROKEN : 0;
#endif
@@ -1746,7 +1747,9 @@
const char *p = READ_DATA_PENDING_PTR(fptr);
const char *e;
long last = 0, len = (c != EOF);
+#if !WITH_OBJC
rb_encoding *enc = io_read_encoding(fptr);
+#endif
if (limit > 0 && pending > limit) pending = limit;
e = memchr(p, delim, pending);
@@ -1849,9 +1852,9 @@
{
VALUE str = Qnil;
int len = 0;
+#if !WITH_OBJC
long pos = 0;
rb_encoding *enc = io_input_encoding(fptr);
-#if !WITH_OBJC
int cr = fptr->enc2 ? ENC_CODERANGE_BROKEN : 0;
#endif
@@ -1904,7 +1907,9 @@
prepare_getline_args(int argc, VALUE *argv, VALUE *rsp, long *limit, VALUE io)
{
VALUE lim, rs;
+#if !WITH_OBJC
rb_io_t *fptr;
+#endif
if (argc == 0) {
rs = rb_rs;
@@ -2006,7 +2011,7 @@
while ((c = appendline(fptr, newline, &str, &limit)) != EOF) {
if (c == newline) {
- const char *s, *p, *pp;
+ const char *s, *p;
if (RSTRING_LEN(str) < rslen) continue;
s = RSTRING_PTR(str);
@@ -2287,7 +2292,9 @@
static VALUE
io_getc(rb_io_t *fptr, rb_encoding *enc)
{
+#if !WITH_OBJC
int r, n, cr = 0;
+#endif
VALUE str;
if (io_fillbuf(fptr) < 0) {
@@ -2472,9 +2479,7 @@
{
int c;
- if (!STDIO_READ_DATA_PENDING(f)) {
- rb_thread_wait_fd(fileno(f));
- }
+ rb_read_check(f);
TRAP_BEG;
c = getc(f);
TRAP_END;
@@ -5180,7 +5185,9 @@
static void
argf_mark(void *ptr)
{
+#if !WITH_OBJC
struct argf *p = ptr;
+#endif
rb_gc_mark(p->filename);
rb_gc_mark(p->current_file);
rb_gc_mark(p->lineno);
@@ -6440,9 +6447,9 @@
int close_src;
int close_dst;
off_t total;
- char *syserr;
+ const char *syserr;
int error_no;
- char *notimp;
+ const char *notimp;
rb_fdset_t fds;
rb_thread_t *th;
};
@@ -7037,13 +7044,19 @@
static VALUE
argf_external_encoding(VALUE argf)
{
- return rb_io_external_encoding(current_file);
+ if (!RTEST(current_file)) {
+ return rb_enc_from_encoding(rb_default_external_encoding());
+ }
+ return rb_io_external_encoding(rb_io_check_io(current_file));
}
static VALUE
argf_internal_encoding(VALUE argf)
{
- return rb_io_internal_encoding(current_file);
+ if (!RTEST(current_file)) {
+ return rb_enc_from_encoding(rb_default_external_encoding());
+ }
+ return rb_io_internal_encoding(rb_io_check_io(current_file));
}
static VALUE
@@ -7282,7 +7295,7 @@
VALUE ch;
retry:
- if (!next_argv()) return Qnil;
+ if (!next_argv()) rb_eof_error();
if (TYPE(current_file) != T_FILE) {
ch = rb_funcall3(current_file, rb_intern("getc"), 0, 0);
}
@@ -7743,6 +7756,9 @@
rb_define_method(rb_cARGF, "each_line", argf_each_line, -1);
rb_define_method(rb_cARGF, "each_byte", argf_each_byte, 0);
rb_define_method(rb_cARGF, "each_char", argf_each_char, 0);
+ rb_define_method(rb_cARGF, "lines", argf_each_line, -1);
+ rb_define_method(rb_cARGF, "bytes", argf_each_byte, 0);
+ rb_define_method(rb_cARGF, "chars", argf_each_char, 0);
rb_define_method(rb_cARGF, "read", argf_read, -1);
rb_define_method(rb_cARGF, "readpartial", argf_readpartial, -1);
Modified: MacRuby/trunk/iseq.c
===================================================================
--- MacRuby/trunk/iseq.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/iseq.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
iseq.c -
- $Author: ko1 $
+ $Author: nobu $
created at: 2006-07-11(Tue) 09:00:03 +0900
Copyright (C) 2006 Koichi Sasada
@@ -184,7 +184,6 @@
(struct iseq_compile_data_storage *)
ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE +
sizeof(struct iseq_compile_data_storage));
- GC_WB(&iseq->compile_data->storage_head, iseq->compile_data->storage_head);
GC_WB(&iseq->compile_data->catch_table_ary, rb_ary_new());
iseq->compile_data->storage_head->pos = 0;
@@ -394,6 +393,7 @@
st_insert(type_map, ID2SYM(rb_intern("rescue")), ISEQ_TYPE_RESCUE);
st_insert(type_map, ID2SYM(rb_intern("ensure")), ISEQ_TYPE_ENSURE);
st_insert(type_map, ID2SYM(rb_intern("eval")), ISEQ_TYPE_EVAL);
+ st_insert(type_map, ID2SYM(rb_intern("defined_guard")), ISEQ_TYPE_DEFINED_GUARD);
}
if (st_lookup(type_map, type, &iseq_type) == 0) {
@@ -448,7 +448,7 @@
rb_thread_t *th = GET_THREAD();
make_compile_option(&option, opt);
- if (th->base_block) {
+ if (th->base_block && th->base_block->iseq) {
return rb_iseq_new_with_opt(node, th->base_block->iseq->name,
file, th->base_block->iseq->self,
ISEQ_TYPE_EVAL, &option);
@@ -779,7 +779,7 @@
return len;
}
-static char *
+static const char *
catch_type(int type)
{
switch (type) {
@@ -1007,6 +1007,7 @@
DECL_SYMBOL(rescue);
DECL_SYMBOL(ensure);
DECL_SYMBOL(eval);
+ DECL_SYMBOL(defined_guard);
if (sym_top == 0) {
int i;
@@ -1020,6 +1021,7 @@
INIT_SYMBOL(rescue);
INIT_SYMBOL(ensure);
INIT_SYMBOL(eval);
+ INIT_SYMBOL(defined_guard);
}
/* type */
@@ -1031,6 +1033,7 @@
case ISEQ_TYPE_RESCUE: type = sym_rescue; break;
case ISEQ_TYPE_ENSURE: type = sym_ensure; break;
case ISEQ_TYPE_EVAL: type = sym_eval; break;
+ case ISEQ_TYPE_DEFINED_GUARD: type = sym_defined_guard; break;
default: rb_bug("unsupported iseq type");
};
@@ -1306,6 +1309,7 @@
/* disable this feature because there is no verifier. */
/* rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1); */
+ (void)iseq_s_load;
rb_define_singleton_method(rb_cISeq, "compile", iseq_s_compile, -1);
rb_define_singleton_method(rb_cISeq, "new", iseq_s_compile, -1);
Modified: MacRuby/trunk/keywords
===================================================================
--- MacRuby/trunk/keywords 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/keywords 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,5 +1,5 @@
%{
-struct kwtable {char *name; int id[2]; enum lex_state_e state;};
+struct kwtable {const char *name; int id[2]; enum lex_state_e state;};
const struct kwtable *rb_reserved_word(const char *, unsigned int);
#ifndef RIPPER
%}
Modified: MacRuby/trunk/lex.c.blt
===================================================================
--- MacRuby/trunk/lex.c.blt 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lex.c.blt 2008-06-05 08:11:58 UTC (rev 247)
@@ -30,7 +30,7 @@
#line 1 "keywords"
-struct kwtable {char *name; int id[2]; enum lex_state_e state;};
+struct kwtable {const char *name; int id[2]; enum lex_state_e state;};
const struct kwtable *rb_reserved_word(const char *, unsigned int);
#ifndef RIPPER
#line 7 "keywords"
Modified: MacRuby/trunk/lex.c.src
===================================================================
--- MacRuby/trunk/lex.c.src 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lex.c.src 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,5 +1,5 @@
%{
-struct kwtable {char *name; int id[2]; enum lex_state_e state;};
+struct kwtable {const char *name; int id[2]; enum lex_state_e state;};
const struct kwtable *rb_reserved_word(const char *, unsigned int);
#ifndef RIPPER
%}
Added: MacRuby/trunk/lib/cmath.rb
===================================================================
--- MacRuby/trunk/lib/cmath.rb (rev 0)
+++ MacRuby/trunk/lib/cmath.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,223 @@
+module CMath
+
+ include Math
+
+ alias exp! exp
+ alias log! log
+ alias log10! log10
+ alias sqrt! sqrt
+
+ alias sin! sin
+ alias cos! cos
+ alias tan! tan
+
+ alias sinh! sinh
+ alias cosh! cosh
+ alias tanh! tanh
+
+ alias asin! asin
+ alias acos! acos
+ alias atan! atan
+ alias atan2! atan2
+
+ alias asinh! asinh
+ alias acosh! acosh
+ alias atanh! atanh
+
+ def exp(z)
+ if Complex.generic?(z)
+ exp!(z)
+ else
+ Complex(exp!(z.real) * cos!(z.image),
+ exp!(z.real) * sin!(z.image))
+ end
+ end
+
+ def log(*args)
+ z, b = args
+ if Complex.generic?(z) and z >= 0 and (b.nil? or b >= 0)
+ log!(*args)
+ else
+ r, theta = z.polar
+ a = Complex(log!(r.abs), theta)
+ if b
+ a /= log(b)
+ end
+ a
+ end
+ end
+
+ def log10(z)
+ if Complex.generic?(z)
+ log10!(z)
+ else
+ log(z) / log!(10)
+ end
+ end
+
+ def sqrt(z)
+ if Complex.generic?(z)
+ if z >= 0
+ sqrt!(z)
+ else
+ Complex(0,sqrt!(-z))
+ end
+ else
+ if z.image < 0
+ sqrt(z.conjugate).conjugate
+ else
+ r = z.abs
+ x = z.real
+ Complex(sqrt!((r + x) / 2), sqrt!((r - x) / 2))
+ end
+ end
+ end
+
+ def sin(z)
+ if Complex.generic?(z)
+ sin!(z)
+ else
+ Complex(sin!(z.real) * cosh!(z.image),
+ cos!(z.real) * sinh!(z.image))
+ end
+ end
+
+ def cos(z)
+ if Complex.generic?(z)
+ cos!(z)
+ else
+ Complex(cos!(z.real) * cosh!(z.image),
+ -sin!(z.real) * sinh!(z.image))
+ end
+ end
+
+ def tan(z)
+ if Complex.generic?(z)
+ tan!(z)
+ else
+ sin(z)/cos(z)
+ end
+ end
+
+ def sinh(z)
+ if Complex.generic?(z)
+ sinh!(z)
+ else
+ Complex(sinh!(z.real) * cos!(z.image),
+ cosh!(z.real) * sin!(z.image))
+ end
+ end
+
+ def cosh(z)
+ if Complex.generic?(z)
+ cosh!(z)
+ else
+ Complex(cosh!(z.real) * cos!(z.image),
+ sinh!(z.real) * sin!(z.image))
+ end
+ end
+
+ def tanh(z)
+ if Complex.generic?(z)
+ tanh!(z)
+ else
+ sinh(z) / cosh(z)
+ end
+ end
+
+ def asin(z)
+ if Complex.generic?(z) and z >= -1 and z <= 1
+ asin!(z)
+ else
+ -1.0.im * log(1.0.im * z + sqrt(1.0 - z * z))
+ end
+ end
+
+ def acos(z)
+ if Complex.generic?(z) and z >= -1 and z <= 1
+ acos!(z)
+ else
+ -1.0.im * log(z + 1.0.im * sqrt(1.0 - z * z))
+ end
+ end
+
+ def atan(z)
+ if Complex.generic?(z)
+ atan!(z)
+ else
+ 1.0.im * log((1.0.im + z) / (1.0.im - z)) / 2.0
+ end
+ end
+
+ def atan2(y,x)
+ if Complex.generic?(y) and Complex.generic?(x)
+ atan2!(y,x)
+ else
+ -1.0.im * log((x + 1.0.im * y) / sqrt(x * x + y * y))
+ end
+ end
+
+ def acosh(z)
+ if Complex.generic?(z) and z >= 1
+ acosh!(z)
+ else
+ log(z + sqrt(z * z - 1.0))
+ end
+ end
+
+ def asinh(z)
+ if Complex.generic?(z)
+ asinh!(z)
+ else
+ log(z + sqrt(1.0 + z * z))
+ end
+ end
+
+ def atanh(z)
+ if Complex.generic?(z) and z >= -1 and z <= 1
+ atanh!(z)
+ else
+ log((1.0 + z) / (1.0 - z)) / 2.0
+ end
+ end
+
+ module_function :exp!
+ module_function :exp
+ module_function :log!
+ module_function :log
+ module_function :log10!
+ module_function :log10
+ module_function :sqrt!
+ module_function :sqrt
+
+ module_function :sin!
+ module_function :sin
+ module_function :cos!
+ module_function :cos
+ module_function :tan!
+ module_function :tan
+
+ module_function :sinh!
+ module_function :sinh
+ module_function :cosh!
+ module_function :cosh
+ module_function :tanh!
+ module_function :tanh
+
+ module_function :asin!
+ module_function :asin
+ module_function :acos!
+ module_function :acos
+ module_function :atan!
+ module_function :atan
+ module_function :atan2!
+ module_function :atan2
+
+ module_function :asinh!
+ module_function :asinh
+ module_function :acosh!
+ module_function :acosh
+ module_function :atanh!
+ module_function :atanh
+
+end
Modified: MacRuby/trunk/lib/delegate.rb
===================================================================
--- MacRuby/trunk/lib/delegate.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/delegate.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -153,9 +153,9 @@
# Checks for a method provided by this the delegate object by fowarding the
# call through \_\_getobj\_\_.
#
- def respond_to?(m)
+ def respond_to?(m, include_private = false)
return true if super
- return self.__getobj__.respond_to?(m)
+ return self.__getobj__.respond_to?(m, include_private)
end
#
Modified: MacRuby/trunk/lib/erb.rb
===================================================================
--- MacRuby/trunk/lib/erb.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/erb.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -236,7 +236,7 @@
# Rails, the web application framework, uses ERB to create views.
#
class ERB
- Revision = '$Date:: 2008-04-30 05:40:52 -0700#$' #'
+ Revision = '$Date:: 2008-06-02 00:15:12 -0700#$' #'
# Returns revision information for the erb.rb module.
def self.version
Deleted: MacRuby/trunk/lib/generator.rb
===================================================================
--- MacRuby/trunk/lib/generator.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/generator.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,385 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# $Idaemons: /home/cvs/rb/generator.rb,v 1.8 2001/10/03 08:54:32 knu Exp $
-# $RoughId: generator.rb,v 1.10 2003/10/14 19:36:58 knu Exp $
-# $Id: generator.rb 11708 2007-02-12 23:01:19Z shyouhei $
-#++
-#
-# = generator.rb: convert an internal iterator to an external one
-#
-# Copyright (c) 2001,2003 Akinori MUSHA <knu at iDaemons.org>
-#
-# All rights reserved. You can redistribute and/or modify it under
-# the same terms as Ruby.
-#
-# == Overview
-#
-# This library provides the Generator class, which converts an
-# internal iterator (i.e. an Enumerable object) to an external
-# iterator. In that form, you can roll many iterators independently.
-#
-# The SyncEnumerator class, which is implemented using Generator,
-# makes it easy to roll many Enumerable objects synchronously.
-#
-# See the respective classes for examples of usage.
-
-
-#
-# Generator converts an internal iterator (i.e. an Enumerable object)
-# to an external iterator.
-#
-# == Example
-#
-# require 'generator'
-#
-# # Generator from an Enumerable object
-# g = Generator.new(['A', 'B', 'C', 'Z'])
-#
-# while g.next?
-# puts g.next
-# end
-#
-# # Generator from a block
-# g = Generator.new { |g|
-# for i in 'A'..'C'
-# g.yield i
-# end
-#
-# g.yield 'Z'
-# }
-#
-# # The same result as above
-# while g.next?
-# puts g.next
-# end
-#
-class Generator
- include Enumerable
-
- # Creates a new generator either from an Enumerable object or from a
- # block.
- #
- # In the former, block is ignored even if given.
- #
- # In the latter, the given block is called with the generator
- # itself, and expected to call the +yield+ method for each element.
- def initialize(enum = nil, &block)
- if enum
- @block = proc{|g| enum.each{|value| g.yield value}}
- else
- @block = block
- end
- @index = 0
- @queue = []
- @main_thread = nil
- @loop_thread.kill if defined?(@loop_thread)
- @loop_thread = Thread.new do
- Thread.stop
- begin
- @block.call(self)
- rescue
- @main_thread.raise $!
- ensure
- @main_thread.wakeup
- end
- end
- Thread.pass until @loop_thread.stop?
- self
- end
-
- # Yields an element to the generator.
- def yield(value)
- if Thread.current != @loop_thread
- raise "should be called in Generator.new{|g| ... }"
- end
- Thread.critical = true
- begin
- @queue << value
- @main_thread.wakeup
- Thread.stop
- ensure
- Thread.critical = false
- end
- self
- end
-
- # Returns true if the generator has reached the end.
- def end?
- if @queue.empty?
- if @main_thread
- raise "should not be called in Generator.new{|g| ... }"
- end
- Thread.critical = true
- begin
- @main_thread = Thread.current
- @loop_thread.wakeup
- Thread.stop
- rescue ThreadError
- # ignore
- ensure
- @main_thread = nil
- Thread.critical = false
- end
- end
- @queue.empty?
- end
-
- # Returns true if the generator has not reached the end yet.
- def next?
- !end?
- end
-
- # Returns the current index (position) counting from zero.
- def index
- @index
- end
-
- # Returns the current index (position) counting from zero.
- def pos
- @index
- end
-
- # Returns the element at the current position and moves forward.
- def next
- raise EOFError.new("no more elements available") if end?
- @index += 1
- @queue.shift
- end
-
- # Returns the element at the current position.
- def current
- raise EOFError.new("no more elements available") if end?
- @queue.first
- end
-
- # Rewinds the generator.
- def rewind
- initialize(nil, &@block) if @index.nonzero?
- self
- end
-
- # Rewinds the generator and enumerates the elements.
- def each
- rewind
- until end?
- yield self.next
- end
- self
- end
-end
-
-#
-# SyncEnumerator creates an Enumerable object from multiple Enumerable
-# objects and enumerates them synchronously.
-#
-# == Example
-#
-# require 'generator'
-#
-# s = SyncEnumerator.new([1,2,3], ['a', 'b', 'c'])
-#
-# # Yields [1, 'a'], [2, 'b'], and [3,'c']
-# s.each { |row| puts row.join(', ') }
-#
-class SyncEnumerator
- include Enumerable
-
- # Creates a new SyncEnumerator which enumerates rows of given
- # Enumerable objects.
- def initialize(*enums)
- @gens = enums.map { |e| Generator.new(e) }
- end
-
- # Returns the number of enumerated Enumerable objects, i.e. the size
- # of each row.
- def size
- @gens.size
- end
-
- # Returns the number of enumerated Enumerable objects, i.e. the size
- # of each row.
- def length
- @gens.length
- end
-
- # Returns true if the given nth Enumerable object has reached the
- # end. If no argument is given, returns true if any of the
- # Enumerable objects has reached the end.
- def end?(i = nil)
- if i.nil?
- @gens.detect { |g| g.end? } ? true : false
- else
- @gens[i].end?
- end
- end
-
- # Enumerates rows of the Enumerable objects.
- def each
- @gens.each { |g| g.rewind }
-
- loop do
- count = 0
-
- ret = @gens.map { |g|
- if g.end?
- count += 1
- nil
- else
- g.next
- end
- }
-
- if count == @gens.size
- break
- end
-
- yield ret
- end
-
- self
- end
-end
-
-if $0 == __FILE__
- eval DATA.read, nil, $0, __LINE__+4
-end
-
-__END__
-
-__END__
-
-require 'test/unit'
-
-class TC_Generator < Test::Unit::TestCase
- def test_block1
- g = Generator.new { |g|
- # no yield's
- }
-
- assert_equal(0, g.pos)
- assert_raises(EOFError) { g.current }
- end
-
- def test_block2
- g = Generator.new { |g|
- for i in 'A'..'C'
- g.yield i
- end
-
- g.yield 'Z'
- }
-
- assert_equal(0, g.pos)
- assert_equal('A', g.current)
-
- assert_equal(true, g.next?)
- assert_equal(0, g.pos)
- assert_equal('A', g.current)
- assert_equal(0, g.pos)
- assert_equal('A', g.next)
-
- assert_equal(1, g.pos)
- assert_equal(true, g.next?)
- assert_equal(1, g.pos)
- assert_equal('B', g.current)
- assert_equal(1, g.pos)
- assert_equal('B', g.next)
-
- assert_equal(g, g.rewind)
-
- assert_equal(0, g.pos)
- assert_equal('A', g.current)
-
- assert_equal(true, g.next?)
- assert_equal(0, g.pos)
- assert_equal('A', g.current)
- assert_equal(0, g.pos)
- assert_equal('A', g.next)
-
- assert_equal(1, g.pos)
- assert_equal(true, g.next?)
- assert_equal(1, g.pos)
- assert_equal('B', g.current)
- assert_equal(1, g.pos)
- assert_equal('B', g.next)
-
- assert_equal(2, g.pos)
- assert_equal(true, g.next?)
- assert_equal(2, g.pos)
- assert_equal('C', g.current)
- assert_equal(2, g.pos)
- assert_equal('C', g.next)
-
- assert_equal(3, g.pos)
- assert_equal(true, g.next?)
- assert_equal(3, g.pos)
- assert_equal('Z', g.current)
- assert_equal(3, g.pos)
- assert_equal('Z', g.next)
-
- assert_equal(4, g.pos)
- assert_equal(false, g.next?)
- assert_raises(EOFError) { g.next }
- end
-
- def test_each
- a = [5, 6, 7, 8, 9]
-
- g = Generator.new(a)
-
- i = 0
-
- g.each { |x|
- assert_equal(a[i], x)
-
- i += 1
-
- break if i == 3
- }
-
- assert_equal(3, i)
-
- i = 0
-
- g.each { |x|
- assert_equal(a[i], x)
-
- i += 1
- }
-
- assert_equal(5, i)
- end
-end
-
-class TC_SyncEnumerator < Test::Unit::TestCase
- def test_each
- r = ['a'..'f', 1..10, 10..20]
- ra = r.map { |x| x.to_a }
-
- a = (0...(ra.map {|x| x.size}.max)).map { |i| ra.map { |x| x[i] } }
-
- s = SyncEnumerator.new(*r)
-
- i = 0
-
- s.each { |x|
- assert_equal(a[i], x)
-
- i += 1
-
- break if i == 3
- }
-
- assert_equal(3, i)
-
- i = 0
-
- s.each { |x|
- assert_equal(a[i], x)
-
- i += 1
- }
-
- assert_equal(a.size, i)
- end
-end
Modified: MacRuby/trunk/lib/net/imap.rb
===================================================================
--- MacRuby/trunk/lib/net/imap.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/net/imap.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -936,6 +936,7 @@
@continuation_request_arrival = new_cond
@logout_command_tag = nil
@debug_output_bol = true
+ @exception = nil
@greeting = get_response
if @greeting.name == "BYE"
@@ -951,14 +952,24 @@
def receive_responses
while true
+ synchronize do
+ @exception = nil
+ end
begin
resp = get_response
- rescue Exception
- @sock.close
- @client_thread.raise($!)
+ rescue Exception => e
+ synchronize do
+ @sock.close
+ @exception = e
+ end
break
end
- break unless resp
+ unless resp
+ synchronize do
+ @exception = EOFError.new("end of file reached")
+ end
+ break
+ end
begin
synchronize do
case resp
@@ -976,7 +987,8 @@
end
if resp.name == "BYE" && @logout_command_tag.nil?
@sock.close
- raise ByeResponseError, resp.raw_data
+ @exception = ByeResponseError.new(resp.raw_data)
+ break
end
when ContinuationRequest
@continuation_request_arrival.signal
@@ -985,14 +997,23 @@
handler.call(resp)
end
end
- rescue Exception
- @client_thread.raise($!)
+ rescue Exception => e
+ @exception = e
+ synchronize do
+ @tagged_response_arrival.broadcast
+ @continuation_request_arrival.broadcast
+ end
end
end
+ synchronize do
+ @tagged_response_arrival.broadcast
+ @continuation_request_arrival.broadcast
+ end
end
def get_tagged_response(tag, cmd)
until @tagged_responses.key?(tag)
+ raise @exception if @exception
@tagged_response_arrival.wait
end
resp = @tagged_responses.delete(tag)
@@ -1119,6 +1140,7 @@
def send_literal(str)
put_string("{" + str.length.to_s + "}" + CRLF)
@continuation_request_arrival.wait
+ raise @exception if @exception
put_string(str)
end
Deleted: MacRuby/trunk/lib/require_relative.rb
===================================================================
--- MacRuby/trunk/lib/require_relative.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/require_relative.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,11 +0,0 @@
-def require_relative(relative_feature)
- c = caller.first
- e = c.rindex(/:\d+:in /)
- file = $`
- if /\A\((.*)\)/ =~ file # eval, etc.
- raise LoadError, "require_relative is called in #{$1}"
- end
- absolute_feature = File.expand_path(File.join(File.dirname(file), relative_feature))
- require absolute_feature
-end
-
Deleted: MacRuby/trunk/lib/rubygems/gem_open_uri.rb
===================================================================
--- MacRuby/trunk/lib/rubygems/gem_open_uri.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/rubygems/gem_open_uri.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,7 +0,0 @@
-#!/usr/bin/env ruby
-
-if RUBY_VERSION > '1.9' then
- require 'open-uri'
-else
- require 'rubygems/open-uri'
-end
Deleted: MacRuby/trunk/lib/rubygems/open-uri.rb
===================================================================
--- MacRuby/trunk/lib/rubygems/open-uri.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/rubygems/open-uri.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,773 +0,0 @@
-require 'uri'
-require 'stringio'
-require 'time'
-
-# :stopdoc:
-module Kernel
- private
- alias rubygems_open_uri_original_open open # :nodoc:
-
- # makes possible to open various resources including URIs.
- # If the first argument respond to `open' method,
- # the method is called with the rest arguments.
- #
- # If the first argument is a string which begins with xxx://,
- # it is parsed by URI.parse. If the parsed object respond to `open' method,
- # the method is called with the rest arguments.
- #
- # Otherwise original open is called.
- #
- # Since open-uri.rb provides URI::HTTP#open, URI::HTTPS#open and
- # URI::FTP#open,
- # Kernel[#.]open can accepts such URIs and strings which begins with
- # http://, https:// and ftp://.
- # In these case, the opened file object is extended by OpenURI::Meta.
- def open(name, *rest, &block) # :doc:
- if name.respond_to?(:open)
- name.open(*rest, &block)
- elsif name.respond_to?(:to_str) &&
- %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
- (uri = URI.parse(name)).respond_to?(:open)
- uri.open(*rest, &block)
- else
- rubygems_open_uri_original_open(name, *rest, &block)
- end
- end
- module_function :open
-end
-
-# OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp.
-#
-#== Example
-#
-# It is possible to open http/https/ftp URL as usual like opening a file:
-#
-# open("http://www.ruby-lang.org/") {|f|
-# f.each_line {|line| p line}
-# }
-#
-# The opened file has several methods for meta information as follows since
-# it is extended by OpenURI::Meta.
-#
-# open("http://www.ruby-lang.org/en") {|f|
-# f.each_line {|line| p line}
-# p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
-# p f.content_type # "text/html"
-# p f.charset # "iso-8859-1"
-# p f.content_encoding # []
-# p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
-# }
-#
-# Additional header fields can be specified by an optional hash argument.
-#
-# open("http://www.ruby-lang.org/en/",
-# "User-Agent" => "Ruby/#{RUBY_VERSION}",
-# "From" => "foo at bar.invalid",
-# "Referer" => "http://www.ruby-lang.org/") {|f|
-# # ...
-# }
-#
-# The environment variables such as http_proxy, https_proxy and ftp_proxy
-# are in effect by default. :proxy => nil disables proxy.
-#
-# open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f|
-# # ...
-# }
-#
-# URI objects can be opened in a similar way.
-#
-# uri = URI.parse("http://www.ruby-lang.org/en/")
-# uri.open {|f|
-# # ...
-# }
-#
-# URI objects can be read directly. The returned string is also extended by
-# OpenURI::Meta.
-#
-# str = uri.read
-# p str.base_uri
-#
-# Author:: Tanaka Akira <akr at m17n.org>
-
-module OpenURI
- Options = {
- :proxy => true,
- :proxy_http_basic_authentication => true,
- :progress_proc => true,
- :content_length_proc => true,
- :http_basic_authentication => true,
- :read_timeout => true,
- :ssl_ca_cert => nil,
- :ssl_verify_mode => nil,
- }
-
- def OpenURI.check_options(options) # :nodoc:
- options.each {|k, v|
- next unless Symbol === k
- unless Options.include? k
- raise ArgumentError, "unrecognized option: #{k}"
- end
- }
- end
-
- def OpenURI.scan_open_optional_arguments(*rest) # :nodoc:
- if !rest.empty? && (String === rest.first || Integer === rest.first)
- mode = rest.shift
- if !rest.empty? && Integer === rest.first
- perm = rest.shift
- end
- end
- return mode, perm, rest
- end
-
- def OpenURI.open_uri(name, *rest) # :nodoc:
- uri = URI::Generic === name ? name : URI.parse(name)
- mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest)
- options = rest.shift if !rest.empty? && Hash === rest.first
- raise ArgumentError.new("extra arguments") if !rest.empty?
- options ||= {}
- OpenURI.check_options(options)
-
- unless mode == nil ||
- mode == 'r' || mode == 'rb' ||
- mode == File::RDONLY
- raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
- end
-
- io = open_loop(uri, options)
- if block_given?
- begin
- yield io
- ensure
- io.close
- end
- else
- io
- end
- end
-
- def OpenURI.open_loop(uri, options) # :nodoc:
- proxy_opts = []
- proxy_opts << :proxy_http_basic_authentication if options.include? :proxy_http_basic_authentication
- proxy_opts << :proxy if options.include? :proxy
- proxy_opts.compact!
- if 1 < proxy_opts.length
- raise ArgumentError, "multiple proxy options specified"
- end
- case proxy_opts.first
- when :proxy_http_basic_authentication
- opt_proxy, proxy_user, proxy_pass = options.fetch(:proxy_http_basic_authentication)
- proxy_user = proxy_user.to_str
- proxy_pass = proxy_pass.to_str
- if opt_proxy == true
- raise ArgumentError.new("Invalid authenticated proxy option: #{options[:proxy_http_basic_authentication].inspect}")
- end
- when :proxy
- opt_proxy = options.fetch(:proxy)
- proxy_user = nil
- proxy_pass = nil
- when nil
- opt_proxy = true
- proxy_user = nil
- proxy_pass = nil
- end
- case opt_proxy
- when true
- find_proxy = lambda {|u| pxy = u.find_proxy; pxy ? [pxy, nil, nil] : nil}
- when nil, false
- find_proxy = lambda {|u| nil}
- when String
- opt_proxy = URI.parse(opt_proxy)
- find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
- when URI::Generic
- find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
- else
- raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
- end
-
- uri_set = {}
- buf = nil
- while true
- redirect = catch(:open_uri_redirect) {
- buf = Buffer.new
- uri.buffer_open(buf, find_proxy.call(uri), options)
- nil
- }
- if redirect
- if redirect.relative?
- # Although it violates RFC2616, Location: field may have relative
- # URI. It is converted to absolute URI using uri as a base URI.
- redirect = uri + redirect
- end
- unless OpenURI.redirectable?(uri, redirect)
- raise "redirection forbidden: #{uri} -> #{redirect}"
- end
- if options.include? :http_basic_authentication
- # send authentication only for the URI directly specified.
- options = options.dup
- options.delete :http_basic_authentication
- end
- uri = redirect
- raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
- uri_set[uri.to_s] = true
- else
- break
- end
- end
- io = buf.io
- io.base_uri = uri
- io
- end
-
- def OpenURI.redirectable?(uri1, uri2) # :nodoc:
- # This test is intended to forbid a redirection from http://... to
- # file:///etc/passwd.
- # However this is ad hoc. It should be extensible/configurable.
- uri1.scheme.downcase == uri2.scheme.downcase ||
- (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
- end
-
- def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
- if proxy
- proxy_uri, proxy_user, proxy_pass = proxy
- raise "Non-HTTP proxy URI: #{proxy_uri}" if proxy_uri.class != URI::HTTP
- end
-
- if target.userinfo && "1.9.0" <= RUBY_VERSION
- # don't raise for 1.8 because compatibility.
- raise ArgumentError, "userinfo not supported. [RFC3986]"
- end
-
- header = {}
- options.each {|k, v| header[k] = v if String === k }
-
- require 'net/http'
- klass = Net::HTTP
- if URI::HTTP === target
- # HTTP or HTTPS
- if proxy
- if proxy_user && proxy_pass
- klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_user, proxy_pass)
- else
- klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port)
- end
- end
- target_host = target.host
- target_port = target.port
- request_uri = target.request_uri
- else
- # FTP over HTTP proxy
- target_host = proxy_uri.host
- target_port = proxy_uri.port
- request_uri = target.to_s
- if proxy_user && proxy_pass
- header["Proxy-Authorization"] = 'Basic ' + ["#{proxy_user}:#{proxy_pass}"].pack('m').delete("\r\n")
- end
- end
-
- http = klass.new(target_host, target_port)
- if target.class == URI::HTTPS
- require 'net/https'
- http.use_ssl = true
- http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER
- store = OpenSSL::X509::Store.new
- if options[:ssl_ca_cert]
- if File.directory? options[:ssl_ca_cert]
- store.add_path options[:ssl_ca_cert]
- else
- store.add_file options[:ssl_ca_cert]
- end
- else
- store.set_default_paths
- end
- store.set_default_paths
- http.cert_store = store
- end
- if options.include? :read_timeout
- http.read_timeout = options[:read_timeout]
- end
-
- resp = nil
- http.start {
- if target.class == URI::HTTPS
- # xxx: information hiding violation
- sock = http.instance_variable_get(:@socket)
- if sock.respond_to?(:io)
- sock = sock.io # 1.9
- else
- sock = sock.instance_variable_get(:@socket) # 1.8
- end
- sock.post_connection_check(target_host)
- end
- req = Net::HTTP::Get.new(request_uri, header)
- if options.include? :http_basic_authentication
- user, pass = options[:http_basic_authentication]
- req.basic_auth user, pass
- end
- http.request(req) {|response|
- resp = response
- if options[:content_length_proc] && Net::HTTPSuccess === resp
- if resp.key?('Content-Length')
- options[:content_length_proc].call(resp['Content-Length'].to_i)
- else
- options[:content_length_proc].call(nil)
- end
- end
- resp.read_body {|str|
- buf << str
- if options[:progress_proc] && Net::HTTPSuccess === resp
- options[:progress_proc].call(buf.size)
- end
- }
- }
- }
- io = buf.io
- io.rewind
- io.status = [resp.code, resp.message]
- resp.each {|name,value| buf.io.meta_add_field name, value }
- case resp
- when Net::HTTPSuccess
- when Net::HTTPMovedPermanently, # 301
- Net::HTTPFound, # 302
- Net::HTTPSeeOther, # 303
- Net::HTTPTemporaryRedirect # 307
- throw :open_uri_redirect, URI.parse(resp['location'])
- else
- raise OpenURI::HTTPError.new(io.status.join(' '), io)
- end
- end
-
- class HTTPError < StandardError
- def initialize(message, io)
- super(message)
- @io = io
- end
- attr_reader :io
- end
-
- class Buffer # :nodoc:
- def initialize
- @io = StringIO.new
- @size = 0
- end
- attr_reader :size
-
- StringMax = 10240
- def <<(str)
- @io << str
- @size += str.length
- if StringIO === @io && StringMax < @size
- require 'tempfile'
- io = Tempfile.new('open-uri')
- io.binmode
- Meta.init io, @io if @io.respond_to? :meta
- io << @io.string
- @io = io
- end
- end
-
- def io
- Meta.init @io unless @io.respond_to? :meta
- @io
- end
- end
-
- # Mixin for holding meta-information.
- module Meta
- def Meta.init(obj, src=nil) # :nodoc:
- obj.extend Meta
- obj.instance_eval {
- @base_uri = nil
- @meta = {}
- }
- if src
- obj.status = src.status
- obj.base_uri = src.base_uri
- src.meta.each {|name, value|
- obj.meta_add_field(name, value)
- }
- end
- end
-
- # returns an Array which consists status code and message.
- attr_accessor :status
-
- # returns a URI which is base of relative URIs in the data.
- # It may differ from the URI supplied by a user because redirection.
- attr_accessor :base_uri
-
- # returns a Hash which represents header fields.
- # The Hash keys are downcased for canonicalization.
- attr_reader :meta
-
- def meta_add_field(name, value) # :nodoc:
- @meta[name.downcase] = value
- end
-
- # returns a Time which represents Last-Modified field.
- def last_modified
- if v = @meta['last-modified']
- Time.httpdate(v)
- else
- nil
- end
- end
-
- RE_LWS = /[\r\n\t ]+/n
- RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
- RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
- RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n
-
- def content_type_parse # :nodoc:
- v = @meta['content-type']
- # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
- if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v
- type = $1.downcase
- subtype = $2.downcase
- parameters = []
- $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
- val = qval.gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/n) { $1 ? $1[1,1] : $& } if qval
- parameters << [att.downcase, val]
- }
- ["#{type}/#{subtype}", *parameters]
- else
- nil
- end
- end
-
- # returns "type/subtype" which is MIME Content-Type.
- # It is downcased for canonicalization.
- # Content-Type parameters are stripped.
- def content_type
- type, *parameters = content_type_parse
- type || 'application/octet-stream'
- end
-
- # returns a charset parameter in Content-Type field.
- # It is downcased for canonicalization.
- #
- # If charset parameter is not given but a block is given,
- # the block is called and its result is returned.
- # It can be used to guess charset.
- #
- # If charset parameter and block is not given,
- # nil is returned except text type in HTTP.
- # In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1.
- def charset
- type, *parameters = content_type_parse
- if pair = parameters.assoc('charset')
- pair.last.downcase
- elsif block_given?
- yield
- elsif type && %r{\Atext/} =~ type &&
- @base_uri && /\Ahttp\z/i =~ @base_uri.scheme
- "iso-8859-1" # RFC2616 3.7.1
- else
- nil
- end
- end
-
- # returns a list of encodings in Content-Encoding field
- # as an Array of String.
- # The encodings are downcased for canonicalization.
- def content_encoding
- v = @meta['content-encoding']
- if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v
- v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
- else
- []
- end
- end
- end
-
- # Mixin for HTTP and FTP URIs.
- module OpenRead
- # OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.
- #
- # OpenURI::OpenRead#open takes optional 3 arguments as:
- # OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
- #
- # `mode', `perm' is same as Kernel#open.
- #
- # However, `mode' must be read mode because OpenURI::OpenRead#open doesn't
- # support write mode (yet).
- # Also `perm' is just ignored because it is meaningful only for file
- # creation.
- #
- # `options' must be a hash.
- #
- # Each pairs which key is a string in the hash specify a extra header
- # field for HTTP.
- # I.e. it is ignored for FTP without HTTP proxy.
- #
- # The hash may include other options which key is a symbol:
- #
- # [:proxy]
- # Synopsis:
- # :proxy => "http://proxy.foo.com:8000/"
- # :proxy => URI.parse("http://proxy.foo.com:8000/")
- # :proxy => true
- # :proxy => false
- # :proxy => nil
- #
- # If :proxy option is specified, the value should be String, URI,
- # boolean or nil.
- # When String or URI is given, it is treated as proxy URI.
- # When true is given or the option itself is not specified,
- # environment variable `scheme_proxy' is examined.
- # `scheme' is replaced by `http', `https' or `ftp'.
- # When false or nil is given, the environment variables are ignored and
- # connection will be made to a server directly.
- #
- # [:proxy_http_basic_authentication]
- # Synopsis:
- # :proxy_http_basic_authentication => ["http://proxy.foo.com:8000/", "proxy-user", "proxy-password"]
- # :proxy_http_basic_authentication => [URI.parse("http://proxy.foo.com:8000/"), "proxy-user", "proxy-password"]
- #
- # If :proxy option is specified, the value should be an Array with 3 elements.
- # It should contain a proxy URI, a proxy user name and a proxy password.
- # The proxy URI should be a String, an URI or nil.
- # The proxy user name and password should be a String.
- #
- # If nil is given for the proxy URI, this option is just ignored.
- #
- # If :proxy and :proxy_http_basic_authentication is specified,
- # ArgumentError is raised.
- #
- # [:http_basic_authentication]
- # Synopsis:
- # :http_basic_authentication=>[user, password]
- #
- # If :http_basic_authentication is specified,
- # the value should be an array which contains 2 strings:
- # username and password.
- # It is used for HTTP Basic authentication defined by RFC 2617.
- #
- # [:content_length_proc]
- # Synopsis:
- # :content_length_proc => lambda {|content_length| ... }
- #
- # If :content_length_proc option is specified, the option value procedure
- # is called before actual transfer is started.
- # It takes one argument which is expected content length in bytes.
- #
- # If two or more transfer is done by HTTP redirection, the procedure
- # is called only one for a last transfer.
- #
- # When expected content length is unknown, the procedure is called with
- # nil.
- # It is happen when HTTP response has no Content-Length header.
- #
- # [:progress_proc]
- # Synopsis:
- # :progress_proc => lambda {|size| ...}
- #
- # If :progress_proc option is specified, the proc is called with one
- # argument each time when `open' gets content fragment from network.
- # The argument `size' `size' is a accumulated transfered size in bytes.
- #
- # If two or more transfer is done by HTTP redirection, the procedure
- # is called only one for a last transfer.
- #
- # :progress_proc and :content_length_proc are intended to be used for
- # progress bar.
- # For example, it can be implemented as follows using Ruby/ProgressBar.
- #
- # pbar = nil
- # open("http://...",
- # :content_length_proc => lambda {|t|
- # if t && 0 < t
- # pbar = ProgressBar.new("...", t)
- # pbar.file_transfer_mode
- # end
- # },
- # :progress_proc => lambda {|s|
- # pbar.set s if pbar
- # }) {|f| ... }
- #
- # [:read_timeout]
- # Synopsis:
- # :read_timeout=>nil (no timeout)
- # :read_timeout=>10 (10 second)
- #
- # :read_timeout option specifies a timeout of read for http connections.
- #
- # [:ssl_ca_cert]
- # Synopsis:
- # :ssl_ca_cert=>filename
- #
- # :ssl_ca_cert is used to specify CA certificate for SSL.
- # If it is given, default certificates are not used.
- #
- # [:ssl_verify_mode]
- # Synopsis:
- # :ssl_verify_mode=>mode
- #
- # :ssl_verify_mode is used to specify openssl verify mode.
- #
- # OpenURI::OpenRead#open returns an IO like object if block is not given.
- # Otherwise it yields the IO object and return the value of the block.
- # The IO object is extended with OpenURI::Meta.
- def open(*rest, &block)
- OpenURI.open_uri(self, *rest, &block)
- end
-
- # OpenURI::OpenRead#read([options]) reads a content referenced by self and
- # returns the content as string.
- # The string is extended with OpenURI::Meta.
- # The argument `options' is same as OpenURI::OpenRead#open.
- def read(options={})
- self.open(options) {|f|
- str = f.read
- Meta.init str, f
- str
- }
- end
- end
-end
-
-module URI
- class Generic
- # returns a proxy URI.
- # The proxy URI is obtained from environment variables such as http_proxy,
- # ftp_proxy, no_proxy, etc.
- # If there is no proper proxy, nil is returned.
- #
- # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
- # are examined too.
- #
- # But http_proxy and HTTP_PROXY is treated specially under CGI environment.
- # It's because HTTP_PROXY may be set by Proxy: header.
- # So HTTP_PROXY is not used.
- # http_proxy is not used too if the variable is case insensitive.
- # CGI_HTTP_PROXY can be used instead.
- def find_proxy
- name = self.scheme.downcase + '_proxy'
- proxy_uri = nil
- if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
- # HTTP_PROXY conflicts with *_proxy for proxy settings and
- # HTTP_* for header information in CGI.
- # So it should be careful to use it.
- pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
- case pairs.length
- when 0 # no proxy setting anyway.
- proxy_uri = nil
- when 1
- k, v = pairs.shift
- if k == 'http_proxy' && ENV[k.upcase] == nil
- # http_proxy is safe to use because ENV is case sensitive.
- proxy_uri = ENV[name]
- else
- proxy_uri = nil
- end
- else # http_proxy is safe to use because ENV is case sensitive.
- proxy_uri = ENV[name]
- end
- if !proxy_uri
- # Use CGI_HTTP_PROXY. cf. libwww-perl.
- proxy_uri = ENV["CGI_#{name.upcase}"]
- end
- elsif name == 'http_proxy'
- unless proxy_uri = ENV[name]
- if proxy_uri = ENV[name.upcase]
- warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.'
- end
- end
- else
- proxy_uri = ENV[name] || ENV[name.upcase]
- end
-
- if proxy_uri && self.host
- require 'socket'
- begin
- addr = IPSocket.getaddress(self.host)
- proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
- rescue SocketError
- end
- end
-
- if proxy_uri
- proxy_uri = URI.parse(proxy_uri)
- name = 'no_proxy'
- if no_proxy = ENV[name] || ENV[name.upcase]
- no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
- if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
- (!port || self.port == port.to_i)
- proxy_uri = nil
- break
- end
- }
- end
- proxy_uri
- else
- nil
- end
- end
- end
-
- class HTTP
- def buffer_open(buf, proxy, options) # :nodoc:
- OpenURI.open_http(buf, self, proxy, options)
- end
-
- include OpenURI::OpenRead
- end
-
- class FTP
- def buffer_open(buf, proxy, options) # :nodoc:
- if proxy
- OpenURI.open_http(buf, self, proxy, options)
- return
- end
- require 'net/ftp'
-
- directories = self.path.split(%r{/}, -1)
- directories.shift if directories[0] == '' # strip a field before leading slash
- directories.each {|d|
- d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
- }
- unless filename = directories.pop
- raise ArgumentError, "no filename: #{self.inspect}"
- end
- directories.each {|d|
- if /[\r\n]/ =~ d
- raise ArgumentError, "invalid directory: #{d.inspect}"
- end
- }
- if /[\r\n]/ =~ filename
- raise ArgumentError, "invalid filename: #{filename.inspect}"
- end
- typecode = self.typecode
- if typecode && /\A[aid]\z/ !~ typecode
- raise ArgumentError, "invalid typecode: #{typecode.inspect}"
- end
-
- # The access sequence is defined by RFC 1738
- ftp = Net::FTP.open(self.host)
- # todo: extract user/passwd from .netrc.
- user = 'anonymous'
- passwd = nil
- user, passwd = self.userinfo.split(/:/) if self.userinfo
- ftp.login(user, passwd)
- directories.each {|cwd|
- ftp.voidcmd("CWD #{cwd}")
- }
- if typecode
- # xxx: typecode D is not handled.
- ftp.voidcmd("TYPE #{typecode.upcase}")
- end
- if options[:content_length_proc]
- options[:content_length_proc].call(ftp.size(filename))
- end
- ftp.retrbinary("RETR #{filename}", 4096) { |str|
- buf << str
- options[:progress_proc].call(buf.size) if options[:progress_proc]
- }
- ftp.close
- buf.io.rewind
- end
-
- include OpenURI::OpenRead
- end
-end
-# :startdoc:
Modified: MacRuby/trunk/lib/singleton.rb
===================================================================
--- MacRuby/trunk/lib/singleton.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/singleton.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -85,6 +85,10 @@
Singleton.__init__(super)
end
+ def _load(str)
+ instance
+ end
+
private
# ensure that the Singleton pattern is properly inherited
@@ -92,10 +96,6 @@
super
Singleton.__init__(sub_klass)
end
-
- def _load(str)
- instance
- end
end
class << Singleton
Modified: MacRuby/trunk/lib/un.rb
===================================================================
--- MacRuby/trunk/lib/un.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/un.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -214,6 +214,33 @@
end
##
+# Wait until the file becomes writable.
+#
+# ruby -run -e wait_writable -- [OPTION] FILE
+#
+
+def wait_writable
+ setup("n:w:v") do |argv, options|
+ verbose = options[:verbose]
+ n = options[:n] and n = Integer(n)
+ wait = (wait = options[:w]) ? Float(wait) : 0.2
+ argv.each do |file|
+ begin
+ open(file, "r+b")
+ rescue Errno::ENOENT
+ break
+ rescue Errno::EACCES => e
+ raise if n and (n -= 1) <= 0
+ puts e
+ STDOUT.flush
+ sleep wait
+ retry
+ end
+ end
+ end
+end
+
+##
# Display help message.
#
# ruby -run -e help [COMMAND]
Modified: MacRuby/trunk/lib/webrick/httpservlet/abstract.rb
===================================================================
--- MacRuby/trunk/lib/webrick/httpservlet/abstract.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/webrick/httpservlet/abstract.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -58,7 +58,7 @@
def redirect_to_directory_uri(req, res)
if req.path[-1] != ?/
- location = req.path + "/"
+ location = WEBrick::HTTPUtils.escape_path(req.path + "/")
if req.query_string && req.query_string.size > 0
location << "?" << req.query_string
end
Modified: MacRuby/trunk/lib/webrick/httpservlet/cgi_runner.rb
===================================================================
--- MacRuby/trunk/lib/webrick/httpservlet/cgi_runner.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/webrick/httpservlet/cgi_runner.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -39,7 +39,9 @@
Dir::chdir dir
if interpreter = ARGV[0]
- exec(interpreter, ENV["SCRIPT_FILENAME"])
+ argv = ARGV.dup
+ argv << ENV["SCRIPT_FILENAME"]
+ exec(*argv)
# NOTREACHED
end
exec ENV["SCRIPT_FILENAME"]
Modified: MacRuby/trunk/lib/webrick/httpservlet/cgihandler.rb
===================================================================
--- MacRuby/trunk/lib/webrick/httpservlet/cgihandler.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/webrick/httpservlet/cgihandler.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -87,6 +87,10 @@
res.status = $1.to_i
header.delete('status')
end
+ if header.has_key?('location')
+ # RFC 3875 6.2.3, 6.2.4
+ res.status = 302 unless (300...400) === res.status
+ end
if header.has_key?('set-cookie')
header['set-cookie'].each{|k|
res.cookies << Cookie.parse_set_cookie(k)
Modified: MacRuby/trunk/lib/webrick/httpservlet/filehandler.rb
===================================================================
--- MacRuby/trunk/lib/webrick/httpservlet/filehandler.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/lib/webrick/httpservlet/filehandler.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -199,26 +199,38 @@
private
+ def trailing_pathsep?(path)
+ # check for trailing path separator:
+ # File.dirname("/aaaa/bbbb/") #=> "/aaaa")
+ # File.dirname("/aaaa/bbbb/x") #=> "/aaaa/bbbb")
+ # File.dirname("/aaaa/bbbb") #=> "/aaaa")
+ # File.dirname("/aaaa/bbbbx") #=> "/aaaa")
+ return File.dirname(path) != File.dirname(path+"x")
+ end
+
def prevent_directory_traversal(req, res)
- # Preventing directory traversal on DOSISH platforms;
+ # Preventing directory traversal on Windows platforms;
# Backslashes (0x5c) in path_info are not interpreted as special
# character in URI notation. So the value of path_info should be
# normalize before accessing to the filesystem.
- if File::ALT_SEPARATOR
+
+ if trailing_pathsep?(req.path_info)
# File.expand_path removes the trailing path separator.
# Adding a character is a workaround to save it.
# File.expand_path("/aaa/") #=> "/aaa"
# File.expand_path("/aaa/" + "x") #=> "/aaa/x"
expanded = File.expand_path(req.path_info + "x")
- expanded[-1, 1] = "" # remove trailing "x"
- req.path_info = expanded
+ expanded.chop! # remove trailing "x"
+ else
+ expanded = File.expand_path(req.path_info)
end
+ req.path_info = expanded
end
def exec_handler(req, res)
raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
if set_filename(req, res)
- handler = get_handler(req)
+ handler = get_handler(req, res)
call_callback(:HandlerCallback, req, res)
h = handler.get_instance(@config, res.filename)
h.service(req, res)
@@ -228,9 +240,13 @@
return false
end
- def get_handler(req)
- suffix1 = (/\.(\w+)$/ =~ req.script_name) && $1.downcase
- suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ req.script_name) && $1.downcase
+ def get_handler(req, res)
+ suffix1 = (/\.(\w+)\z/ =~ res.filename) && $1.downcase
+ if /\.(\w+)\.([\w\-]+)\z/ =~ res.filename
+ if @options[:AcceptableLanguages].include?($2.downcase)
+ suffix2 = $1.downcase
+ end
+ end
handler_table = @options[:HandlerTable]
return handler_table[suffix1] || handler_table[suffix2] ||
HandlerTable[suffix1] || HandlerTable[suffix2] ||
@@ -243,15 +259,13 @@
path_info.unshift("") # dummy for checking @root dir
while base = path_info.first
- check_filename(req, res, base)
break if base == "/"
- break unless File.directory?(res.filename + base)
+ break unless File.directory?(File.expand_path(res.filename + base))
shift_path_info(req, res, path_info)
call_callback(:DirectoryCallback, req, res)
end
if base = path_info.first
- check_filename(req, res, base)
if base == "/"
if file = search_index_file(req, res)
shift_path_info(req, res, path_info, file)
@@ -272,12 +286,10 @@
end
def check_filename(req, res, name)
- @options[:NondisclosureName].each{|pattern|
- if File.fnmatch("/#{pattern}", name, File::FNM_CASEFOLD)
- @logger.warn("the request refers nondisclosure name `#{name}'.")
- raise HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- }
+ if nondisclosure_name?(name) || windows_ambiguous_name?(name)
+ @logger.warn("the request refers nondisclosure name `#{name}'.")
+ raise HTTPStatus::NotFound, "`#{req.path}' not found."
+ end
end
def shift_path_info(req, res, path_info, base=nil)
@@ -285,7 +297,8 @@
base = base || tmp
req.path_info = path_info.join
req.script_name << base
- res.filename << base
+ res.filename = File.expand_path(res.filename + base)
+ check_filename(req, res, File.basename(res.filename))
end
def search_index_file(req, res)
@@ -325,6 +338,12 @@
end
end
+ def windows_ambiguous_name?(name)
+ return true if /[. ]+\z/ =~ name
+ return true if /::\$DATA\z/ =~ name
+ return false
+ end
+
def nondisclosure_name?(name)
@options[:NondisclosureName].each{|pattern|
if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
@@ -343,7 +362,8 @@
list = Dir::entries(local_path).collect{|name|
next if name == "." || name == ".."
next if nondisclosure_name?(name)
- st = (File::stat(local_path + name) rescue nil)
+ next if windows_ambiguous_name?(name)
+ st = (File::stat(File.join(local_path, name)) rescue nil)
if st.nil?
[ name, nil, -1 ]
elsif st.directory?
@@ -383,7 +403,7 @@
res.body << "<A HREF=\"?S=#{d1}\">Size</A>\n"
res.body << "<HR>\n"
- list.unshift [ "..", File::mtime(local_path+".."), -1 ]
+ list.unshift [ "..", File::mtime(local_path+"/.."), -1 ]
list.each{ |name, time, size|
if name == ".."
dname = "Parent Directory"
Modified: MacRuby/trunk/load.c
===================================================================
--- MacRuby/trunk/load.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/load.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -407,7 +407,7 @@
return rb_require_safe(fname, rb_safe_level());
}
-static int
+/*static*/ int
search_required(VALUE fname, volatile VALUE *path)
{
VALUE tmp;
@@ -650,7 +650,7 @@
static VALUE
rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
{
- VALUE klass = ruby_cbase();
+ VALUE klass = rb_vm_cbase();
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
}
@@ -664,8 +664,8 @@
static VALUE
rb_f_autoload_p(VALUE obj, VALUE sym)
{
- /* use ruby_cbase() as same as rb_f_autoload. */
- VALUE klass = ruby_cbase();
+ /* use rb_vm_cbase() as same as rb_f_autoload. */
+ VALUE klass = rb_vm_cbase();
if (NIL_P(klass)) {
return Qnil;
}
@@ -686,7 +686,7 @@
rb_define_virtual_variable("$\"", get_loaded_features, 0);
rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
- GC_WB(&GET_VM()->loaded_features, rb_ary_new());
+ GC_WB(&vm->loaded_features, rb_ary_new());
rb_define_global_function("load", rb_f_load, -1);
rb_define_global_function("require", rb_f_require, 1);
Modified: MacRuby/trunk/main.c
===================================================================
--- MacRuby/trunk/main.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/main.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
main.c -
- $Author: akr $
+ $Author: nobu $
created at: Fri Aug 19 13:19:58 JST 1994
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -10,7 +10,7 @@
**********************************************************************/
#undef RUBY_EXPORT
-#include "ruby/ruby.h"
+#include "ruby.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
@@ -21,7 +21,6 @@
main(int argc, char **argv, char **envp)
{
#ifdef RUBY_DEBUG_ENV
- extern void ruby_set_debug_option(const char *);
ruby_set_debug_option(getenv("RUBY_DEBUG"));
#endif
#ifdef HAVE_LOCALE_H
Modified: MacRuby/trunk/marshal.c
===================================================================
--- MacRuby/trunk/marshal.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/marshal.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
marshal.c -
- $Author: matz $
+ $Author: mame $
created at: Thu Apr 27 16:30:01 JST 1995
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -97,7 +97,9 @@
static int
mark_marshal_compat_i(st_data_t key, st_data_t value)
{
+#if !WITH_OBJC
marshal_compat_t *p = (marshal_compat_t *)value;
+#endif
rb_gc_mark(p->newclass);
rb_gc_mark(p->oldclass);
return ST_CONTINUE;
@@ -149,11 +151,21 @@
};
static void
+check_dump_arg(struct dump_arg *arg)
+{
+ if (!DATA_PTR(arg->wrapper)) {
+ rb_raise(rb_eRuntimeError, "Marshal.dump reentered");
+ }
+}
+
+static void
mark_dump_arg(void *ptr)
{
+#if !WITH_OBJC
struct dump_arg *p = ptr;
if (!ptr)
return;
+#endif
rb_mark_set(p->data);
rb_mark_hash(p->compat_tbl);
}
@@ -406,7 +418,7 @@
static void
w_extended(VALUE klass, struct dump_arg *arg, int check)
{
- char *path;
+ const char *path;
if (check && FL_TEST(klass, FL_SINGLETON)) {
if (RCLASS_M_TBL(klass)->num_entries ||
@@ -598,23 +610,25 @@
else {
if (OBJ_TAINTED(obj)) arg->taint = Qtrue;
- if (rb_respond_to(obj, s_mdump)) {
+ if (rb_obj_respond_to(obj, s_mdump, Qtrue)) {
volatile VALUE v;
st_add_direct(arg->data, obj, arg->data->num_entries);
v = rb_funcall(obj, s_mdump, 0, 0);
+ check_dump_arg(arg);
w_class(TYPE_USRMARSHAL, obj, arg, Qfalse);
w_object(v, arg, limit);
if (hasiv) w_ivar(obj, 0, &c_arg);
return;
}
- if (rb_respond_to(obj, s_dump)) {
+ if (rb_obj_respond_to(obj, s_dump, Qtrue)) {
VALUE v;
st_table *ivtbl2 = 0;
int hasiv2;
v = rb_funcall(obj, s_dump, 1, INT2NUM(limit));
+ check_dump_arg(arg);
if (TYPE(v) != T_STRING) {
rb_raise(rb_eTypeError, "_dump() must return string");
}
@@ -801,12 +815,13 @@
{
VALUE v;
- if (!rb_respond_to(obj, s_dump_data)) {
+ if (!rb_obj_respond_to(obj, s_dump_data, Qtrue)) {
rb_raise(rb_eTypeError,
"no marshal_dump is defined for class %s",
rb_obj_classname(obj));
}
v = rb_funcall(obj, s_dump_data, 0);
+ check_dump_arg(arg);
w_class(TYPE_DATA, obj, arg, Qtrue);
w_object(v, arg, limit);
}
@@ -837,6 +852,7 @@
static VALUE
dump_ensure(struct dump_arg *arg)
{
+ if (!DATA_PTR(arg->wrapper)) return 0;
st_free_table(arg->symbols);
st_free_table(arg->data);
st_free_table(arg->compat_tbl);
@@ -896,13 +912,13 @@
}
arg.dest = 0;
if (!NIL_P(port)) {
- if (!rb_respond_to(port, s_write)) {
+ if (!rb_obj_respond_to(port, s_write, Qtrue)) {
type_error:
rb_raise(rb_eTypeError, "instance of IO needed");
}
arg.str = rb_str_buf_new(0);
arg.dest = port;
- if (rb_respond_to(port, s_binmode)) {
+ if (rb_obj_respond_to(port, s_binmode, Qtrue)) {
rb_funcall2(port, s_binmode, 0, 0);
}
}
@@ -942,6 +958,14 @@
VALUE compat_tbl_wrapper;
};
+static void
+check_load_arg(struct load_arg *arg)
+{
+ if (!DATA_PTR(arg->compat_tbl_wrapper)) {
+ rb_raise(rb_eRuntimeError, "Marshal.load reentered");
+ }
+}
+
static VALUE r_entry(VALUE v, struct load_arg *arg);
static VALUE r_object(struct load_arg *arg);
static VALUE path2class(const char *path);
@@ -962,6 +986,7 @@
else {
VALUE src = arg->src;
VALUE v = rb_funcall2(src, s_getbyte, 0, 0);
+ check_load_arg(arg);
if (NIL_P(v)) rb_eof_error();
c = (unsigned char)NUM2CHR(v);
}
@@ -971,7 +996,7 @@
static void
long_toobig(int size)
{
- rb_raise(rb_eTypeError, "long too big for this architecture (size %d, given %d)",
+ rb_raise(rb_eTypeError, "long too big for this architecture (size %zd, given %d)",
sizeof(long), size);
}
@@ -1038,6 +1063,7 @@
VALUE src = arg->src;
VALUE n = LONG2NUM(len);
str = rb_funcall2(src, s_read, 1, &n);
+ check_load_arg(arg);
if (NIL_P(str)) goto too_short;
StringValue(str);
if (RSTRING_CLEN(str) != len) goto too_short;
@@ -1132,6 +1158,7 @@
}
if (arg->proc) {
v = rb_funcall(arg->proc, rb_intern("call"), 1, v);
+ check_load_arg(arg);
}
return v;
}
@@ -1214,11 +1241,13 @@
case TYPE_LINK:
id = r_long(arg);
v = rb_hash_aref(arg->data, LONG2FIX(id));
+ check_load_arg(arg);
if (NIL_P(v)) {
rb_raise(rb_eArgError, "dump format error (unlinked)");
}
if (arg->proc) {
v = rb_funcall(arg->proc, rb_intern("call"), 1, v);
+ check_load_arg(arg);
}
break;
@@ -1249,7 +1278,6 @@
case TYPE_UCLASS:
{
VALUE c = path2class(r_unique(arg));
- bool non_native;
if (FL_TEST(c, FL_SINGLETON)) {
rb_raise(rb_eTypeError, "singleton can't be loaded");
@@ -1463,7 +1491,7 @@
VALUE klass = path2class(r_unique(arg));
VALUE data;
- if (!rb_respond_to(klass, s_load)) {
+ if (!rb_obj_respond_to(klass, s_load, Qtrue)) {
rb_raise(rb_eTypeError, "class %s needs to have method `_load'",
rb_class2name(klass));
}
@@ -1473,6 +1501,7 @@
*ivp = Qfalse;
}
v = rb_funcall(klass, s_load, 1, data);
+ check_load_arg(arg);
v = r_entry(v, arg);
v = r_leave(v, arg);
}
@@ -1490,13 +1519,14 @@
rb_extend_object(v, m);
}
}
- if (!rb_respond_to(v, s_mload)) {
+ if (!rb_obj_respond_to(v, s_mload, Qtrue)) {
rb_raise(rb_eTypeError, "instance of %s needs to have method `marshal_load'",
rb_class2name(klass));
}
v = r_entry(v, arg);
data = r_object(arg);
rb_funcall(v, s_mload, 1, data);
+ check_load_arg(arg);
v = r_leave(v, arg);
}
break;
@@ -1516,13 +1546,14 @@
case TYPE_DATA:
{
VALUE klass = path2class(r_unique(arg));
- if (rb_respond_to(klass, s_alloc)) {
+ if (rb_obj_respond_to(klass, s_alloc, Qtrue)) {
static int warn = Qtrue;
if (warn) {
rb_warn("define `allocate' instead of `_alloc'");
warn = Qfalse;
}
v = rb_funcall(klass, s_alloc, 0);
+ check_load_arg(arg);
}
else {
v = rb_obj_alloc(klass);
@@ -1531,12 +1562,13 @@
rb_raise(rb_eArgError, "dump format error");
}
v = r_entry(v, arg);
- if (!rb_respond_to(v, s_load_data)) {
+ if (!rb_obj_respond_to(v, s_load_data, Qtrue)) {
rb_raise(rb_eTypeError,
"class %s needs to have instance method `_load_data'",
rb_class2name(klass));
}
rb_funcall(v, s_load_data, 1, r_object0(arg, 0, extmod));
+ check_load_arg(arg);
v = r_leave(v, arg);
}
break;
@@ -1602,6 +1634,7 @@
static VALUE
load_ensure(struct load_arg *arg)
{
+ if (!DATA_PTR(arg->compat_tbl_wrapper)) return 0;
st_free_table(arg->symbols);
st_free_table(arg->compat_tbl);
DATA_PTR(arg->compat_tbl_wrapper) = 0;
@@ -1629,12 +1662,13 @@
struct load_arg arg;
rb_scan_args(argc, argv, "11", &port, &proc);
- if (rb_respond_to(port, rb_intern("to_str"))) {
+ v = rb_check_string_type(port);
+ if (!NIL_P(v)) {
arg.taint = OBJ_TAINTED(port); /* original taintedness */
- StringValue(port); /* possible conversion */
+ port = v;
}
- else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
- if (rb_respond_to(port, s_binmode)) {
+ else if (rb_obj_respond_to(port, s_getbyte, Qtrue) && rb_obj_respond_to(port, s_read, Qtrue)) {
+ if (rb_obj_respond_to(port, s_binmode, Qtrue)) {
rb_funcall2(port, s_binmode, 0, 0);
}
arg.taint = Qtrue;
Modified: MacRuby/trunk/math.c
===================================================================
--- MacRuby/trunk/math.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/math.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
math.c -
- $Author: matz $
+ $Author: nobu $
created at: Tue Jan 25 14:12:56 JST 1994
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -35,7 +35,7 @@
} while (0)
static void
-domain_check(double x, char *msg)
+domain_check(double x, const char *msg)
{
while(1) {
if (errno) {
Modified: MacRuby/trunk/misc/ruby-mode.el
===================================================================
--- MacRuby/trunk/misc/ruby-mode.el 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/misc/ruby-mode.el 2008-06-05 08:11:58 UTC (rev 247)
@@ -5,7 +5,7 @@
;;; created at: Fri Feb 4 14:49:13 JST 1994
;;;
-(defconst ruby-mode-revision "$Revision: 16266 $"
+(defconst ruby-mode-revision "$Revision: 16611 $"
"Ruby mode revision string.")
(defconst ruby-mode-version
@@ -312,7 +312,9 @@
(set (make-local-variable 'font-lock-syntax-table) ruby-font-lock-syntax-table)
(set (make-local-variable 'font-lock-syntactic-keywords) ruby-font-lock-syntactic-keywords)
- (run-mode-hooks 'ruby-mode-hook))
+ (if (fboundp 'run-mode-hooks)
+ (run-mode-hooks 'ruby-mode-hook)
+ (run-hooks 'ruby-mode-hook)))
(defun ruby-current-indentation ()
(save-excursion
Modified: MacRuby/trunk/missing/crypt.c
===================================================================
--- MacRuby/trunk/missing/crypt.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/missing/crypt.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -107,13 +107,15 @@
#define LARGEDATA
#endif
+int des_setkey(), des_cipher();
+
/* compile with "-DSTATIC=int" when profiling */
#ifndef STATIC
#define STATIC static
#endif
-STATIC init_des(), init_perm(), permute();
+STATIC void init_des(), init_perm(), permute();
#ifdef DEBUG
-STATIC prtab();
+STATIC void prtab();
#endif
/* ==================================== */
@@ -299,7 +301,7 @@
#define PERM3264(d,d0,d1,cpp,p) \
{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
-STATIC
+STATIC void
permute(cp, out, p, chars_in)
unsigned char *cp;
C_block *out;
@@ -377,46 +379,62 @@
};
static unsigned char S[8][64] = { /* 48->32 bit substitution tables */
+ {
/* S[1] */
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
+ },
+ {
/* S[2] */
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
+ },
+ {
/* S[3] */
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
+ },
+ {
/* S[4] */
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
+ },
+ {
/* S[5] */
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
+ },
+ {
/* S[6] */
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
+ },
+ {
/* S[7] */
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
+ },
+ {
/* S[8] */
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
+ },
};
static unsigned char P32Tr[] = { /* 32-bit permutation function */
@@ -580,6 +598,7 @@
/*
* Set up the key schedule from the key.
*/
+int
des_setkey(key)
register const char *key;
{
@@ -614,6 +633,7 @@
* NOTE: the performance of this routine is critically dependent on your
* compiler and machine architecture.
*/
+int
des_cipher(in, out, salt, num_iter)
const char *in;
char *out;
@@ -734,7 +754,7 @@
* Initialize various tables. This need only be done once. It could even be
* done at compile time, if the compiler were capable of that sort of thing.
*/
-STATIC
+STATIC void
init_des()
{
register int i, j;
@@ -878,7 +898,7 @@
*
* "perm" must be all-zeroes on entry to this routine.
*/
-STATIC
+STATIC void
init_perm(perm, p, chars_in, chars_out)
C_block perm[64/CHUNKBITS][1<<CHUNKBITS];
unsigned char p[64];
@@ -902,6 +922,7 @@
/*
* "setkey" routine (for backwards compatibility)
*/
+int
setkey(key)
register const char *key;
{
@@ -922,6 +943,7 @@
/*
* "encrypt" routine (for backwards compatibility)
*/
+int
encrypt(block, flag)
register char *block;
int flag;
@@ -950,7 +972,7 @@
}
#ifdef DEBUG
-STATIC
+STATIC void
prtab(s, t, num_rows)
char *s;
unsigned char *t;
Modified: MacRuby/trunk/missing/vsnprintf.c
===================================================================
--- MacRuby/trunk/missing/vsnprintf.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/missing/vsnprintf.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -217,7 +217,7 @@
* I/O descriptors for __sfvwrite().
*/
struct __siov {
- void *iov_base;
+ const void *iov_base;
size_t iov_len;
};
struct __suio {
@@ -422,7 +422,7 @@
* use the given digits.
*/
static char *
-BSD__ultoa(register u_long val, char *endp, int base, int octzero, char *xdigs)
+BSD__ultoa(register u_long val, char *endp, int base, int octzero, const char *xdigs)
{
register char *cp = endp;
register long sval;
@@ -523,10 +523,10 @@
static int
BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
{
- register char *fmt; /* format string */
+ register const char *fmt; /* format string */
register int ch; /* character from fmt */
register int n; /* handy integer (short term usage) */
- register char *cp; /* handy char pointer (short term usage) */
+ register const char *cp;/* handy char pointer (short term usage) */
register struct __siov *iovp;/* for PRINT macro */
register int flags; /* flags as above */
int ret; /* return value accumulator */
@@ -550,12 +550,13 @@
int fieldsz; /* field size expanded by sign, etc */
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
- char *xdigs = 0; /* digits for [xX] conversion */
+ const char *xdigs = 0; /* digits for [xX] conversion */
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
char ox[2]; /* space for 0x hex-prefix */
+ char *const ebuf = buf + sizeof(buf);
/*
* Choose PADSIZE to trade efficiency vs. size. If larger printf
@@ -616,7 +617,7 @@
fp->_file >= 0)
return (BSD__sbprintf(fp, fmt0, ap));
- fmt = (char *)fmt0;
+ fmt = fmt0;
uio.uio_iov = iovp = iov;
uio.uio_resid = 0;
uio.uio_iovcnt = 0;
@@ -720,7 +721,8 @@
goto rflag;
#endif /* _HAVE_SANE_QUAD_ */
case 'c':
- *(cp = buf) = va_arg(ap, int);
+ cp = buf;
+ *buf = (char)va_arg(ap, int);
size = 1;
sign = '\0';
break;
@@ -868,7 +870,7 @@
* NUL in the first `prec' characters, and
* strlen() will go further.
*/
- char *p = (char *)memchr(cp, 0, prec);
+ const char *p = (char *)memchr(cp, 0, prec);
if (p != NULL) {
size = p - cp;
@@ -930,28 +932,27 @@
* explicit precision of zero is no characters.''
* -- ANSI X3J11
*/
- cp = buf + BUF;
#ifdef _HAVE_SANE_QUAD_
if (flags & QUADINT) {
if (uqval != 0 || prec != 0)
- cp = BSD__uqtoa(uqval, cp, base,
+ cp = BSD__uqtoa(uqval, ebuf, base,
flags & ALT, xdigs);
} else
#else /* _HAVE_SANE_QUAD_ */
#endif /* _HAVE_SANE_QUAD_ */
{
if (ulval != 0 || prec != 0)
- cp = BSD__ultoa(ulval, cp, base,
+ cp = BSD__ultoa(ulval, ebuf, base,
flags & ALT, xdigs);
}
- size = buf + BUF - cp;
+ size = ebuf - cp;
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
/* pretend it was %c with argument ch */
cp = buf;
- *cp = ch;
+ *buf = ch;
size = 1;
sign = '\0';
break;
Modified: MacRuby/trunk/mkconfig.rb
===================================================================
--- MacRuby/trunk/mkconfig.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/mkconfig.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -75,6 +75,7 @@
next if /^\$ac_\w+$/ =~ val
next if $install_name and /^RUBY_INSTALL_NAME$/ =~ name
next if $so_name and /^RUBY_SO_NAME$/ =~ name
+ next if /^(?:X|(?:MINI|RUN)RUBY$)/ =~ name
if /^program_transform_name$/ =~ name and /^s(\\?.)(.*)\1$/ =~ val
next if $install_name
sep = %r"#{Regexp.quote($1)}"
Modified: MacRuby/trunk/numeric.c
===================================================================
--- MacRuby/trunk/numeric.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/numeric.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
numeric.c -
- $Author: matz $
+ $Author: akr $
created at: Fri Aug 13 18:33:09 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -260,6 +260,20 @@
}
+/*
+ * call-seq:
+ * num.fdiv(numeric) => float
+ *
+ * Returns float division.
+ */
+
+static VALUE
+num_fdiv(VALUE x, VALUE y)
+{
+ return rb_funcall(rb_Float(x), '/', 1, y);
+}
+
+
static VALUE num_floor(VALUE num);
/*
@@ -274,6 +288,7 @@
static VALUE
num_div(VALUE x, VALUE y)
{
+ if (rb_equal(INT2FIX(0), y)) rb_num_zerodiv();
return num_floor(rb_funcall(x, '/', 1, y));
}
@@ -1559,22 +1574,14 @@
else {
return;
}
-#ifdef LONG_LONG_VALUE
- rb_raise(rb_eRangeError, "integer %lld too %s to convert to `int'", num, s);
-#else
- rb_raise(rb_eRangeError, "integer %ld too %s to convert to `int'", num, s);
-#endif
+ rb_raise(rb_eRangeError, "integer %"PRIdVALUE " too %s to convert to `int'", num, s);
}
static void
check_uint(VALUE num)
{
if (num > UINT_MAX) {
-#ifdef LONG_LONG_VALUE
- rb_raise(rb_eRangeError, "integer %llu too big to convert to `unsigned int'", num);
-#else
- rb_raise(rb_eRangeError, "integer %lu too big to convert to `unsigned int'", num);
-#endif
+ rb_raise(rb_eRangeError, "integer %"PRIuVALUE " too big to convert to `unsigned int'", num);
}
}
@@ -1644,7 +1651,7 @@
v = rb_num2long(val);
if (!FIXABLE(v))
- rb_raise(rb_eRangeError, "integer %ld out of range of fixnum", v);
+ rb_raise(rb_eRangeError, "integer %"PRIdVALUE " out of range of fixnum", v);
return LONG2FIX(v);
}
@@ -1863,7 +1870,9 @@
int_chr(int argc, VALUE *argv, VALUE num)
{
char c;
+#if !WITH_OBJC
int n;
+#endif
long i = NUM2LONG(num);
rb_encoding *enc;
VALUE str;
@@ -1871,8 +1880,10 @@
switch (argc) {
case 0:
if (i < 0 || 0xff < i) {
+#if !WITH_OBJC
out_of_range:
- rb_raise(rb_eRangeError, "%ld out of char range", i);
+#endif
+ rb_raise(rb_eRangeError, "%"PRIdVALUE " out of char range", i);
}
c = i;
if (i < 0x80) {
@@ -1888,16 +1899,16 @@
break;
}
#if WITH_OBJC
- /* TODO */
- rb_notimplement();
+ enc = rb_to_encoding(argv[0]);
+ str = rb_enc_str_new(&c, 1, enc);
#else
enc = rb_to_encoding(argv[0]);
if (!enc) enc = rb_ascii8bit_encoding();
if (i < 0 || (n = rb_enc_codelen(i, enc)) <= 0) goto out_of_range;
str = rb_enc_str_new(0, n, enc);
rb_enc_mbcput(i, RSTRING_PTR(str), enc);
+#endif
return str;
-#endif
}
static VALUE
@@ -2260,11 +2271,15 @@
return rb_big_div(x, y);
case T_FLOAT:
{
- double div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
+ double div;
+
if (op == '/') {
+ div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
return DOUBLE2NUM(div);
}
else {
+ if (RFLOAT_VALUE(y) == 0) rb_num_zerodiv();
+ div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
return rb_dbl2big(floor(div));
}
}
@@ -3114,7 +3129,7 @@
rb_define_method(rb_cNumeric, "<=>", num_cmp, 1);
rb_define_method(rb_cNumeric, "eql?", num_eql, 1);
rb_define_method(rb_cNumeric, "quo", num_quo, 1);
- rb_define_method(rb_cNumeric, "fdiv", num_quo, 1);
+ rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1);
rb_define_method(rb_cNumeric, "div", num_div, 1);
rb_define_method(rb_cNumeric, "divmod", num_divmod, 1);
rb_define_method(rb_cNumeric, "modulo", num_modulo, 1);
Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/objc.m 2008-06-05 08:11:58 UTC (rev 247)
@@ -69,6 +69,7 @@
static struct st_table *bs_inf_prot_imethods;
static struct st_table *bs_cftypes;
+#if 0
static char *
rb_objc_sel_to_mid(SEL selector, char *buffer, unsigned buffer_len)
{
@@ -89,6 +90,7 @@
return buffer;
}
+#endif
static inline const char *
rb_objc_skip_octype_modifiers(const char *octype)
@@ -213,7 +215,6 @@
static size_t
get_ffi_struct_size(ffi_type *type)
{
- unsigned i;
ffi_type **p;
size_t s;
@@ -627,7 +628,7 @@
if (n < bs_struct->fields_count)
rb_raise(rb_eArgError,
"not enough elements in array `%s' to create " \
- "structure `%s' (%d for %d)",
+ "structure `%s' (%ld for %d)",
RSTRING_CPTR(rb_inspect(rval)), bs_struct->name, n,
bs_struct->fields_count);
@@ -641,7 +642,7 @@
if (RARRAY_LEN(rval) != 0 || n != bs_struct->fields_count) {
rb_raise(rb_eArgError,
"too much elements in array `%s' to create " \
- "structure `%s' (%d for %d)",
+ "structure `%s' (%ld for %d)",
RSTRING_CPTR(rb_inspect(orig)),
bs_struct->name, RARRAY_LEN(orig),
bs_struct->fields_count);
@@ -1087,12 +1088,12 @@
real_count = count;
if (bs_method != NULL && bs_method->variadic) {
if (RARRAY_LEN(argv) < count - 2)
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for %d)",
RARRAY_LEN(argv), count - 2);
count = RARRAY_LEN(argv) + 2;
}
else if (RARRAY_LEN(argv) != count - 2) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for %d)",
RARRAY_LEN(argv), count - 2);
}
@@ -1849,7 +1850,6 @@
static VALUE
rb_bs_boxed_is_equal(VALUE recv, VALUE other)
{
- unsigned i;
bs_element_boxed_t *bs_boxed;
bool ok;
void *d1, *d2;
@@ -1905,7 +1905,6 @@
{
bs_element_boxed_t *bs_boxed = rb_klass_get_bs_boxed(CLASS_OF(recv));
bs_element_struct_t *bs_struct = (bs_element_struct_t *)bs_boxed->value;
- VALUE ary;
unsigned i;
VALUE str;
@@ -2236,7 +2235,6 @@
{
char path[PATH_MAX];
char *error;
- char *p;
if (bs_find_path(framework_path, path, sizeof path)) {
if (!bs_parse(path, BS_PARSE_OPTIONS_LOAD_DYLIBS, bs_parse_cb, NULL,
@@ -2468,7 +2466,7 @@
{
const char *name;
size_t len;
- char buf[100];
+ char buf[100];
if (mid == 0)
return mid;
@@ -2504,10 +2502,11 @@
strlcpy(buf, name, sizeof buf);
buf[len - 1] = '\0';
}
- else
+ else {
return mid;
+ }
-// printf("new sel %s for %s\n", buf, name);
+ //printf("new sel %s for %s\n", buf, name);
return rb_intern(buf);
}
@@ -2613,34 +2612,9 @@
rb_raise(rb_eArgError, "can't register `%s' as an IB outlet",
symname);
}
+ return recv;
}
-#if 0
-/* XXX the ivar cluster API is not used yet, and may not simply be used.
- */
-#define IVAR_CLUSTER_NAME "__rivars__"
-void
-rb_objc_install_ivar_cluster(Class klass)
-{
- assert(class_addIvar(klass, IVAR_CLUSTER_NAME, sizeof(void *),
- log2(sizeof(void *)), "^v") == YES);
-}
-
-void *
-rb_objc_get_ivar_cluster(void *obj)
-{
- void *v = NULL;
- assert(object_getInstanceVariable((id)obj, IVAR_CLUSTER_NAME, &v) != NULL);
- return v;
-}
-
-void
-rb_objc_set_ivar_cluster(void *obj, void *v)
-{
- assert(object_setInstanceVariable((id)obj, IVAR_CLUSTER_NAME, v) != NULL);
-}
-#endif
-
static CFMutableDictionaryRef __obj_flags;
long
@@ -2919,10 +2893,10 @@
rb_objc_retain(bs_inf_prot_imethods = st_init_numtable());
rb_objc_retain(bs_cftypes = st_init_strtable());
- rb_objc_retain(
- bs_const_magic_cookie = rb_str_new2("bs_const_magic_cookie"));
- rb_objc_retain(
- rb_objc_class_magic_cookie = rb_str_new2("rb_objc_class_magic_cookie"));
+ rb_objc_retain((const void *)(
+ bs_const_magic_cookie = rb_str_new2("bs_const_magic_cookie")));
+ rb_objc_retain((const void *)(
+ rb_objc_class_magic_cookie = rb_str_new2("rb_objc_class_magic_cookie")));
rb_cBoxed = rb_define_class("Boxed",
rb_objc_import_class(objc_getClass("NSValue")));
Modified: MacRuby/trunk/object.c
===================================================================
--- MacRuby/trunk/object.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/object.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
object.c -
- $Author: matz $
+ $Author: nobu $
created at: Thu Jul 15 12:01:24 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -159,8 +159,8 @@
{
#if WITH_OBJC
if (rb_objc_is_non_native(obj)) {
- if (rb_objc_flag_check(obj, FL_TAINT))
- rb_objc_flag_set(dest, FL_TAINT);
+ if (rb_objc_flag_check((const void *)obj, FL_TAINT))
+ rb_objc_flag_set((const void *)dest, FL_TAINT, true);
goto call_init_copy;
}
#endif
@@ -318,7 +318,7 @@
VALUE
rb_any_to_s(VALUE obj)
{
- char *cname = rb_obj_classname(obj);
+ const char *cname = rb_obj_classname(obj);
VALUE str;
str = rb_sprintf("#<%s:%p>", cname, (void*)obj);
@@ -419,9 +419,8 @@
if (has_ivar) {
VALUE str;
- char *c;
+ const char *c = rb_obj_classname(obj);
- c = rb_obj_classname(obj);
str = rb_sprintf("-<%s:%p", c, (void*)obj);
return rb_exec_recursive(inspect_obj, obj, str);
}
@@ -679,7 +678,7 @@
{
#if WITH_OBJC
if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
- return rb_objc_flag_check(obj, FL_TAINT) ? Qtrue : Qfalse;
+ return rb_objc_flag_check((const void *)obj, FL_TAINT) ? Qtrue : Qfalse;
}
#endif
if (FL_TEST(obj, FL_TAINT))
@@ -702,7 +701,7 @@
rb_secure(4);
#if WITH_OBJC
if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
- rb_objc_flag_set(obj, FL_TAINT, true);
+ rb_objc_flag_set((const void *)obj, FL_TAINT, true);
return obj;
}
#endif
@@ -729,7 +728,7 @@
rb_secure(3);
#if WITH_OBJC
if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
- rb_objc_flag_set(obj, FL_TAINT, false);
+ rb_objc_flag_set((const void *)obj, FL_TAINT, false);
return obj;
}
#endif
@@ -785,7 +784,7 @@
}
#if WITH_OBJC
else if (rb_objc_is_non_native(obj)) {
- rb_objc_flag_set(obj, FL_FREEZE, true);
+ rb_objc_flag_set((const void *)obj, FL_FREEZE, true);
}
#endif
else {
@@ -816,7 +815,8 @@
}
#if WITH_OBJC
if (rb_objc_is_non_native(obj)) {
- return rb_objc_is_immutable(obj) || rb_objc_flag_check(obj, FL_FREEZE)
+ return rb_objc_is_immutable(obj)
+ || rb_objc_flag_check((const void *)obj, FL_FREEZE)
? Qtrue : Qfalse;
}
#endif
@@ -1976,7 +1976,7 @@
ID m;
m = rb_intern(method);
- if (!rb_respond_to(val, m)) {
+ if (!rb_obj_respond_to(val, m, Qtrue)) {
if (raise) {
rb_raise(rb_eTypeError, "can't convert %s into %s",
NIL_P(val) ? "nil" :
@@ -2000,7 +2000,7 @@
if (TYPE(val) == type) return val;
v = convert_type(val, tname, method, Qtrue);
if (TYPE(v) != type) {
- char *cname = rb_obj_classname(val);
+ const char *cname = rb_obj_classname(val);
rb_raise(rb_eTypeError, "can't convert %s to %s (%s#%s gives %s)",
cname, tname, cname, method, rb_obj_classname(v));
}
@@ -2017,7 +2017,7 @@
v = convert_type(val, tname, method, Qfalse);
if (NIL_P(v)) return Qnil;
if (TYPE(v) != type) {
- char *cname = rb_obj_classname(val);
+ const char *cname = rb_obj_classname(val);
rb_raise(rb_eTypeError, "can't convert %s to %s (%s#%s gives %s)",
cname, tname, cname, method, rb_obj_classname(v));
}
@@ -2033,7 +2033,7 @@
if (FIXNUM_P(val)) return val;
v = convert_type(val, "Integer", method, Qtrue);
if (!rb_obj_is_kind_of(v, rb_cInteger)) {
- char *cname = rb_obj_classname(val);
+ const char *cname = rb_obj_classname(val);
rb_raise(rb_eTypeError, "can't convert %s to Integer (%s#%s gives %s)",
cname, cname, method, rb_obj_classname(v));
}
Modified: MacRuby/trunk/pack.c
===================================================================
--- MacRuby/trunk/pack.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/pack.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -12,6 +12,7 @@
#include "ruby/ruby.h"
#include <sys/types.h>
#include <ctype.h>
+#include <errno.h>
#define SIZE16 2
#define SIZE32 4
@@ -478,7 +479,7 @@
continue;
}
if (*p == '_' || *p == '!') {
- const char *natstr = "sSiIlL";
+ static const char natstr[] = "sSiIlL";
if (strchr(natstr, type)) {
#ifdef NATINT_PACK
@@ -495,7 +496,11 @@
p++;
}
else if (ISDIGIT(*p)) {
+ errno = 0;
len = STRTOUL(p, (char**)&p, 10);
+ if (errno) {
+ rb_raise(rb_eRangeError, "pack length too big");
+ }
}
else {
len = 1;
@@ -1338,7 +1343,7 @@
}
star = 0;
if (*p == '_' || *p == '!') {
- const char *natstr = "sSiIlL";
+ static const char natstr[] = "sSiIlL";
if (strchr(natstr, type)) {
#ifdef NATINT_PACK
@@ -1358,7 +1363,11 @@
p++;
}
else if (ISDIGIT(*p)) {
+ errno = 0;
len = STRTOUL(p, (char**)&p, 10);
+ if (errno) {
+ rb_raise(rb_eRangeError, "pack length too big");
+ }
}
else {
len = (type != '@');
@@ -1565,7 +1574,6 @@
}
PACK_ITEM_ADJUST();
break;
-
case 'L':
PACK_LENGTH_ADJUST(unsigned long,4);
while (len-- > 0) {
@@ -1586,7 +1594,6 @@
}
PACK_ITEM_ADJUST();
break;
-
case 'Q':
PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);
while (len-- > 0) {
Modified: MacRuby/trunk/parse.y
===================================================================
--- MacRuby/trunk/parse.y 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/parse.y 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
parse.y -
- $Author: usa $
+ $Author: mame $
created at: Fri May 28 18:02:42 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -433,8 +433,10 @@
static int arg_var_gen(struct parser_params*, ID);
#define arg_var(id) arg_var_gen(parser, id)
#if WITH_OBJC
-static int named_arg_gen(struct parser_params*, ID, int);
+static void named_arg_gen(struct parser_params*, ID, int);
# define named_arg(id, flag) named_arg_gen(parser, id, flag)
+static NODE *process_named_args_gen(struct parser_params*, NODE*);
+# define process_named_args(node) process_named_args_gen(parser, node)
#endif
static int local_id_gen(struct parser_params*, ID);
#define local_id(id) local_id_gen(parser, id)
@@ -6217,7 +6219,9 @@
int cmd_state;
enum lex_state_e last_state;
rb_encoding *enc;
+#if !WITH_OBJC
int mb;
+#endif
#ifdef RIPPER
int fallthru = Qfalse;
#endif
@@ -7939,7 +7943,9 @@
else if (is_class_id(id)) {
return NEW_CVASGN(id, val);
}
- compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
+ else {
+ compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
+ }
return 0;
}
@@ -8665,7 +8671,47 @@
}
#if WITH_OBJC
-static int
+static NODE *
+process_named_args_gen(struct parser_params *parser, NODE *n)
+{
+ NODE *args = n->nd_args;
+ if (args != NULL
+ && args->nd_argc == 2
+ && nd_type(args->u3.node->u1.node) == NODE_ARRAY
+ && args->u3.node->u1.node->flags & NODE_ARRAY_NAMED_ARGS) {
+
+ NODE *named_args;
+ NODE *new_argv;
+ NODE *p;
+ char buf[512];
+ bool flip;
+
+ new_argv = NEW_LIST(args->nd_head);
+
+ strlcpy(buf, rb_id2name(n->u2.id), sizeof buf);
+ strlcat(buf, ":", sizeof buf);
+
+ named_args = args->u3.node->u1.node;
+ for (flip = true, p = named_args;
+ p != NULL;
+ p = p->nd_next, flip = !flip) {
+ if (flip) {
+ strlcat(buf, rb_id2name(SYM2ID(p->nd_head->nd_lit)),
+ sizeof buf);
+ strlcat(buf, ":", sizeof buf);
+ }
+ else {
+ list_append(new_argv, p->nd_head);
+ }
+ }
+
+ n->nd_mid = rb_intern(buf);
+ n->nd_args = new_argv;
+ }
+ return n;
+}
+
+static void
named_arg_gen(struct parser_params *parser, ID id, int init)
{
if (init)
@@ -9095,7 +9141,6 @@
Init_sym(void)
{
#if WITH_OBJC
- CFDictionaryKeyCallBacks cb;
global_symbols.sym_id = CFDictionaryCreateMutable(NULL,
0, NULL, NULL);
GC_ROOT(&global_symbols.sym_id);
@@ -9660,7 +9705,9 @@
static void
parser_mark(void *ptr)
{
+#if !WITH_OBJC
struct parser_params *p = (struct parser_params*)ptr;
+#endif
rb_gc_mark((VALUE)p->parser_lex_strterm);
rb_gc_mark(p->parser_lex_input);
Modified: MacRuby/trunk/proc.c
===================================================================
--- MacRuby/trunk/proc.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/proc.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
proc.c - Proc, Binding, Env
- $Author: matz $
+ $Author: nobu $
created at: Wed Jan 17 12:13:14 2007
Copyright (C) 2004-2007 Koichi Sasada
@@ -50,7 +50,6 @@
proc = ptr;
RUBY_MARK_UNLESS_NULL(proc->envval);
RUBY_MARK_UNLESS_NULL(proc->blockprocval);
- RUBY_MARK_UNLESS_NULL((VALUE)proc->special_cref_stack);
RUBY_MARK_UNLESS_NULL(proc->block.proc);
RUBY_MARK_UNLESS_NULL(proc->block.self);
if (proc->block.iseq && RUBY_VM_IFUNC_P(proc->block.iseq)) {
@@ -93,8 +92,7 @@
dst->block = src->block;
dst->block.proc = procval;
dst->envval = src->envval;
- dst->safe_level = dst->safe_level;
- dst->special_cref_stack = src->special_cref_stack;
+ dst->safe_level = src->safe_level;
dst->is_lambda = src->is_lambda;
return procval;
@@ -241,7 +239,6 @@
if (ptr) {
bind = ptr;
RUBY_MARK_UNLESS_NULL(bind->env);
- RUBY_MARK_UNLESS_NULL((VALUE)bind->cref_stack);
}
RUBY_MARK_LEAVE("binding");
}
@@ -264,7 +261,6 @@
GetBindingPtr(self, src);
GetBindingPtr(bindval, dst);
dst->env = src->env;
- dst->cref_stack = src->cref_stack;
return bindval;
}
@@ -286,7 +282,6 @@
GetBindingPtr(bindval, bind);
GC_WB(&bind->env, vm_make_env_object(th, cfp));
- GC_WB(&bind->cref_stack, ruby_cref());
return bindval;
}
@@ -666,7 +661,7 @@
{
VALUE str = 0;
rb_proc_t *proc;
- char *cname = rb_obj_classname(self);
+ const char *cname = rb_obj_classname(self);
rb_iseq_t *iseq;
const char *is_lambda;
@@ -710,23 +705,6 @@
return self;
}
-/*
- * call-seq:
- * prc.binding => binding
- *
- * Returns the binding associated with <i>prc</i>. Note that
- * <code>Kernel#eval</code> accepts either a <code>Proc</code> or a
- * <code>Binding</code> object as its second parameter.
- *
- * def fred(param)
- * proc {}
- * end
- *
- * b = fred(99)
- * eval("param", b.binding) #=> 99
- * eval("param", b) #=> 99
- */
-
static void
bm_mark(struct METHOD *data)
{
@@ -1208,10 +1186,12 @@
}
}
if ((state = EXEC_TAG()) == 0) {
+ VALUE rb_vm_call(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid,
+ int argc, const VALUE *argv, const NODE *body, int nosuper);
+
PASS_PASSED_BLOCK();
- result = vm_call0(GET_THREAD(),
- data->oclass, data->recv, data->id, data->oid,
- argc, argv, data->body, 0);
+ result = rb_vm_call(GET_THREAD(), data->oclass, data->recv, data->id, data->oid,
+ argc, argv, data->body, 0);
}
POP_TAG();
if (safe >= 0)
@@ -1447,7 +1427,7 @@
struct METHOD *data;
VALUE str;
const char *s;
- char *sharp = "#";
+ const char *sharp = "#";
Data_Get_Struct(method, struct METHOD, data);
str = rb_str_buf_new2("#<");
@@ -1615,12 +1595,11 @@
GetProcPtr(self, proc);
GetBindingPtr(bindval, bind);
- if (BUILTIN_TYPE(proc->block.iseq) == T_NODE) {
+ if (TYPE(proc->block.iseq) == T_NODE) {
rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
}
bind->env = proc->envval;
- bind->cref_stack = proc->special_cref_stack;
return bindval;
}
Modified: MacRuby/trunk/process.c
===================================================================
--- MacRuby/trunk/process.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/process.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2676,6 +2676,10 @@
else {
status = proc_spawn_n(argc, argv, prog);
}
+# if defined(_WIN32)
+ if (status == -1)
+ rb_last_status_set(0x7f << 8, 0);
+# endif
# else
if (argc) prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
status = system(StringValuePtr(prog));
Modified: MacRuby/trunk/rational.c
===================================================================
--- MacRuby/trunk/rational.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/rational.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -1371,7 +1371,7 @@
VALUE l;
while (*p) {
- if (isdigit(*p))
+ if (rb_isdigit(*p))
count++;
p++;
}
Modified: MacRuby/trunk/re.c
===================================================================
--- MacRuby/trunk/re.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/re.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
re.c -
- $Author: matz $
+ $Author: mame $
created at: Mon Aug 9 18:24:49 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -325,7 +325,9 @@
static void
rb_reg_expr_str(VALUE str, const char *s, long len)
{
+#if !WITH_OBJC
rb_encoding *enc = rb_enc_get(str);
+#endif
const char *p, *pend;
int need_escape = 0;
int c, clen;
@@ -924,6 +926,14 @@
rm->char_offset_updated = 1;
}
+static void
+match_check(VALUE match)
+{
+ if (!RMATCH(match)->regexp) {
+ rb_raise(rb_eTypeError, "uninitialized Match");
+ }
+}
+
/* :nodoc: */
static VALUE
match_init_copy(VALUE obj, VALUE orig)
@@ -939,9 +949,6 @@
RMATCH(obj)->regexp = RMATCH(orig)->regexp;
rm = RMATCH(obj)->rmatch;
- onig_region_free(&rm->regs, 0);
- rm->regs.allocated = 0;
-
onig_region_copy(&rm->regs, RMATCH_REGS(orig));
if (!RMATCH(orig)->rmatch->char_offset_updated) {
@@ -974,6 +981,7 @@
static VALUE
match_regexp(VALUE match)
{
+ match_check(match);
return RMATCH(match)->regexp;
}
@@ -994,6 +1002,7 @@
static VALUE
match_names(VALUE match)
{
+ match_check(match);
return rb_reg_names(RMATCH(match)->regexp);
}
@@ -1012,6 +1021,7 @@
static VALUE
match_size(VALUE match)
{
+ match_check(match);
return INT2FIX(RMATCH_REGS(match)->num_regs);
}
@@ -1024,6 +1034,7 @@
struct re_registers *regs = RMATCH_REGS(match);
VALUE regexp = RMATCH(match)->regexp;
+ match_check(match);
switch(TYPE(backref)) {
default:
return NUM2INT(backref);
@@ -1074,6 +1085,7 @@
int i = match_backref_number(match, n);
struct re_registers *regs = RMATCH_REGS(match);
+ match_check(match);
if (i < 0 || regs->num_regs <= i)
rb_raise(rb_eIndexError, "index %d out of matches", i);
@@ -1109,6 +1121,7 @@
int i = match_backref_number(match, n);
struct re_registers *regs = RMATCH_REGS(match);
+ match_check(match);
if (i < 0 || regs->num_regs <= i)
rb_raise(rb_eIndexError, "index %d out of matches", i);
@@ -1143,6 +1156,7 @@
int i = match_backref_number(match, n);
struct re_registers *regs = RMATCH_REGS(match);
+ match_check(match);
if (i < 0 || regs->num_regs <= i)
rb_raise(rb_eIndexError, "index %d out of matches", i);
@@ -1203,7 +1217,7 @@
rb_reg_preprocess(const char *p, const char *end, rb_encoding *enc,
rb_encoding **fixed_enc, onig_errmsg_buffer err);
-
+#if !WITH_OBJC
static void
reg_enc_error(VALUE re, VALUE str)
{
@@ -1212,6 +1226,7 @@
rb_enc_name(rb_enc_get(re)),
rb_enc_name(rb_enc_get(str)));
}
+#endif
static rb_encoding*
rb_reg_prepare_enc(VALUE re, VALUE str, int warn)
@@ -1302,7 +1317,9 @@
{
int range;
rb_encoding *enc;
+#if !WITH_OBJC
UChar *p, *string;
+#endif
enc = rb_reg_prepare_enc(re, str, 0);
@@ -1430,6 +1447,7 @@
{
struct re_registers *regs;
if (NIL_P(match)) return Qnil;
+ match_check(match);
regs = RMATCH_REGS(match);
if (nth >= regs->num_regs) {
return Qnil;
@@ -1450,6 +1468,7 @@
struct re_registers *regs;
if (NIL_P(match)) return Qnil;
+ match_check(match);
regs = RMATCH_REGS(match);
if (nth >= regs->num_regs) {
return Qnil;
@@ -1492,6 +1511,7 @@
struct re_registers *regs;
if (NIL_P(match)) return Qnil;
+ match_check(match);
regs = RMATCH_REGS(match);
if (BEG(0) == -1) return Qnil;
str = rb_str_subseq(RMATCH(match)->str, 0, BEG(0));
@@ -1519,6 +1539,7 @@
struct re_registers *regs;
if (NIL_P(match)) return Qnil;
+ match_check(match);
regs = RMATCH_REGS(match);
if (BEG(0) == -1) return Qnil;
str = RMATCH(match)->str;
@@ -1535,6 +1556,7 @@
struct re_registers *regs;
if (NIL_P(match)) return Qnil;
+ match_check(match);
regs = RMATCH_REGS(match);
if (BEG(0) == -1) return Qnil;
@@ -1577,6 +1599,7 @@
int i;
int taint = OBJ_TAINTED(match);
+ match_check(match);
for (i=start; i<regs->num_regs; i++) {
if (regs->beg[i] == -1) {
rb_ary_push(ary, Qnil);
@@ -1645,18 +1668,18 @@
static int
name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name, const char* name_end)
{
- int num;
+ int num;
- num = onig_name_to_backref_number(RREGEXP(regexp)->ptr,
- (const unsigned char* )name, (const unsigned char* )name_end, regs);
- if (num >= 1) {
- return num;
- }
- else {
- VALUE s = rb_str_new(name, (long )(name_end - name));
- rb_raise(rb_eIndexError, "undefined group name reference: %s",
- StringValuePtr(s));
- }
+ num = onig_name_to_backref_number(RREGEXP(regexp)->ptr,
+ (const unsigned char* )name, (const unsigned char* )name_end, regs);
+ if (num >= 1) {
+ return num;
+ }
+ else {
+ VALUE s = rb_str_new(name, (long )(name_end - name));
+ rb_raise(rb_eIndexError, "undefined group name reference: %s",
+ StringValuePtr(s));
+ }
}
/*
@@ -1690,6 +1713,7 @@
{
VALUE idx, rest;
+ match_check(match);
rb_scan_args(argc, argv, "11", &idx, &rest);
if (NIL_P(rest)) {
@@ -1749,6 +1773,7 @@
match_values_at(int argc, VALUE *argv, VALUE match)
{
struct re_registers *regs = RMATCH_REGS(match);
+ match_check(match);
return rb_get_values_at(match, regs->num_regs, argc, argv, match_entry);
}
@@ -1768,6 +1793,7 @@
{
VALUE str = rb_reg_last_match(match);
+ match_check(match);
if (NIL_P(str)) str = rb_str_new(0,0);
if (OBJ_TAINTED(match)) OBJ_TAINT(str);
if (OBJ_TAINTED(RMATCH(match)->str)) OBJ_TAINT(str);
@@ -1788,6 +1814,7 @@
static VALUE
match_string(VALUE match)
{
+ match_check(match);
return RMATCH(match)->str; /* str is frozen */
}
@@ -1833,7 +1860,7 @@
static VALUE
match_inspect(VALUE match)
{
- char *cname = rb_obj_classname(match);
+ const char *cname = rb_obj_classname(match);
VALUE str;
int i;
struct re_registers *regs = RMATCH_REGS(match);
@@ -1997,7 +2024,9 @@
char *chbuf = ALLOCA_N(char, chmaxlen);
int chlen = 0;
int byte;
+#if !WITH_OBJC
int l;
+#endif
memset(chbuf, 0, chmaxlen);
@@ -2899,7 +2928,9 @@
VALUE
rb_reg_quote(VALUE str)
{
+#if !WITH_OBJC
rb_encoding *enc = rb_enc_get(str);
+#endif
const char *s, *send;
char *t;
VALUE tmp;
@@ -3103,7 +3134,9 @@
else {
int i;
VALUE source = rb_str_buf_new(0);
+#if !WITH_OBJC
rb_encoding *result_enc;
+#endif
int has_asciionly = 0;
rb_encoding *has_ascii_compat_fixed = 0;
Modified: MacRuby/trunk/regenc.h
===================================================================
--- MacRuby/trunk/regenc.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/regenc.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -70,7 +70,7 @@
#define ONIG_CHECK_NULL_RETURN(p) if (ONIG_IS_NULL(p)) return NULL
#define ONIG_CHECK_NULL_RETURN_VAL(p,val) if (ONIG_IS_NULL(p)) return (val)
-#define enclen(enc,p,e) ONIGENC_MBC_ENC_LEN(enc,p,e)
+#define enclen(enc,p,e) ((enc->max_enc_len == enc->min_enc_len) ? enc->min_enc_len : ONIGENC_MBC_ENC_LEN(enc,p,e))
/* character types bit flag */
#define BIT_CTYPE_NEWLINE (1<< ONIGENC_CTYPE_NEWLINE)
Modified: MacRuby/trunk/regerror.c
===================================================================
--- MacRuby/trunk/regerror.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/regerror.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -41,7 +41,7 @@
extern UChar*
onig_error_code_to_format(int code)
{
- char *p;
+ const char *p;
if (code >= 0) return (UChar* )0;
Modified: MacRuby/trunk/regexec.c
===================================================================
--- MacRuby/trunk/regexec.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/regexec.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2741,16 +2741,25 @@
s = (UChar* )text;
+ if (enc->max_enc_len == enc->min_enc_len) {
+ int n = enc->max_enc_len;
+
+ while (s < end) {
+ if (*s == *target) {
+ p = s + 1;
+ t = target + 1;
+ if (target_end == t || memcmp(t, p, target_end - t) == 0)
+ return s;
+ }
+ s += n;
+ }
+ return (UChar*)NULL;
+ }
while (s < end) {
if (*s == *target) {
p = s + 1;
t = target + 1;
- while (t < target_end) {
- if (*t != *p++)
- break;
- t++;
- }
- if (t == target_end)
+ if (target_end == t || memcmp(t, p, target_end - t) == 0)
return s;
}
s += enclen(enc, s, end);
Modified: MacRuby/trunk/ruby.c
===================================================================
--- MacRuby/trunk/ruby.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/ruby.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -72,6 +72,11 @@
disable_rubyopt,
};
+#define DUMP_BIT(bit) (1U << dump_##bit)
+enum dump_flag_bits {
+ dump_insns,
+};
+
struct cmdline_options {
int sflag, xflag;
int do_loop, do_print;
@@ -83,7 +88,8 @@
unsigned int disable;
int verbose;
int yydebug;
- char *script;
+ unsigned int dump;
+ const char *script;
VALUE script_name;
VALUE e_script;
struct {
@@ -592,6 +598,14 @@
rb_warn("unknown argument for --disable: `%.*s'", len, str);
}
+static void
+dump_option(const char *str, int len, void *arg)
+{
+#define SET_WHEN_DUMP(bit) SET_WHEN(#bit, DUMP_BIT(bit), str, len)
+ SET_WHEN_DUMP(insns);
+ rb_warn("don't know how to dump `%.*s', (insns)", len, str);
+}
+
static int
proc_options(int argc, char **argv, struct cmdline_options *opt)
{
@@ -879,6 +893,10 @@
}
else if (strcmp("yydebug", s) == 0)
opt->yydebug = 1;
+ else if (strncmp("dump", s, n = 4) == 0 && (!s[n] || s[n] == '=')) {
+ if (!(s += n + 1)[-1] && (!--argc || !(s = *++argv)) && *s != '-') break;
+ ruby_each_words(s, dump_option, &opt->dump);
+ }
else if (strcmp("help", s) == 0) {
usage(origarg.argv[0]);
rb_exit(EXIT_SUCCESS);
@@ -971,6 +989,7 @@
char **argv = argp->argv;
NODE *tree = 0;
VALUE parser;
+ VALUE iseq;
rb_encoding *enc, *lenc;
const char *s;
char fbuf[MAXPATHLEN];
@@ -1168,8 +1187,16 @@
tree = rb_parser_while_loop(parser, tree, opt->do_line, opt->do_split);
}
- return rb_iseq_new(tree, rb_str_new2("<main>"),
+ iseq = rb_iseq_new(tree, rb_str_new2("<main>"),
opt->script_name, Qfalse, ISEQ_TYPE_TOP);
+
+ if (opt->dump & DUMP_BIT(insns)) {
+ rb_io_write(rb_stdout, ruby_iseq_disasm(iseq));
+ rb_io_flush(rb_stdout);
+ return Qtrue;
+ }
+
+ return iseq;
}
static NODE *
@@ -1403,7 +1430,6 @@
set_arg0(VALUE val, ID id)
{
const char *s;
- char *t;
long i;
if (origarg.argv == 0)
@@ -1434,13 +1460,13 @@
}
memcpy(origarg.argv[0], s, i);
- t = origarg.argv[0] + i;
- *t = '\0';
- if (i + 1 < origarg.len) memset(t + 1, ' ', origarg.len - i - 1);
-
{
int j;
+ char *t = origarg.argv[0] + i;
+ *t = '\0';
+
+ if (i + 1 < origarg.len) memset(t + 1, ' ', origarg.len - i - 1);
for (j = 1; j < origarg.argc; j++) {
origarg.argv[j] = t;
}
Modified: MacRuby/trunk/sample-macruby/CircleView/CircleView.rb
===================================================================
--- MacRuby/trunk/sample-macruby/CircleView/CircleView.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/sample-macruby/CircleView/CircleView.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -159,12 +159,26 @@
# We schedule a timer for a desired 30fps animation rate.
# In performAnimation: we determine exactly
# how much time has elapsed and animate accordingly.
+
+=begin
+ @timer = NSTimer.timerWithTimeInterval 1.0/30.0,
+ target:self,
+ selector:'performAnimation:',
+ userInfo:nil,
+ repeats:true
+=end
+
+ #@timer = Foo.foo(self)
+
+#=begin
@timer = NSTimer.scheduledTimerWithTimeInterval 1.0/30.0,
target:self,
selector:'performAnimation:',
userInfo:nil,
repeats:true
-
+#=end
+ p @timer
+
# The next two lines make sure that animation will continue to occur
# while modal panels are displayed and while event tracking is taking
# place (for example, while a slider is being dragged).
Modified: MacRuby/trunk/sample-macruby/CircleView/main.m
===================================================================
--- MacRuby/trunk/sample-macruby/CircleView/main.m 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/sample-macruby/CircleView/main.m 2008-06-05 08:11:58 UTC (rev 247)
@@ -8,6 +8,16 @@
#import <MacRuby/MacRuby.h>
+#import <Cocoa/Cocoa.h>
+ at interface Foo
+ at end
+ at implementation Foo
++(id)foo:(id)rcv
+{
+ return [NSTimer scheduledTimerWithTimeInterval:1.0/30.0 target:rcv selector:@selector(performAnimation:) userInfo:nil repeats:true];
+}
+ at end
+
int main(int argc, char *argv[])
{
return macruby_main("rb_main.rb", argc, argv);
Modified: MacRuby/trunk/signal.c
===================================================================
--- MacRuby/trunk/signal.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/signal.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
signal.c -
- $Author: nobu $
+ $Author: mame $
created at: Tue Dec 20 10:13:44 JST 1994
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -222,6 +222,7 @@
if (argc > 0) {
sig = rb_check_to_integer(argv[0], "to_int");
if (!NIL_P(sig)) argnum = 2;
+ else sig = argv[0];
}
if (argc < 1 || argnum < argc) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
@@ -252,9 +253,7 @@
if (!signo) {
rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm);
}
- if (SYMBOL_P(sig)) {
- sig = rb_str_new2(signm);
- }
+ sig = rb_sprintf("SIG%s", signm);
}
rb_call_super(1, &sig);
rb_iv_set(self, "signo", INT2NUM(signo));
@@ -262,7 +261,20 @@
return self;
}
+/*
+ * call-seq:
+ * signal_exception.signo => num
+ *
+ * Returns a signal number.
+ */
+
static VALUE
+esignal_signo(VALUE self)
+{
+ return rb_iv_get(self, "signo");
+}
+
+static VALUE
interrupt_init(int argc, VALUE *argv, VALUE self)
{
VALUE args[2];
@@ -1069,7 +1081,7 @@
rb_define_module_function(mSignal, "list", sig_list, 0);
rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
- rb_attr(rb_eSignal, rb_intern("signo"), 1, 0, 0);
+ rb_define_method(rb_eSignal, "signo", esignal_signo, 0);
rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
Modified: MacRuby/trunk/sprintf.c
===================================================================
--- MacRuby/trunk/sprintf.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/sprintf.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -21,6 +21,7 @@
#define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
#define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n)))
+#if !WITH_OBJC
static void fmt_setup(char*,int,int,int,int);
static char*
@@ -67,6 +68,7 @@
}
return c;
}
+#endif
#define FNONE 0
#define FSHARP 1
@@ -987,7 +989,6 @@
if (tainted) OBJ_TAINT(result);
return result;
}
-#endif
static void
fmt_setup(char *buf, int c, int flags, int width, int prec)
@@ -1058,6 +1059,7 @@
fp->_p = (unsigned char *)buf;
return 0;
}
+#endif
VALUE
rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/string.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
string.c -
- $Author: mame $
+ $Author: nobu $
created at: Mon Aug 9 17:12:58 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -181,7 +181,6 @@
CFIndex datalen;
const UInt8 *dataptr;
CFStringRef bytestr;
- const char *strptr;
data = (CFDataRef)cfdata;
datalen = CFDataGetLength(data);
@@ -921,7 +920,7 @@
{
VALUE orig;
- if (rb_scan_args(argc, argv, "01", &orig) == 1)
+ if (argc > 0 && rb_scan_args(argc, argv, "01", &orig) == 1)
rb_str_replace(str, orig);
return str;
}
@@ -1109,7 +1108,7 @@
static VALUE
rb_str_empty(VALUE str)
{
- if (CFStringGetLength((CFStringRef)str) == 0)
+ if (RSTRING_CLEN(str) == 0)
return Qtrue;
return Qfalse;
}
@@ -3045,13 +3044,10 @@
NEIGHBOR_NOT_CHAR is returned if invalid character or the range has only one
character.
*/
+#if !WITH_OBJC
static enum neighbor_char
enc_succ_alnum_char(char *p, int len, rb_encoding *enc, char *carry)
{
-#if WITH_OBJC
- /* TODO rewrite me */
- return NEIGHBOR_NOT_CHAR;
-#else
enum neighbor_char ret;
int c;
int ctype;
@@ -3103,10 +3099,9 @@
MEMCPY(carry, p, char, len);
enc_succ_char(carry, len, enc);
return NEIGHBOR_WRAPPED;
+}
#endif
-}
-
/*
* call-seq:
* str.succ => new_str
@@ -3319,10 +3314,13 @@
VALUE current, after_end;
ID succ;
int n, excl;
+#if !WITH_OBJC
rb_encoding *enc;
+#endif
rb_scan_args(argc, argv, "11", &end, &exclusive);
excl = RTEST(exclusive);
+ succ = rb_intern("succ");
StringValue(end);
#if WITH_OBJC
if (RSTRING_CLEN(beg) == 1 && RSTRING_CLEN(end) == 1) {
@@ -3364,7 +3362,6 @@
n = rb_str_cmp(beg, end);
if (n > 0 || (excl && n == 0)) return beg;
- succ = rb_intern("succ");
after_end = rb_funcall(end, succ, 0, 0);
current = beg;
while (!rb_str_equal(current, after_end)) {
@@ -3589,7 +3586,9 @@
{
VALUE match;
long start, end, len;
+#if !WITH_OBJC
rb_encoding *enc;
+#endif
struct re_registers *regs;
if (rb_reg_search(re, str, 0, 0) < 0) {
@@ -3824,7 +3823,6 @@
struct re_registers *regs;
int iter = 0;
int tainted = 0;
- long plen;
if (argc == 1 && rb_block_given_p()) {
iter = 1;
@@ -3843,8 +3841,8 @@
pat = get_pat(argv[0], 1);
if (rb_reg_search(pat, str, 0, 0) >= 0) {
+#if !WITH_OBJC
rb_encoding *enc;
-#if !WITH_OBJC
int cr = ENC_CODERANGE(str);
#endif
@@ -3894,6 +3892,7 @@
if (OBJ_TAINTED(repl)) tainted = 1;
#else
rb_enc_associate(str, enc);
+ if (OBJ_TAINTED(repl)) tainted = 1;
if (ENC_CODERANGE_UNKNOWN < cr && cr < ENC_CODERANGE_BROKEN) {
int cr2 = ENC_CODERANGE(repl);
if (cr2 == ENC_CODERANGE_UNKNOWN || cr2 > cr) cr = cr2;
@@ -3966,7 +3965,7 @@
VALUE pat, val, repl, match, dest, hash = Qnil;
struct re_registers *regs;
long beg, n;
- long offset, blen, slen, len;
+ long offset, slen, len;
int iter = 0;
const char *sp, *cp;
int tainted = 0;
@@ -4002,6 +4001,7 @@
slen = RSTRING_CLEN(str);
sp = RSTRING_CPTR(str);
cp = sp;
+ str_enc = NULL;
#else
blen = RSTRING_LEN(str) + 30; /* len + margin */
dest = rb_str_buf_new(blen);
@@ -4166,7 +4166,6 @@
VALUE
rb_str_replace(VALUE str, VALUE str2)
{
- long len;
if (str == str2) return str;
#if WITH_OBJC
rb_str_modify(str);
@@ -4646,7 +4645,9 @@
char *s;
const char *q;
+#if !WITH_OBJC
escape_codepoint:
+#endif
for (q = p-n; q < p; q++) {
s = buf;
sprintf(buf, "\\x%02X", *q & 0377);
@@ -4955,7 +4956,6 @@
CFStringRef tmp;
long i, n;
bool changed;
- UniChar c;
UniChar *buffer;
rb_str_modify(str);
@@ -5188,7 +5188,6 @@
{
int i;
long n;
- bool changed;
CFMutableCharacterSetRef charset;
CFRange search_range, result_range;
@@ -5416,12 +5415,13 @@
else {
/* TODO: support all syntaxes */
char sb, se, rb, re;
- long n;
bool s_is_range, r_is_range;
CFStringRef substr;
bool release_substr;
long delta;
+ sb = se = rb = re = 0;
+
if (_ctx->src_len == 3 && _ctx->src[1] == '-') {
sb = _ctx->src[0];
se = _ctx->src[2];
@@ -6224,7 +6224,6 @@
long beg, end, i = 0;
int lim = 0;
VALUE result, tmp;
- const char *cstr;
long clen;
#if !WITH_OBJC
@@ -6294,7 +6293,7 @@
#if WITH_OBJC
if (awk_split || spat_string) {
CFRange search_range;
- CFCharacterSetRef charset;
+ CFCharacterSetRef charset = NULL;
if (spat == Qnil)
charset = CFCharacterSetGetPredefined(
kCFCharacterSetWhitespaceAndNewline);
@@ -6525,7 +6524,6 @@
{
#if WITH_OBJC
VALUE rs;
- CFArrayRef ranges;
long n;
CFStringRef substr;
CFRange sub_range, search_range, res_range;
@@ -6953,7 +6951,7 @@
if (len == 0) return Qnil;
p = RSTRING_PTR(str);
e = p + len;
- if (rb_scan_args(argc, argv, "01", &rs) == 0) {
+ if (argc == 0) {
rs = rb_rs;
if (rs == rb_default_rs) {
smart_chomp:
@@ -7292,7 +7290,9 @@
static VALUE
scan_once(VALUE str, VALUE pat, long *start, long strlen, bool pat_is_string)
{
+#if !WITH_OBJC
rb_encoding *enc;
+#endif
VALUE result, match;
struct re_registers *regs;
long i;
@@ -7308,11 +7308,11 @@
CFRangeMake(*start, strlen - *start),
0,
&result_range)) {
- CFStringRef str = CFStringCreateWithSubstring(NULL,
+ CFStringRef substr = CFStringCreateWithSubstring(NULL,
(CFStringRef)str, result_range);
*start = result_range.location + result_range.length + 1;
- result = (VALUE)CFStringCreateMutableCopy(NULL, 0, str);
- CFRelease(str);
+ result = (VALUE)CFStringCreateMutableCopy(NULL, 0, substr);
+ CFRelease(substr);
CFMakeCollectable((CFTypeRef)result);
}
else {
@@ -7844,7 +7844,7 @@
{
long pos;
int regex = Qfalse;
- long strlen, seplen;
+ long strlen, seplen = 0;
if (TYPE(sep) == T_REGEXP) {
pos = rb_reg_search(sep, str, 0, 0);
@@ -7965,8 +7965,10 @@
rb_str_end_with(int argc, VALUE *argv, VALUE str)
{
int i;
+#if !WITH_OBJC
char *p, *s;
rb_encoding *enc;
+#endif
for (i=0; i<argc; i++) {
VALUE tmp = rb_check_string_type(argv[i]);
@@ -8540,8 +8542,7 @@
rb_define_method(rb_cString, "==", rb_str_equal, 1);
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);
#if 1
-/* FIXME remove me once we use the objc dispatch for everything
-/*#if !WITH_OBJC*/
+ /* FIXME remove me once we use the objc dispatch for everything */
rb_define_method(rb_cString, "hash", rb_str_hash_m, 0);
#endif
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
Modified: MacRuby/trunk/struct.c
===================================================================
--- MacRuby/trunk/struct.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/struct.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
struct.c -
- $Author: matz $
+ $Author: nobu $
created at: Tue Mar 22 18:44:30 JST 1995
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -227,7 +227,7 @@
}
VALUE
-rb_struct_define_without_accessor(char *class_name, VALUE super, rb_alloc_func_t alloc, ...)
+rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_func_t alloc, ...)
{
VALUE klass;
va_list ar;
@@ -483,7 +483,7 @@
static VALUE
inspect_struct(VALUE s, VALUE dummy, int recur)
{
- char *cname = rb_class2name(rb_obj_class(s));
+ const char *cname = rb_class2name(rb_obj_class(s));
VALUE str, members;
long i;
Modified: MacRuby/trunk/template/insns.inc.tmpl
===================================================================
--- MacRuby/trunk/template/insns.inc.tmpl 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/template/insns.inc.tmpl 2008-06-05 08:11:58 UTC (rev 247)
@@ -19,4 +19,3 @@
#define VM_INSTRUCTION_SIZE <%= @insns.size %>
-
Modified: MacRuby/trunk/test/erb/test_erb.rb
===================================================================
--- MacRuby/trunk/test/erb/test_erb.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/erb/test_erb.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -54,16 +54,16 @@
def _test_core(safe)
erb = @erb.new("hello")
- assert_equal(erb.result, "hello")
+ assert_equal("hello", erb.result)
erb = @erb.new("hello", safe, 0)
- assert_equal(erb.result, "hello")
+ assert_equal("hello", erb.result)
erb = @erb.new("hello", safe, 1)
- assert_equal(erb.result, "hello")
+ assert_equal("hello", erb.result)
erb = @erb.new("hello", safe, 2)
- assert_equal(erb.result, "hello")
+ assert_equal("hello", erb.result)
src = <<EOS
%% hi
@@ -159,7 +159,7 @@
def test_safe_04
erb = @erb.new('<%=$SAFE%>', 4)
- assert_equal(erb.result(TOPLEVEL_BINDING.taint), '4')
+ assert_equal('4', erb.result(TOPLEVEL_BINDING.taint))
end
class Foo; end
Modified: MacRuby/trunk/test/net/imap/test_imap.rb
===================================================================
--- MacRuby/trunk/test/net/imap/test_imap.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/net/imap/test_imap.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -81,6 +81,37 @@
end
end
+ def test_unexpected_eof
+ server = TCPServer.new(0)
+ port = server.addr[1]
+ Thread.start do
+ begin
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ sock.gets
+# sock.print("* BYE terminating connection\r\n")
+# sock.print("RUBY0001 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = Net::IMAP.new("localhost", :port => port)
+ assert_raise(EOFError) do
+ imap.logout
+ end
+ ensure
+ imap.disconnect if imap
+ end
+ ensure
+ server.close
+ end
+ end
+
private
def imaps_test
Modified: MacRuby/trunk/test/ruby/envutil.rb
===================================================================
--- MacRuby/trunk/test/ruby/envutil.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/envutil.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -34,11 +34,6 @@
LANG_ENVS = %w"LANG LC_ALL LC_CTYPE"
def rubyexec(*args)
- if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM
- flunk("cannot test in win32")
- return
- end
-
ruby = EnvUtil.rubybin
c = "C"
env = {}
@@ -77,9 +72,16 @@
module Assertions
public
def assert_normal_exit(testsrc, message = '')
- IO.popen([EnvUtil.rubybin, '-W0'], 'w') {|io|
- io.write testsrc
- }
+ in_c, in_p = IO.pipe
+ out_p, out_c = IO.pipe
+ pid = spawn(EnvUtil.rubybin, '-W0', STDIN=>in_c, STDOUT=>out_c, STDERR=>out_c)
+ in_c.close
+ out_c.close
+ in_p.write testsrc
+ in_p.close
+ msg = out_p.read
+ out_p.close
+ Process.wait pid
status = $?
faildesc = nil
if status.signaled?
@@ -89,9 +91,27 @@
if signame
sigdesc = "SIG#{signame} (#{sigdesc})"
end
- full_message = build_message(message, "killed by ?", sigdesc)
+ if status.coredump?
+ sigdesc << " (core dumped)"
+ end
+ if msg.empty?
+ full_message = build_message(message, "pid ? killed by ?",
+ pid,
+ AssertionMessage::Literal.new(sigdesc))
+ else
+ msg << "\n" if /\n\z/ !~ msg
+ full_message = build_message(message, "pid ? killed by ?\n?",
+ pid,
+ AssertionMessage::Literal.new(sigdesc),
+ AssertionMessage::Literal.new(msg.gsub(/^/, '| ')))
+ end
end
assert_block(full_message) { !status.signaled? }
+ ensure
+ in_c.close if in_c && !in_c.closed?
+ in_p.close if in_p && !in_p.closed?
+ out_c.close if out_c && !out_c.closed?
+ out_p.close if out_p && !out_p.closed?
end
end
end
Added: MacRuby/trunk/test/ruby/test_argf.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_argf.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_argf.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,695 @@
+require 'test/unit'
+require 'timeout'
+require 'tmpdir'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestArgf < Test::Unit::TestCase
+ def setup
+ @t1 = Tempfile.new("foo")
+ @t1.puts "1"
+ @t1.puts "2"
+ @t1.close
+ @t2 = Tempfile.new("bar")
+ @t2.puts "3"
+ @t2.puts "4"
+ @t2.close
+ @t3 = Tempfile.new("baz")
+ @t3.puts "5"
+ @t3.puts "6"
+ @t3.close
+ @tmps = [@t1, @t2, @t3]
+ end
+
+ def teardown
+ @tmps.each {|t|
+ bak = t.path + ".bak"
+ File.unlink bak if File.file? bak
+ }
+ end
+
+ def make_tempfile
+ t = Tempfile.new("foo")
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ @tmps << t
+ t
+ end
+
+ def ruby(*args)
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def test_argf
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF
+ b = a.dup
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 1]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 2]
+ a.rewind
+ b.rewind
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 3]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 4]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["3", 3, "3", 5]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["4", 4, "4", 6]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 7]
+ a.rewind
+ b.rewind
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 8]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["6", 6, "6", 9]
+ SRC
+ a = f.read.split("\n")
+ assert_equal('["1", 1, "1", 1]', a.shift)
+ assert_equal('["2", 2, "2", 2]', a.shift)
+ assert_equal('["1", 1, "1", 3]', a.shift)
+ assert_equal('["2", 2, "2", 4]', a.shift)
+ assert_equal('["3", 3, "3", 5]', a.shift)
+ assert_equal('["4", 4, "4", 6]', a.shift)
+ assert_equal('["5", 5, "5", 7]', a.shift)
+ assert_equal('["5", 5, "5", 8]', a.shift)
+ assert_equal('["6", 6, "6", 9]', a.shift)
+
+ # is this test OK? [ruby-dev:34445]
+ end
+ end
+
+ def test_lineno
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 3
+ a.rewind; p $. #=> 3
+ a.gets; p $. #=> 3
+ a.gets; p $. #=> 4
+ a.rewind; p $. #=> 4
+ a.gets; p $. #=> 3
+ a.lineno = 1000; p $. #=> 1000
+ a.gets; p $. #=> 1001
+ a.gets; p $. #=> 1002
+ $. = 2000
+ a.gets; p $. #=> 2001
+ a.gets; p $. #=> 2001
+ SRC
+ assert_equal("1,2,3,3,3,4,4,3,1000,1001,1002,2001,2001", f.read.chomp.gsub("\n", ","))
+ end
+ end
+
+ def test_lineno2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF.dup
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 1
+ a.rewind; p $. #=> 1
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 1
+ a.lineno = 1000; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 2
+ $. = 2000
+ a.gets; p $. #=> 2001
+ a.gets; p $. #=> 2000
+ SRC
+ assert_equal("1,2,1,1,1,2,1,1,2,2,2000,2000", f.read.chomp.gsub("\n", ","))
+ end
+ end
+
+ def test_inplace
+ EnvUtil.rubyexec("-", @t1.path, @t2.path, @t3.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "while line = ARGF.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("1.new\n2.new\n", File.read(@t1.path))
+ assert_equal("3.new\n4.new\n", File.read(@t2.path))
+ assert_equal("5.new\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal("3\n4\n", File.read(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+ end
+
+ def test_inplace2
+ EnvUtil.rubyexec("-", @t1.path, @t2.path, @t3.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p ARGF.inplace_mode"
+ w.puts "ARGF.inplace_mode = nil"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p ARGF.inplace_mode"
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p ARGF.inplace_mode"
+ w.puts "ARGF.inplace_mode = nil"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+ assert_equal("3\n4\n", File.read(@t2.path))
+ assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal(false, File.file?(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+ end
+
+ def test_inplace3
+ EnvUtil.rubyexec("-i.bak", "-", @t1.path, @t2.path, @t3.path) do |w, r, e|
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p $-i"
+ w.puts "$-i = nil"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p $-i"
+ w.puts "$-i = '.bak'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p $-i"
+ w.puts "$-i = nil"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+ assert_equal("3\n4\n", File.read(@t2.path))
+ assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal(false, File.file?(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+ end
+
+ def test_inplace_rename_impossible
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", t.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = '/\\\\'"
+ w.puts "while line = ARGF.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_match(/Can't rename .* to .*: .*. skipping file/, e.read)
+ assert_equal("", r.read)
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+ end
+ end
+
+ def test_inplace_no_backup
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", t.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = ''"
+ w.puts "while line = ARGF.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ end
+ end
+
+ def test_inplace_dup
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", t.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "f = ARGF.dup"
+ w.puts "while line = f.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ end
+ end
+
+ def test_inplace_stdin
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", "-") do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "f = ARGF.dup"
+ w.puts "while line = f.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_match("Can't do inplace edit for stdio; skipping", e.read)
+ assert_equal("", r.read)
+ end
+ end
+
+ def test_inplace_stdin2
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-") do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "while line = ARGF.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_match("Can't do inplace edit for stdio", e.read)
+ assert_equal("", r.read)
+ end
+ end
+
+ def test_encoding
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ p ARGF.external_encoding.is_a?(Encoding)
+ p ARGF.internal_encoding.is_a?(Encoding)
+ ARGF.gets
+ p ARGF.external_encoding.is_a?(Encoding)
+ p ARGF.internal_encoding
+ SRC
+ assert_equal("true\ntrue\ntrue\nnil\n", f.read)
+ end
+ end
+
+ def test_tell
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ loop do
+ p ARGF.tell
+ p ARGF.gets
+ end
+ rescue ArgumentError
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ [0, 2, 4, 2, 4, 2, 4].map {|i| i.to_s }.
+ zip((1..6).map {|i| '"' + i.to_s + '\n"' } + ["nil"]).flatten.
+ each do |x|
+ assert_equal(x, a.shift)
+ end
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_seek
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.seek(4)
+ p ARGF.gets #=> "3"
+ ARGF.seek(0, IO::SEEK_END)
+ p ARGF.gets #=> "5"
+ ARGF.seek(4)
+ p ARGF.gets #=> nil
+ begin
+ ARGF.seek(0)
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_set_pos
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.pos = 4
+ p ARGF.gets #=> "3"
+ ARGF.pos = 4
+ p ARGF.gets #=> "5"
+ ARGF.pos = 4
+ p ARGF.gets #=> nil
+ begin
+ ARGF.pos = 4
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_rewind
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.pos = 4
+ ARGF.rewind
+ p ARGF.gets #=> "1"
+ ARGF.pos = 4
+ p ARGF.gets #=> "3"
+ ARGF.pos = 4
+ p ARGF.gets #=> "5"
+ ARGF.pos = 4
+ p ARGF.gets #=> nil
+ begin
+ ARGF.rewind
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"1\n"', a.shift)
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_fileno
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ begin
+ ARGF.fileno
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ fd1, fd2, fd3, fd4, tag = a
+ assert_match(/^\d+$/, fd1)
+ assert_match(/^\d+$/, fd2)
+ assert_match(/^\d+$/, fd3)
+ assert_match(/^\d+$/, fd4)
+ assert_equal('end', tag)
+ end
+ end
+
+ def test_to_io
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ 8.times do
+ p ARGF.to_io
+ ARGF.gets
+ end
+ SRC
+ a = f.read.split("\n")
+ f11, f12, f13, f21, f22, f31, f32, f4 = a
+ assert_equal(f11, f12)
+ assert_equal(f11, f13)
+ assert_equal(f21, f22)
+ assert_equal(f31, f32)
+ assert_match(/\(closed\)/, f4)
+ f4.sub!(/ \(closed\)/, "")
+ assert_equal(f31, f4)
+ end
+ end
+
+ def test_eof
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ 8.times do
+ p ARGF.eof?
+ ARGF.gets
+ end
+ rescue IOError
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ ((%w(true false) * 4).take(7) + %w(end)).each do |x|
+ assert_equal(x, a.shift)
+ end
+ end
+ end
+
+ def test_read
+ ruby('-e', "p ARGF.read(8)", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
+ end
+ end
+
+ def test_read2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ ARGF.read(8, s)
+ p s
+ SRC
+ assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
+ end
+ end
+
+ def test_read3
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ nil while ARGF.gets
+ p ARGF.read
+ p ARGF.read(0, "")
+ SRC
+ assert_equal("nil\n\"\"\n", f.read)
+ end
+ end
+
+ def test_readpartial
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ begin
+ loop do
+ s << ARGF.readpartial(1)
+ t = ""; ARGF.readpartial(1, t); s << t
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_readpartial2
+ ruby('-e', <<-SRC) do |f|
+ s = ""
+ begin
+ loop do
+ s << ARGF.readpartial(1)
+ t = ""; ARGF.readpartial(1, t); s << t
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ f.puts("foo")
+ f.puts("bar")
+ f.puts("baz")
+ f.close_write
+ assert_equal("foo\nbar\nbaz\n", f.read)
+ end
+ end
+
+ def test_getc
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ while c = ARGF.getc
+ s << c
+ end
+ puts s
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_getbyte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ while c = ARGF.getbyte
+ s << c
+ end
+ p s
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_readchar
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ begin
+ while c = ARGF.readchar
+ s << c
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_readbyte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ s = []
+ while c = ARGF.readbyte
+ s << c
+ end
+ rescue EOFError
+ p s
+ end
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_each_line
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ ARGF.each_line {|l| s << l }
+ p s
+ SRC
+ assert_equal("[\"1\\n\", \"2\\n\", \"3\\n\", \"4\\n\", \"5\\n\", \"6\\n\"]\n", f.read)
+ end
+ end
+
+ def test_each_byte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ ARGF.each_byte {|c| s << c }
+ p s
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_each_char
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ ARGF.each_char {|c| s << c }
+ puts s
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_filename
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts ARGF.filename.dump
+ end while ARGF.gets
+ puts ARGF.filename.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_filename2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts $FILENAME.dump
+ end while ARGF.gets
+ puts $FILENAME.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_file
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts ARGF.file.path.dump
+ end while ARGF.gets
+ puts ARGF.file.path.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_binmode
+ ruby('-e', "ARGF.binmode; puts ARGF.read", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_skip
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ ARGF.skip
+ rescue
+ puts "cannot skip" # ???
+ end
+ puts ARGF.gets
+ ARGF.skip
+ puts ARGF.read
+ SRC
+ assert_equal("cannot skip\n1\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_close
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.close
+ puts ARGF.read
+ SRC
+ assert_equal("3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_closed
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ 3.times do
+ p ARGF.closed?
+ ARGF.gets
+ ARGF.gets
+ end
+ p ARGF.closed?
+ ARGF.gets
+ p ARGF.closed?
+ SRC
+ assert_equal("false\nfalse\nfalse\nfalse\ntrue\n", f.read)
+ end
+ end
+
+ def test_argv
+ ruby('-e', "p ARGF.argv; p $*", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
+ assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
+ end
+ end
+end
Modified: MacRuby/trunk/test/ruby/test_array.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_array.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_array.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -74,7 +74,7 @@
end
def test_split_0
- x = "The Boassert of Mormon"
+ x = "The Book of Mormon"
assert_equal(x.reverse, x.split(//).reverse!.join)
assert_equal(x.reverse, x.reverse!)
assert_equal("g:n:i:r:t:s: :e:t:y:b: :1", "1 byte string".split(//).reverse.join(":"))
@@ -539,6 +539,7 @@
def test_count
a = @cls[1, 2, 3, 1, 2]
+ assert_equal(5, a._count)
assert_equal(2, a._count(1))
assert_equal(3, a._count {|x| x % 2 == 1 })
assert_equal(2, a._count(1) {|x| x % 2 == 1 })
@@ -726,6 +727,20 @@
@cls[@cls[@cls[@cls[], at cls[]], at cls[@cls[]], at cls[]], at cls[@cls[@cls[]]]].flatten)
end
+ def test_flatten_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ o = Object.new
+ def o.to_ary() callcc {|k| @cont = k; [1,2,3]} end
+ begin
+ assert_equal([10, 20, 1, 2, 3, 30, 1, 2, 3, 40], [10, 20, o, 30, o, 40].flatten)
+ rescue => e
+ else
+ o.instance_eval {@cont}.call
+ end
+ assert_instance_of(RuntimeError, e, '[ruby-dev:34798]')
+ assert_match(/reentered/, e.message, '[ruby-dev:34798]')
+ end
+
def test_hash
a1 = @cls[ 'cat', 'dog' ]
a2 = @cls[ 'cat', 'dog' ]
@@ -813,14 +828,6 @@
assert_equal(@cls[], a)
end
- def test_nitems
- assert_equal(0, @cls[].nitems)
- assert_equal(1, @cls[1].nitems)
- assert_equal(1, @cls[1, nil].nitems)
- assert_equal(1, @cls[nil, 1].nitems)
- assert_equal(3, @cls[1, nil, nil, 2, nil, 3, nil].nitems)
- end
-
def test_pack
a = @cls[*%w( cat wombat x yy)]
assert_equal("catwomx yy ", a.pack("A3A3A3A3"))
@@ -1155,6 +1162,16 @@
assert_match(/reentered/, e.message, '[ruby-core:16679]')
end
+ def test_sort_with_replace
+ xary = (1..100).to_a
+ 100.times do
+ ary = (1..100).to_a
+ ary.sort! {|a,b| ary.replace(xary); a <=> b}
+ GC.start
+ assert_equal(xary, ary, '[ruby-dev:34732]')
+ end
+ end
+
def test_to_a
a = @cls[ 1, 2, 3 ]
a_id = a.__id__
@@ -1294,14 +1311,24 @@
assert_raise(SecurityError) do
Thread.new do
$SAFE = 4
- a.shift
+ a.shift
end.value
end
end
+ LONGP = [127, 63, 31, 15, 7].map {|x| 2**x-1 }.find do |x|
+ begin
+ [].first(x)
+ rescue ArgumentError
+ true
+ rescue RangeError
+ false
+ end
+ end
+
def test_ary_new
assert_raise(ArgumentError) { [].to_enum.first(-1) }
- assert_raise(ArgumentError) { [].to_enum.first(2**31-1) }
+ assert_raise(ArgumentError) { [].to_enum.first(LONGP) }
end
def test_try_convert
@@ -1314,7 +1341,7 @@
assert_nothing_raised { Array.new { } }
assert_equal([1, 2, 3], Array.new([1, 2, 3]))
assert_raise(ArgumentError) { Array.new(-1, 1) }
- assert_raise(ArgumentError) { Array.new(2**31-1, 1) }
+ assert_raise(ArgumentError) { Array.new(LONGP, 1) }
assert_equal([1, 1, 1], Array.new(3, 1))
assert_equal([1, 1, 1], Array.new(3) { 1 })
assert_equal([1, 1, 1], Array.new(3, 1) { 1 })
@@ -1322,8 +1349,8 @@
def test_aset
assert_raise(IndexError) { [0][-2] = 1 }
- assert_raise(ArgumentError) { [0][2**31-1] = 2 }
- assert_raise(ArgumentError) { [0][2**30-1] = 3 }
+ assert_raise(ArgumentError) { [0][LONGP] = 2 }
+ assert_raise(ArgumentError) { [0][(LONGP + 1) / 2 - 1] = 2 }
a = [0]
a[2] = 4
assert_equal([0, nil, 4], a)
@@ -1461,11 +1488,11 @@
end
def test_fill2
- assert_raise(ArgumentError) { [].fill(0, 1, 2**31-1) }
+ assert_raise(ArgumentError) { [].fill(0, 1, LONGP) }
end
def test_times
- assert_raise(ArgumentError) { [0, 0, 0, 0] * (2**29) }
+ assert_raise(ArgumentError) { [0, 0, 0, 0] * ((LONGP + 1) / 4) }
end
def test_equal
@@ -1484,10 +1511,6 @@
assert_equal(a.hash, b.hash)
end
- def test_nitems2
- assert_equal(3, [5,6,7,8,9].nitems { |x| x % 2 != 0 })
- end
-
def test_flatten2
a = []
a << a
@@ -1533,17 +1556,6 @@
assert_equal([5, 3, 1], r)
end
- def test_each2
- a = [0, 1, 2, 3, 4, 5]
- r = []
- a.each do |x|
- r << x
- a.pop
- a.pop
- end
- assert_equal([0, 1], r)
- end
-
def test_combination2
assert_raise(RangeError) do
(0..100).to_a.combination(50) {}
Added: MacRuby/trunk/test/ruby/test_big5.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_big5.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_big5.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestBig5 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("big5")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("big5"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
Modified: MacRuby/trunk/test/ruby/test_class.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_class.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_class.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,6 +1,10 @@
require 'test/unit'
+require_relative 'envutil'
class TestClass < Test::Unit::TestCase
+ def ruby(*r, &b)
+ EnvUtil.rubyexec(*r, &b)
+ end
# ------------------
# Various test classes
@@ -105,4 +109,46 @@
end
end
+ def test_check_inheritable
+ assert_raise(TypeError) { Class.new(Object.new) }
+
+ o = Object.new
+ c = class << o; self; end
+ assert_raise(TypeError) { Class.new(c) }
+
+ assert_nothing_raised { Class.new(Class) } # is it OK?
+ assert_raise(TypeError) { eval("class Foo < Class; end") }
+ end
+
+ def test_initialize_copy
+ c = Class.new
+ assert_raise(TypeError) { c.instance_eval { initialize_copy(1) } }
+
+ o = Object.new
+ c = class << o; self; end
+ assert_raise(TypeError) { c.dup }
+ end
+
+ def test_singleton_class
+ assert_raise(TypeError) { 1.extend(Module.new) }
+ assert_raise(TypeError) { :foo.extend(Module.new) }
+
+ ruby do |w, r, e|
+ w.puts "module Foo; def foo; :foo; end; end"
+ w.puts "false.extend(Foo)"
+ w.puts "true.extend(Foo)"
+ w.puts "p false.foo"
+ w.puts "p true.foo"
+ w.puts "p FalseClass.include?(Foo)"
+ w.puts "p TrueClass.include?(Foo)"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":foo\n:foo\ntrue\ntrue", r.read.chomp)
+ end
+ end
+
+ def test_uninitialized
+ assert_raise(TypeError) { Class.allocate.new }
+ assert_raise(TypeError) { Class.allocate.superclass }
+ end
end
Modified: MacRuby/trunk/test/ruby/test_continuation.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_continuation.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_continuation.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -51,5 +51,31 @@
c.call
}
end
+
+ def test_ary_flatten
+ assert_normal_exit %q{
+ require 'continuation'
+ n = 0
+ o = Object.new
+ def o.to_ary() callcc {|k| $k = k; [1,2,3]} end
+ [10,20,o,30,o,40].flatten.inspect
+ n += 1
+ $k.call if n < 100
+ }, '[ruby-dev:34798]'
+ end
+
+ def test_marshal_dump
+ assert_normal_exit %q{
+ require 'continuation'
+ n = 0
+ o = Object.new
+ def o.marshal_dump() callcc {|k| $k = k }; "fofof" end
+ a = [1,2,3,o,4,5,6]
+ Marshal.dump(a).inspect
+ n += 1
+ $k.call if n < 100
+ }, '[ruby-dev:34802]'
+ end
+
end
Added: MacRuby/trunk/test/ruby/test_cp949.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_cp949.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_cp949.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestCP949 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("cp949")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("cp949"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
Modified: MacRuby/trunk/test/ruby/test_enum.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_enum.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_enum.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -30,6 +30,7 @@
end
def test_count
+ assert_equal(5, @obj.count)
assert_equal(2, @obj.count(1))
assert_equal(3, @obj.count {|x| x % 2 == 1 })
assert_equal(2, @obj.count(1) {|x| x % 2 == 1 })
Added: MacRuby/trunk/test/ruby/test_euc_jp.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_euc_jp.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_euc_jp.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,20 @@
+# vim: set fileencoding=euc-jp
+
+require "test/unit"
+
+class TestEUC_JP < Test::Unit::TestCase
+ def test_mbc_case_fold
+ assert_match(/(\xA3\xE1)(a)\1\2/i, "\xA3\xE1a\xA3\xE1A")
+ assert_no_match(/(\xA3\xE1)(a)\1\2/i, "\xA3\xE1a\xA3\xC1A")
+ end
+
+ def test_property
+ assert_match(/\xA4\xA2{0}\p{Hiragana}{4}/, "\xA4Ҥ餬\xA4\xCA")
+ assert_no_match(/\xA4\xA2{0}\p{Hiragana}{4}/, "\xA5\xAB\xA5\xBF\xA5\xAB\xA5\xCA")
+ assert_no_match(/\xA4\xA2{0}\p{Hiragana}{4}/, "\xB4\xC1\xBB\xFA\xB4\xC1\xBB\xFA")
+ assert_no_match(/\xA4\xA2{0}\p{Katakana}{4}/, "\xA4Ҥ餬\xA4\xCA")
+ assert_match(/\xA4\xA2{0}\p{Katakana}{4}/, "\xA5\xAB\xA5\xBF\xA5\xAB\xA5\xCA")
+ assert_no_match(/\xA4\xA2{0}\p{Katakana}{4}/, "\xB4\xC1\xBB\xFA\xB4\xC1\xBB\xFA")
+ assert_raise(RegexpError) { Regexp.new('\xA4\xA2{0}\p{foobarbaz}') }
+ end
+end
Added: MacRuby/trunk/test/ruby/test_euc_kr.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_euc_kr.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_euc_kr.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestEucKr < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("euc-kr")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("euc-kr"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
Added: MacRuby/trunk/test/ruby/test_euc_tw.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_euc_tw.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_euc_tw.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestEucTw < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("euc-tw")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("euc-tw"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
Modified: MacRuby/trunk/test/ruby/test_eval.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_eval.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_eval.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -139,7 +139,7 @@
assert_equal 11, o.instance_eval("11")
assert_equal 12, o.instance_eval("@ivar")
- assert_raise(NameError) {o.instance_eval("@@cvar")}
+ assert_equal 13, o.instance_eval("@@cvar")
assert_equal 14, o.instance_eval("$gvar__eval")
assert_equal 15, o.instance_eval("Const")
assert_equal 16, o.instance_eval("7 + 9")
@@ -149,7 +149,7 @@
1.times {
assert_equal 12, o.instance_eval("@ivar")
- assert_raise(NameError) {o.instance_eval("@@cvar")}
+ assert_equal 13, o.instance_eval("@@cvar")
assert_equal 14, o.instance_eval("$gvar__eval")
assert_equal 15, o.instance_eval("Const")
}
@@ -169,7 +169,7 @@
assert_equal 11, o.instance_eval { 11 }
assert_equal 12, o.instance_eval { @ivar }
- assert_raise(NameError) {o.instance_eval{ @@cvar }}
+ assert_equal 13, o.instance_eval { @@cvar }
assert_equal 14, o.instance_eval { $gvar__eval }
assert_equal 15, o.instance_eval { Const }
assert_equal 16, o.instance_eval { 7 + 9 }
@@ -179,7 +179,7 @@
1.times {
assert_equal 12, o.instance_eval { @ivar }
- assert_raise(NameError) {o.instance_eval{ @@cvar }}
+ assert_equal 13, o.instance_eval { @@cvar }
assert_equal 14, o.instance_eval { $gvar__eval }
assert_equal 15, o.instance_eval { Const }
}
@@ -187,8 +187,10 @@
def test_instance_eval_cvar
[Object.new, [], 7, :sym, true, false, nil].each do |obj|
- assert_raise(NameError){obj.instance_eval("@@cvar")}
- assert_raise(NameError){obj.instance_eval{@@cvar}}
+ assert_equal(13, obj.instance_eval("@@cvar"))
+ assert_equal(13, obj.instance_eval{@@cvar})
+ # assert_raise(NameError){obj.instance_eval("@@cvar")}
+ # assert_raise(NameError){obj.instance_eval{@@cvar}}
end
end
@@ -339,9 +341,10 @@
end
def test_cvar_scope_with_instance_eval
+ # TODO: check
Fixnum.class_eval "@@test_cvar_scope_with_instance_eval = 1" # depends on [ruby-dev:24229]
@@test_cvar_scope_with_instance_eval = 4
- assert_equal(1, 1.instance_eval("@@test_cvar_scope_with_instance_eval"), "[ruby-dev:24223]")
+ assert_equal(4, 1.instance_eval("@@test_cvar_scope_with_instance_eval"), "[ruby-dev:24223]")
Fixnum.__send__(:remove_class_variable, :@@test_cvar_scope_with_instance_eval)
end
@@ -358,6 +361,19 @@
}
end
+ def test_define_method_block
+ cc = Class.new do
+ define_method(:foo) {|&block|
+ block.call if block
+ }
+ end
+
+ c = cc.new
+ x = "ng"
+ c.foo() {x = "ok"}
+ assert_equal("ok", x)
+ end
+
def test_eval_using_integer_as_binding
assert_raise(TypeError) { eval("", 1) }
end
Modified: MacRuby/trunk/test/ruby/test_file.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_file.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_file.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -115,4 +115,7 @@
}
end
+ def test_uninitialized
+ assert_raise(TypeError) { File::Stat.allocate.readable? }
+ end
end
Modified: MacRuby/trunk/test/ruby/test_file_exhaustive.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_file_exhaustive.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_file_exhaustive.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -20,7 +20,7 @@
end
begin
File.link(@file, @hardlinkfile)
- rescue NotImplementedError
+ rescue NotImplementedError, Errno::EINVAL # EINVAL for Windows Vista
@hardlinkfile = nil
end
end
@@ -411,6 +411,17 @@
def test_extname
assert(".test", File.extname(@file))
assert_equal("", File.extname("foo"))
+ assert_equal("", File.extname("/foo"))
+ assert_equal("", File.extname(".foo"))
+ assert_equal("", File.extname("/.foo"))
+ assert_equal("", File.extname("bar/.foo"))
+ assert_equal("", File.extname("/bar/.foo"))
+ assert_equal(".ext", File.extname("foo.ext"))
+ assert_equal(".ext", File.extname("/foo.ext"))
+ assert_equal(".ext", File.extname(".foo.ext"))
+ assert_equal(".ext", File.extname("/.foo.ext"))
+ assert_equal(".ext", File.extname("bar/.foo.ext"))
+ assert_equal(".ext", File.extname("/bar/.foo.ext"))
assert_equal("", File.extname(""))
if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM
assert_equal("", File.extname("foo "))
Added: MacRuby/trunk/test/ruby/test_gb18030.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_gb18030.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_gb18030.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,125 @@
+require "test/unit"
+
+class TestGB18030 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("gb18030")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\x81\x40").size)
+ assert_equal(1, s("\x81\x30\x81\x30").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0x8140, s("\x81\x40").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\x81\x40"), 0x8140.chr("gb18030"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\x81\x40)\\1"), "i")
+ assert_match(r, s("\x81\x40\x81\x40"))
+ end
+
+ def scheck(c, i)
+ assert_equal(s(c.reverse.take(c.size - i).join), s(c.reverse.join).chop)
+ end
+
+ def fcheck(c)
+ assert_raise(ArgumentError) { s(c.reverse.join).chop }
+ end
+
+ def test_left_adjust_char_head
+ # C1: 00-2f, 3a-3f, 7f, ff
+ # C2: 40-7e, 80
+ # C4: 30-39
+ # CM: 81-fe
+ c1 = "\x2f"
+ c2 = "\x40"
+ c4 = "\x30"
+ cm = "\x81"
+
+ # S_START-c1
+ # S_START-c2-S_one_C2-0
+ # S_START-c2-S_one_C2-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-cm-S_even_CM_one_CX-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-cm-S_even_CM_one_CX-cm-S_odd_CM_one_CX(rec)
+ # S_START-c4-S_one_C4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-c4-S_one_C4_odd_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-cm-S_even_CM_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-cm-S_even_CM_odd_CMC4-cm-S_odd_CM_odd_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-cm-S_even_CM_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-cm-S_even_CM_even_CMC4-cm-S_odd_CM_even_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-cm-S_even_CM_one_CX(rec)
+ # S_START-cm-S_one_CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-c4-S_odd_C4CM(rec)
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-cm-S_odd_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-cm-S_odd_CM_even_C4CM-cm-S_even_CM_even_C4CM(rec)
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-cm-S_odd_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-cm-S_odd_CM_odd_C4CM-cm-S_even_CM_odd_C4CM(rec)
+ # S_START-cm-S_one_CM-cm-S_odd_CM_one_CX(rec)
+
+ scheck([c1], 1)
+ scheck([c2], 1)
+ scheck([c2, c1], 1)
+ scheck([c2, cm, c1], 2)
+ scheck([c2, cm, cm, c1], 1)
+ scheck([c2, cm, cm, cm], 2)
+ scheck([c4], 1)
+ scheck([c4, c1], 1)
+ scheck([c4, cm], 2)
+ fcheck([c4, cm, c1])
+ fcheck([c4, cm, c4, c1])
+ scheck([c4, cm, c4, cm], 4)
+ scheck([c4, cm, c4, cm, c1], 4)
+ scheck([c4, cm, c4, cm, c4], 4)
+ scheck([c4, cm, c4, cm, c4, c1], 4)
+ fcheck([c4, cm, c4, cm, c4, cm])
+ fcheck([c4, cm, c4, cm, c4, cm, c1])
+ fcheck([c4, cm, c4, cm, c4, cm, c4])
+ scheck([c4, cm, c4, cm, c4, cm, cm, c1], 4)
+ fcheck([c4, cm, c4, cm, c4, cm, cm, cm])
+ fcheck([c4, cm, c4, cm, c4, cm, cm, cm, c1])
+ scheck([c4, cm, c4, cm, c4, cm, cm, cm, cm], 4)
+ fcheck([c4, cm, c4, cm, cm, c1])
+ scheck([c4, cm, c4, cm, cm, cm], 4)
+ scheck([c4, cm, c4, cm, cm, cm, c1], 4)
+ fcheck([c4, cm, c4, cm, cm, cm, cm])
+ scheck([c4, cm, cm], 1)
+ scheck([cm], 1)
+ fcheck([cm, c1])
+ fcheck([cm, c4, c1])
+ scheck([cm, c4, cm], 3)
+ fcheck([cm, c4, cm, c1])
+ fcheck([cm, c4, cm, c4])
+ fcheck([cm, c4, cm, c4, c1])
+ fcheck([cm, c4, cm, c4, cm])
+ fcheck([cm, c4, cm, c4, cm, c1])
+ fcheck([cm, c4, cm, c4, cm, c4])
+ fcheck([cm, c4, cm, c4, cm, cm, c1])
+ fcheck([cm, c4, cm, c4, cm, cm, cm])
+ fcheck([cm, c4, cm, c4, cm, cm, cm, c1])
+ fcheck([cm, c4, cm, c4, cm, cm, cm, cm])
+ fcheck([cm, c4, cm, cm, c1])
+ fcheck([cm, c4, cm, cm, cm])
+ fcheck([cm, c4, cm, cm, cm, c1])
+ fcheck([cm, c4, cm, cm, cm, cm])
+ scheck([cm, cm], 2)
+ end
+end
Added: MacRuby/trunk/test/ruby/test_gbk.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_gbk.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_gbk.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestGBK < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("gbk")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\x81\x40").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0x8140, s("\x81\x40").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\x81\x40"), 0x8140.chr("gbk"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\x81\x40)\\1"), "i")
+ assert_match(r, s("\x81\x40\x81\x40"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\x81\x40"), s("\x81\x40\x81\x40").chop)
+ end
+end
Modified: MacRuby/trunk/test/ruby/test_io.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_io.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_io.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -3,6 +3,9 @@
require 'io/nonblock'
require 'socket'
require 'stringio'
+require 'timeout'
+require 'tempfile'
+require_relative 'envutil'
class TestIO < Test::Unit::TestCase
def test_gets_rs
@@ -545,4 +548,679 @@
}
end
+ def safe_4
+ Thread.new do
+ Timeout.timeout(10) do
+ $SAFE = 4
+ yield
+ end
+ end.join
+ end
+
+ def pipe
+ r, w = IO.pipe
+ Timeout.timeout(10) do
+ yield(r, w)
+ end
+ ensure
+ r.close unless !r || r.closed?
+ w.close unless !w || w.closed?
+ end
+
+ def pipe2(&b)
+ a = []
+ a << IO.pipe while true
+ rescue Errno::EMFILE, Errno::ENFILE, Errno::ENOMEM
+ yield(*a.last)
+ ensure
+ a.each do |r, w|
+ r.close unless !r || r.closed?
+ w.close unless !w || w.closed?
+ end
+ end
+
+ def ruby(*args)
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def test_try_convert
+ assert_equal(STDOUT, IO.try_convert(STDOUT))
+ assert_equal(nil, IO.try_convert("STDOUT"))
+ end
+
+ def test_ungetc2
+ pipe do |r, w|
+ r.ungetc("0" * 10000)
+ w.write("1" * 10000)
+ w.close
+ assert_equal("0" * 10000 + "1" * 10000, r.read)
+ end
+ end
+
+ def test_write_non_writable
+ pipe do |r, w|
+ assert_raise(IOError) do
+ r.write "foobarbaz"
+ end
+ end
+ end
+
+ def test_dup
+ ruby do |f|
+ f2 = f.dup
+ f.puts "foo"
+ f2.puts "bar"
+ f.close_write
+ f2.close_write
+ assert_equal("foo\nbar\n", f.read)
+ assert_equal("", f2.read)
+ end
+
+ pipe2 do |r, w|
+ assert_raise(Errno::EMFILE, Errno::ENFILE, Errno::NOMEM) do
+ r2, w2 = r.dup, w.dup
+ end
+ end
+ end
+
+ def test_inspect
+ pipe do |r, w|
+ assert(r.inspect =~ /^#<IO:0x[0-9a-f]+>$/)
+ assert_raise(SecurityError) do
+ safe_4 { r.inspect }
+ end
+ end
+ end
+
+ def test_readpartial
+ pipe do |r, w|
+ w.write "foobarbaz"
+ w.close
+ assert_raise(ArgumentError) { r.readpartial(-1) }
+ assert_equal("fooba", r.readpartial(5))
+ r.readpartial(5, s = "")
+ assert_equal("rbaz", s)
+ end
+ end
+
+ def test_readpartial_error
+ pipe do |r, w|
+ s = ""
+ t = Thread.new { r.readpartial(5, s) }
+ 0 until s.size == 5
+ s.clear
+ w.write "foobarbaz"
+ w.close
+ assert_raise(RuntimeError) { t.join }
+ end
+ end
+
+ def test_read
+ pipe do |r, w|
+ w.write "foobarbaz"
+ w.close
+ assert_raise(ArgumentError) { r.read(-1) }
+ assert_equal("fooba", r.read(5))
+ r.read(nil, s = "")
+ assert_equal("rbaz", s)
+ end
+ end
+
+ def test_read_error
+ pipe do |r, w|
+ s = ""
+ t = Thread.new { r.read(5, s) }
+ 0 until s.size == 5
+ s.clear
+ w.write "foobarbaz"
+ w.close
+ assert_raise(RuntimeError) { t.join }
+ end
+ end
+
+ def test_write_nonblock
+ pipe do |r, w|
+ w.write_nonblock(1)
+ w.close
+ assert_equal("1", r.read)
+ end
+ end
+
+ def test_gets
+ pipe do |r, w|
+ w.write "foobarbaz"
+ w.close
+ assert_equal("", r.gets(0))
+ assert_equal("foobarbaz", r.gets(9))
+ end
+ end
+
+ def test_close_read
+ ruby do |f|
+ f.close_read
+ f.write "foobarbaz"
+ assert_raise(IOError) { f.read }
+ end
+ end
+
+ def test_close_read_pipe
+ pipe do |r, w|
+ r.close_read
+ assert_raise(Errno::EPIPE) { w.write "foobarbaz" }
+ end
+ end
+
+ def test_close_read_security_error
+ pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close_read }
+ end
+ end
+ end
+
+ def test_close_read_non_readable
+ pipe do |r, w|
+ assert_raise(IOError) do
+ w.close_read
+ end
+ end
+ end
+
+ def test_close_write
+ ruby do |f|
+ f.write "foobarbaz"
+ f.close_write
+ assert_equal("foobarbaz", f.read)
+ end
+ end
+
+ def test_close_write_security_error
+ pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close_write }
+ end
+ end
+ end
+
+ def test_close_write_non_readable
+ pipe do |r, w|
+ assert_raise(IOError) do
+ r.close_write
+ end
+ end
+ end
+
+ def test_pid
+ r, w = IO.pipe
+ assert_equal(nil, r.pid)
+ assert_equal(nil, w.pid)
+
+ pipe = IO.popen(EnvUtil.rubybin, "r+")
+ pid1 = pipe.pid
+ pipe.puts "p $$"
+ pipe.close_write
+ pid2 = pipe.read.chomp.to_i
+ assert_equal(pid2, pid1)
+ assert_equal(pid2, pipe.pid)
+ pipe.close
+ assert_raise(IOError) { pipe.pid }
+ end
+
+ def make_tempfile
+ t = Tempfile.new("foo")
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ t
+ end
+
+ def test_set_lineno
+ t = make_tempfile
+
+ ruby("-e", <<-SRC, t.path) do |f|
+ open(ARGV[0]) do |f|
+ p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.lineno = 1000; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.rewind; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.gets; p $.
+ end
+ SRC
+ assert_equal("nil,1,2,2,1001,1001,1001,1,2,3,3", f.read.chomp.gsub("\n", ","))
+ end
+
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ r.gets; assert_equal(1, $.)
+ r.gets; assert_equal(2, $.)
+ r.lineno = 1000; assert_equal(2, $.)
+ r.gets; assert_equal(1001, $.)
+ r.gets; assert_equal(1001, $.)
+ end
+ end
+
+ def test_readline
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ r.readline; assert_equal(1, $.)
+ r.readline; assert_equal(2, $.)
+ r.lineno = 1000; assert_equal(2, $.)
+ r.readline; assert_equal(1001, $.)
+ assert_raise(EOFError) { r.readline }
+ end
+ end
+
+ def test_each_char
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ a = []
+ r.each_char {|c| a << c }
+ assert_equal(%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"], a)
+ end
+ end
+
+ def test_lines
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ e = r.lines
+ assert_equal("foo\n", e.next)
+ assert_equal("bar\n", e.next)
+ assert_equal("baz\n", e.next)
+ assert_raise(StopIteration) { e.next }
+ end
+ end
+
+ def test_bytes
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ e = r.bytes
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c.ord, e.next)
+ end
+ assert_raise(StopIteration) { e.next }
+ end
+ end
+
+ def test_chars
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ e = r.chars
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c, e.next)
+ end
+ assert_raise(StopIteration) { e.next }
+ end
+ end
+
+ def test_readbyte
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c.ord, r.readbyte)
+ end
+ assert_raise(EOFError) { r.readbyte }
+ end
+ end
+
+ def test_readchar
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c, r.readchar)
+ end
+ assert_raise(EOFError) { r.readchar }
+ end
+ end
+
+ def test_close_on_exec
+ # xxx
+ ruby do |f|
+ assert_equal(false, f.close_on_exec?)
+ f.close_on_exec = true
+ assert_equal(true, f.close_on_exec?)
+ f.close_on_exec = false
+ assert_equal(false, f.close_on_exec?)
+ end
+
+ pipe do |r, w|
+ assert_equal(false, r.close_on_exec?)
+ r.close_on_exec = true
+ assert_equal(true, r.close_on_exec?)
+ r.close_on_exec = false
+ assert_equal(false, r.close_on_exec?)
+
+ assert_equal(false, w.close_on_exec?)
+ w.close_on_exec = true
+ assert_equal(true, w.close_on_exec?)
+ w.close_on_exec = false
+ assert_equal(false, w.close_on_exec?)
+ end
+ end
+
+ def test_close_security_error
+ pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close }
+ end
+ end
+ end
+
+ def test_sysseek
+ t = make_tempfile
+
+ open(t.path) do |f|
+ f.sysseek(-4, IO::SEEK_END)
+ assert_equal("baz\n", f.read)
+ end
+
+ open(t.path) do |f|
+ a = [f.getc, f.getc, f.getc]
+ a.reverse_each {|c| f.ungetc c }
+ assert_raise(IOError) { f.sysseek(1) }
+ end
+ end
+
+ def test_syswrite
+ t = make_tempfile
+
+ open(t.path, "w") do |f|
+ o = Object.new
+ def o.to_s; "FOO\n"; end
+ f.syswrite(o)
+ end
+ assert_equal("FOO\n", File.read(t.path))
+ end
+
+ def test_sysread
+ t = make_tempfile
+
+ open(t.path) do |f|
+ a = [f.getc, f.getc, f.getc]
+ a.reverse_each {|c| f.ungetc c }
+ assert_raise(IOError) { f.sysread(1) }
+ end
+ end
+
+ def test_flag
+ t = make_tempfile
+
+ assert_raise(ArgumentError) do
+ open(t.path, "z") { }
+ end
+
+ assert_raise(ArgumentError) do
+ open(t.path, "rr") { }
+ end
+ end
+
+ def test_sysopen
+ t = make_tempfile
+
+ fd = IO.sysopen(t.path)
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ assert_equal("foo\nbar\nbaz\n", f.read)
+ f.close
+
+ fd = IO.sysopen(t.path, "w", 0666)
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ f.write("FOO\n")
+ f.close
+
+ fd = IO.sysopen(t.path, "r")
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ assert_equal("FOO\n", f.read)
+ f.close
+ end
+
+ def test_open_redirect
+ o = Object.new
+ def o.to_open; self; end
+ assert_equal(o, open(o))
+ o2 = nil
+ open(o) do |f|
+ o2 = f
+ end
+ assert_equal(o, o2)
+ end
+
+ def test_open_pipe
+ open("|" + EnvUtil.rubybin, "r+") do |f|
+ f.puts "puts 'foo'"
+ f.close_write
+ assert_equal("foo\n", f.read)
+ end
+ end
+
+ def test_reopen
+ t = make_tempfile
+
+ pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.reopen(t.path) }
+ end
+ end
+ end
+
+ def test_foreach
+ a = []
+ IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ t = make_tempfile
+
+ a = []
+ IO.foreach(t.path, {:mode => "r" }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:open_args => [] }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:open_args => ["r"] }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+ end
+
+ def test_printf
+ pipe do |r, w|
+ printf(w, "foo %s baz\n", "bar")
+ w.close_write
+ assert_equal("foo bar baz\n", r.read)
+ end
+ end
+
+ def test_print
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", t.path) do |w, r, e|
+ w.puts "print while $<.gets"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("foo\nbar\nbaz\n", r.read)
+ end
+ end
+
+ def test_putc
+ pipe do |r, w|
+ w.putc "A"
+ w.putc "BC"
+ w.putc 68
+ w.close_write
+ assert_equal("ABD", r.read)
+ end
+
+ EnvUtil.rubyexec do |w, r, e|
+ w.puts "putc 65"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("A", r.read)
+ end
+ end
+
+ def test_puts_recursive_array
+ a = ["foo"]
+ a << a
+ pipe do |r, w|
+ w.puts a
+ w.close
+ assert_equal("foo\n[...]\n", r.read)
+ end
+ end
+
+ def test_display
+ pipe do |r, w|
+ "foo".display(w)
+ w.close
+ assert_equal("foo", r.read)
+ end
+
+ EnvUtil.rubyexec do |w, r, e|
+ w.puts "'foo'.display"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("foo", r.read)
+ end
+ end
+
+ def test_set_stdout
+ assert_raise(TypeError) { $> = Object.new }
+
+ EnvUtil.rubyexec do |w, r, e|
+ w.puts "$> = $stderr"
+ w.puts "puts 'foo'"
+ w.close
+ assert_equal("foo\n", e.read)
+ assert_equal("", r.read)
+ end
+ end
+
+ def test_initialize
+ t = make_tempfile
+
+ fd = IO.sysopen(t.path)
+ assert_kind_of(Integer, fd)
+ f = IO.new(fd, "w")
+ f.write("FOO\n")
+ f.close
+
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+
+ pipe do |r, w|
+ assert_raise(RuntimeError) do
+ o = Object.new
+ class << o; self; end.instance_eval do
+ define_method(:to_io) { r }
+ end
+ w.instance_eval { initialize(o) }
+ end
+ end
+
+ pipe do |r, w|
+ r, w = IO.new(r), IO.new(w)
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ assert_equal("foo\nbar\nbaz\n", r.read)
+ end
+
+ pipe do |r, w|
+ assert_raise(ArgumentError) { IO.new(r, "r+") }
+ end
+
+ f = open(t.path)
+ assert_raise(RuntimeError) do
+ f.instance_eval { initialize }
+ end
+ end
+
+ def test_new_with_block
+ EnvUtil.rubyexec do |w, r, e|
+ w.puts "r, w = IO.pipe"
+ w.puts "IO.new(r) {}"
+ w.close
+ assert_not_equal("", e.read)
+ assert_equal("", r.read)
+ end
+ end
+
+ def test_readline2
+ EnvUtil.rubyexec("-e", <<-SRC) do |w, r, e|
+ puts readline
+ puts readline
+ puts readline
+ begin
+ puts readline
+ rescue EOFError
+ puts "end"
+ end
+ SRC
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("foo\nbar\nbaz\nend\n", r.read)
+ end
+ end
+
+ def test_readlines
+ EnvUtil.rubyexec("-e", "p readlines") do |w, r, e|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("[\"foo\\n\", \"bar\\n\", \"baz\\n\"]\n", r.read)
+ end
+ end
+
+ def test_s_read
+ t = make_tempfile
+
+ assert_equal("bar\n", File.read(t.path, 4, 4))
+ end
+
+ def test_uninitialized
+ assert_raise(IOError) { IO.allocate.print "" }
+ end
end
Added: MacRuby/trunk/test/ruby/test_iso_8859.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_iso_8859.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_iso_8859.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,163 @@
+require 'test/unit'
+
+class TestISO8859 < Test::Unit::TestCase
+ ASSERTS = %q(
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ # assert_match(/^(\xdf)\1$/i, "\xdfss") # this must be bug...
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ ((0xc0..0xde).to_a - [0xd7]).each do |c|
+ c1 = c.chr("ENCODING")
+ c2 = (c + 0x20).chr("ENCODING")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ assert_match(/^\xff$/i, "\xff")
+ )
+
+ def test_iso_8859_1
+ eval("# encoding: iso8859-1\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-1"))
+ end
+
+ def test_iso_8859_2
+ eval("# encoding: iso8859-2\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-2"))
+ end
+
+ def test_iso_8859_3
+ eval(%q(# encoding: iso8859-3
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ [0xa1, 0xa6, *(0xa9..0xac), 0xaf].each do |c|
+ c1 = c.chr("iso8859-3")
+ c2 = (c + 0x10).chr("iso8859-3")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ([*(0xc0..0xde)] - [0xc3, 0xd0, 0xd7]).each do |c|
+ c1 = c.chr("iso8859-3")
+ c2 = (c + 0x20).chr("iso8859-3")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_4
+ eval("# encoding: iso8859-4\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-4"))
+ end
+
+ def test_iso_8859_5
+ eval(%q(# encoding: iso8859-5
+ (0xb0..0xcf).each do |c|
+ c1 = c.chr("iso8859-5")
+ c2 = (c + 0x20).chr("iso8859-5")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ((0xa1..0xaf).to_a - [0xad]).each do |c|
+ c1 = c.chr("iso8859-5")
+ c2 = (c + 0x50).chr("iso8859-5")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_6
+ eval(%q(# encoding: iso8859-6
+ [0xa4, 0xac, 0xbb, 0xbf, *(0xc1..0xda), *(0xe0..0xf2)].each do |c|
+ c1 = c.chr("iso8859-6")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_7
+ eval(%q(# encoding: iso8859-7
+ ((0xa0..0xfe).to_a - [0xae, 0xd2]).each do |c|
+ c1 = c.chr("iso8859-7")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ((0xc1..0xd9).to_a - [0xd2]).each do |c|
+ c1 = c.chr("iso8859-7")
+ c2 = (c + 0x20).chr("iso8859-7")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_8
+ eval(%q(# encoding: iso8859-8
+ [0xa0, *(0xa2..0xbe), *(0xdf..0xfa), 0xfc, 0xfd].each do |c|
+ c1 = c.chr("iso8859-8")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_9
+ eval(%q(# encoding: iso8859-9
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ ([*(0xc0..0xdc)] - [0xd7]).each do |c|
+ c1 = c.chr("iso8859-9")
+ c2 = (c + 0x20).chr("iso8859-9")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_10
+ eval("# encoding: iso8859-10\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-10"))
+ end
+
+ def test_iso_8859_11
+ eval(%q(# encoding: iso8859-11
+ [*(0xa0..0xda), *(0xdf..0xfb)].each do |c|
+ c1 = c.chr("iso8859-11")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_13
+ eval("# encoding: iso8859-13\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-13"))
+ end
+
+ def test_iso_8859_14
+ eval("# encoding: iso8859-14\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-14"))
+ end
+
+ def test_iso_8859_15
+ eval("# encoding: iso8859-15\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-15"))
+ end
+
+ def test_iso_8859_16
+ eval("# encoding: iso8859-16\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-16"))
+ end
+end
+
Added: MacRuby/trunk/test/ruby/test_koi8.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_koi8.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_koi8.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,22 @@
+require "test/unit"
+
+class TestKOI8 < Test::Unit::TestCase
+ ASSERTS = %q(
+ (0xc0..0xdf).each do |c|
+ c1 = c.chr("ENCODING")
+ c2 = (c + 0x20).chr("ENCODING")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ )
+
+ def test_koi8_r
+ eval("# encoding: koi8-r\n" + ASSERTS.gsub("ENCODING", "koi8-r"))
+ end
+
+ def test_koi8_u
+ eval("# encoding: koi8-u\n" + ASSERTS.gsub("ENCODING", "koi8-u"))
+ end
+end
Modified: MacRuby/trunk/test/ruby/test_m17n.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_m17n.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_m17n.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1233,4 +1233,13 @@
s.setbyte(-4, 0x84)
assert_equal(u("\xE3\x81\x84\xE3\x81\x84"), s)
end
+
+ def test_compatible
+ assert_equal(nil, Encoding.compatible?("",0), "moved from btest/knownbug")
+ end
+
+ def test_force_encoding
+ assert(("".center(1, "\x80".force_encoding("utf-8")); true),
+ "moved from btest/knownbug, [ruby-dev:33807]")
+ end
end
Modified: MacRuby/trunk/test/ruby/test_method.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_method.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_method.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -220,4 +220,14 @@
def test_caller_negative_level
assert_raise(ArgumentError) { caller(-1) }
end
+
+ def test_attrset_ivar
+ c = Class.new
+ c.class_eval { attr_accessor :foo }
+ o = c.new
+ o.method(:foo=).call(42)
+ assert_equal(42, o.foo)
+ assert_raise(ArgumentError) { o.method(:foo=).call(1, 2, 3) }
+ assert_raise(ArgumentError) { o.method(:foo).call(1) }
+ end
end
Modified: MacRuby/trunk/test/ruby/test_module.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_module.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_module.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -68,6 +68,10 @@
list.reject {|c| c == PP::ObjectMixin }
end
+ def remove_json_mixins(list)
+ list.reject {|c| c.to_s.start_with?("JSON") }
+ end
+
module Mixin
MIXIN = 1
def mixin
@@ -194,9 +198,10 @@
assert_equal([User, Mixin], User.ancestors)
assert_equal([Mixin], Mixin.ancestors)
- assert_equal([Object, Kernel, BasicObject], remove_pp_mixins(Object.ancestors))
+ assert_equal([Object, Kernel, BasicObject],
+ remove_json_mixins(remove_pp_mixins(Object.ancestors)))
assert_equal([String, Comparable, Object, Kernel, BasicObject],
- remove_pp_mixins(String.ancestors))
+ remove_json_mixins(remove_pp_mixins(String.ancestors)))
end
def test_class_eval
@@ -242,9 +247,10 @@
def test_included_modules
assert_equal([], Mixin.included_modules)
assert_equal([Mixin], User.included_modules)
- assert_equal([Kernel], remove_pp_mixins(Object.included_modules))
+ assert_equal([Kernel],
+ remove_json_mixins(remove_pp_mixins(Object.included_modules)))
assert_equal([Comparable, Kernel],
- remove_pp_mixins(String.included_modules))
+ remove_json_mixins(remove_pp_mixins(String.included_modules)))
end
def test_instance_methods
@@ -690,4 +696,23 @@
o.extend(m2)
assert_equal(true, o.respond_to?(:foo))
end
+
+ def test_cyclic_include
+ m1 = Module.new
+ m2 = Module.new
+ m1.instance_eval { include(m2) }
+ assert_raise(ArgumentError) do
+ m2.instance_eval { include(m1) }
+ end
+ end
+
+ def test_include_p
+ m = Module.new
+ c1 = Class.new
+ c1.instance_eval { include(m) }
+ c2 = Class.new(c1)
+ assert_equal(true, c1.include?(m))
+ assert_equal(true, c2.include?(m))
+ assert_equal(false, m.include?(m))
+ end
end
Modified: MacRuby/trunk/test/ruby/test_numeric.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_numeric.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_numeric.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -60,9 +60,9 @@
def %(x); :mod; end
end
- assert_equal(42, DummyNumeric.new.div(0))
- assert_equal(:mod, DummyNumeric.new.modulo(0))
- assert_equal([42, :mod], DummyNumeric.new.divmod(0))
+ assert_equal(42, DummyNumeric.new.div(1))
+ assert_equal(:mod, DummyNumeric.new.modulo(1))
+ assert_equal([42, :mod], DummyNumeric.new.divmod(1))
assert_kind_of(Integer, 11.divmod(3.5).first, '[ruby-dev:34006]')
Modified: MacRuby/trunk/test/ruby/test_objectspace.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_objectspace.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_objectspace.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -47,5 +47,10 @@
assert(h.values.all? {|x| x.is_a?(Integer) })
assert_raise(TypeError) { ObjectSpace.count_objects(1) }
+
+ h0 = {:T_FOO=>1000}
+ h = ObjectSpace.count_objects(h0)
+ assert_same(h0, h)
+ assert_equal(0, h0[:T_FOO])
end
end
Modified: MacRuby/trunk/test/ruby/test_pack.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_pack.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_pack.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -441,4 +441,8 @@
end.join
end
end
+
+ def test_length_too_big
+ assert_raise(RangeError) { [].pack("C100000000000000000000") }
+ end
end
Modified: MacRuby/trunk/test/ruby/test_proc.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_proc.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_proc.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -210,6 +210,18 @@
assert_equal(fib, [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89])
end
+ def test_curry_from_knownbug
+ a = lambda {|x, y, &b| b }
+ b = a.curry[1]
+
+ assert_equal(:ok,
+ if b.call(2){} == nil
+ :ng
+ else
+ :ok
+ end, 'moved from btest/knownbug, [ruby-core:15551]')
+ end
+
def test_dup_clone
b = proc {|x| x + "bar" }
class << b; attr_accessor :foo; end
Modified: MacRuby/trunk/test/ruby/test_process.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_process.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_process.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -697,7 +697,7 @@
File.open("result2", "w") {|t| t << "taki pid=#{$$} ppid=#{Process.ppid}" }
exit 8
End
- ret = system("#{RUBY} script1; #{RUBY} script2")
+ ret = system("#{RUBY} script1 || #{RUBY} script2")
status = $?
assert_equal(false, ret)
assert(status.exited?)
@@ -719,7 +719,7 @@
File.open("result2", "w") {|t| t << "take pid=#{$$} ppid=#{Process.ppid}" }
exit 8
End
- pid = spawn("#{RUBY} script1; #{RUBY} script2")
+ pid = spawn("#{RUBY} script1 || #{RUBY} script2")
Process.wait pid
status = $?
assert(status.exited?)
@@ -742,7 +742,7 @@
puts "tika pid=#{$$} ppid=#{Process.ppid}"
exit 8
End
- io = IO.popen("#{RUBY} script1; #{RUBY} script2")
+ io = IO.popen("#{RUBY} script1 || #{RUBY} script2")
result = io.read
io.close
status = $?
@@ -765,7 +765,7 @@
End
write_file("s", <<-"End")
ruby = #{RUBY.dump}
- exec("\#{ruby} script1; \#{ruby} script2")
+ exec("\#{ruby} script1 || \#{ruby} script2")
End
pid = spawn RUBY, "s"
Process.wait pid
Modified: MacRuby/trunk/test/ruby/test_regexp.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_regexp.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_regexp.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -272,7 +272,7 @@
Thread.new { $SAFE = 4; re.instance_eval { initialize(re) } }.join
end
- assert_equal(Encoding::ASCII_8BIT, Regexp.new("b..", nil, "n").encoding)
+ assert_equal(Encoding.find("ASCII-8BIT"), Regexp.new("b..", nil, "n").encoding)
assert_equal("bar", "foobarbaz"[Regexp.new("b..", nil, "n")])
assert_raise(RegexpError) { Regexp.new(")(") }
@@ -471,12 +471,12 @@
ss = [ss] unless ss.is_a?(Array)
ss.each do |e, s|
s ||= e
+ assert_match(re, s)
m = re.match(s)
- assert_kind_of(MatchData, m)
assert_equal(e, m[0])
end
fs = [fs] unless fs.is_a?(Array)
- fs.each {|s| assert_nil(re.match(s)) }
+ fs.each {|s| assert_no_match(re, s) }
end
def failcheck(re)
@@ -512,8 +512,53 @@
check(/\A\a\z/, "\007")
check(/\A\e\z/, "\033")
check(/\A\v\z/, "\v")
+ failcheck('(')
+ failcheck('(?foo)')
+ failcheck('/\p{foobarbazqux}/')
+ failcheck('/\p{foobarbazqux' + 'a' * 1000 + '}/')
+ failcheck('/[1-\w]/')
end
+ def test_exec
+ check(/A*B/, %w(B AB AAB AAAB), %w(A))
+ check(/\w*!/, %w(! a! ab! abc!), %w(abc))
+ check(/\w*\W/, %w(! a" ab# abc$), %w(abc))
+ check(/\w*\w/, %w(z az abz abcz), %w(!))
+ check(/[a-z]*\w/, %w(z az abz abcz), %w(!))
+ check(/[a-z]*\W/, %w(! a" ab# abc$), %w(A))
+ check(/((a|bb|ccc|dddd)(1|22|333|4444))/i, %w(a1 bb1 a22), %w(a2 b1))
+ check(/\u0080/, (1..4).map {|i| ["\u0080", "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080/, (2..4).map {|i| ["\u0080" * 2, "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080\u0080/, (3..4).map {|i| ["\u0080" * 3, "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080\u0080\u0080/, (4..4).map {|i| ["\u0080" * 4, "\u0080" * i] }, ["\u0081"])
+ check(/[^\u3042\u3043\u3044]/, %W(a b \u0080 \u3041 \u3045), %W(\u3042 \u3043 \u3044))
+ check(/a.+/m, %W(a\u0080 a\u0080\u0080 a\u0080\u0080\u0080), %W(a))
+ check(/a.+z/m, %W(a\u0080z a\u0080\u0080z a\u0080\u0080\u0080z), %W(az))
+ check(/abc\B.\Bxyz/, %w(abcXxyz abc0xyz), %w(abc|xyz abc-xyz))
+ check(/\Bxyz/, [%w(xyz abcXxyz), %w(xyz abc0xyz)], %w(abc xyz abc-xyz))
+ check(/abc\B/, [%w(abc abcXxyz), %w(abc abc0xyz)], %w(abc xyz abc-xyz))
+ failcheck('(?<foo>abc)\1')
+ check(/^(A+|B+)(?>\g<1>)*[BC]$/, %w(AC BC ABC BAC AABBC), %w(AABB))
+ check(/^(A+|B(?>\g<1>)*)[AC]$/, %w(AAAC BBBAAAAC), %w(BBBAAA))
+ check(/^()(?>\g<1>)*$/, "", "a")
+ check(/^(?>(?=a)(#{ "a" * 1000 }|))++$/, ["a" * 1000, "a" * 2000, "a" * 3000], ["", "a" * 500, "b" * 1000])
+ check(eval('/^(?:a?)?$/'), ["", "a"], ["aa"])
+ check(eval('/^(?:a+)?$/'), ["", "a", "aa"], ["ab"])
+ check(/^(?:a?)+?$/, ["", "a", "aa"], ["ab"])
+ check(/^a??[ab]/, [["a", "a"], ["a", "aa"], ["b", "b"], ["a", "ab"]], ["c"])
+ check(/^(?:a*){3,5}$/, ["", "a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa"], ["b"])
+ check(/^(?:a+){3,5}$/, ["aaa", "aaaa", "aaaaa", "aaaaaa"], ["", "a", "aa", "b"])
+ end
+
+ def test_parse_look_behind
+ check(/(?<=A)B(?=C)/, [%w(B ABC)], %w(aBC ABc aBc))
+ check(/(?<!A)B(?!C)/, [%w(B aBc)], %w(ABC aBC ABc))
+ failcheck('(?<=.*)')
+ failcheck('(?<!.*)')
+ check(/(?<=A|B.)C/, [%w(C AC), %w(C BXC)], %w(C BC))
+ check(/(?<!A|B.)C/, [%w(C C), %w(C BC)], %w(AC BXC))
+ end
+
def test_parse_kg
check(/\A(.)(.)\k<1>(.)\z/, %w(abac abab ....), %w(abcd aaba xxx))
check(/\A(.)(.)\k<-1>(.)\z/, %w(abbc abba ....), %w(abcd aaba xxx))
@@ -532,7 +577,22 @@
failcheck('()\k<-2>')
failcheck('()\g<-2>')
check(/\A(?<x>.)(?<x>.)\k<x>\z/, %w(aba abb), %w(abc .. ....))
+ check(/\A(?<x>.)(?<x>.)\k<x>\z/i, %w(aba ABa abb ABb), %w(abc .. ....))
check(/\k\g/, "kg")
+ failcheck('(.\g<1>)')
+ failcheck('(.\g<2>)')
+ failcheck('(?=\g<1>)')
+ failcheck('((?=\g<1>))')
+ failcheck('(\g<1>|.)')
+ failcheck('(.|\g<1>)')
+ check(/(!)(?<=(a)|\g<1>)/, ["!"], %w(a))
+ check(/^(a|b\g<1>c)$/, %w(a bac bbacc bbbaccc), %w(bbac bacc))
+ check(/^(a|b\g<2>c)(B\g<1>C){0}$/, %w(a bBaCc bBbBaCcCc bBbBbBaCcCcCc), %w(bBbBaCcC BbBaCcCc))
+ check(/\A(?<n>.|X\g<n>)(?<x>\g<n>){0}(?<y>\k<n+0>){0}\g<x>\g<y>\z/, "XXaXbXXa", %w(XXabXa abb))
+ check(/\A(?<n>.|X\g<n>)(?<x>\g<n>){0}(?<y>\k<n+1>){0}\g<x>\g<y>\z/, "XaXXbXXb", %w(aXXbXb aba))
+ failcheck('(?<x>)(?<x>)(\g<x>)')
+ check(/^(?<x>foo)(bar)\k<x>/, %w(foobarfoo), %w(foobar barfoo))
+ check(/^(?<a>f)(?<a>o)(?<a>o)(?<a>b)(?<a>a)(?<a>r)(?<a>b)(?<a>a)(?<a>z)\k<a>{9}$/, %w(foobarbazfoobarbaz foobarbazbazbarfoo foobarbazzabraboof), %w(foobar barfoo))
end
def test_parse_curly_brace
@@ -595,6 +655,7 @@
check(/\A[a-f&&[^b-c]&&[^e]]\z/, %w(a d f), %w(b c e g 0))
check(/\A[[^b-c]&&[^e]&&a-f]\z/, %w(a d f), %w(b c e g 0))
check(/\A[\n\r\t]\z/, ["\n", "\r", "\t"])
+ failcheck('[9-1]')
end
def test_posix_bracket
@@ -608,4 +669,90 @@
failcheck('[[:alpha:')
failcheck('[[:alp:]]')
end
+
+ def test_backward
+ assert_equal(3, "foobar".rindex(/b.r/i))
+ assert_equal(nil, "foovar".rindex(/b.r/i))
+ assert_equal(3, ("foo" + "bar" * 1000).rindex(/#{"bar"*1000}/))
+ assert_equal(4, ("foo\nbar\nbaz\n").rindex(/bar/i))
+ end
+
+ def test_uninitialized
+ assert_raise(TypeError) { Regexp.allocate.hash }
+ assert_raise(TypeError) { Regexp.allocate.eql? Regexp.allocate }
+ assert_raise(TypeError) { Regexp.allocate == Regexp.allocate }
+ assert_raise(TypeError) { Regexp.allocate =~ "" }
+ assert_equal(false, Regexp.allocate === Regexp.allocate)
+ assert_nil(~Regexp.allocate)
+ assert_raise(TypeError) { Regexp.allocate.match("") }
+ assert_raise(TypeError) { Regexp.allocate.to_s }
+ assert_raise(TypeError) { Regexp.allocate.inspect }
+ assert_raise(TypeError) { Regexp.allocate.source }
+ assert_raise(TypeError) { Regexp.allocate.casefold? }
+ assert_raise(TypeError) { Regexp.allocate.options }
+ assert_equal(Encoding.find("ASCII-8BIT"), Regexp.allocate.encoding)
+ assert_equal(false, Regexp.allocate.fixed_encoding?)
+ assert_raise(TypeError) { Regexp.allocate.names }
+ assert_raise(TypeError) { Regexp.allocate.named_captures }
+
+ assert_raise(TypeError) { MatchData.allocate.regexp }
+ assert_raise(TypeError) { MatchData.allocate.names }
+ assert_raise(TypeError) { MatchData.allocate.size }
+ assert_raise(TypeError) { MatchData.allocate.length }
+ assert_raise(TypeError) { MatchData.allocate.offset(0) }
+ assert_raise(TypeError) { MatchData.allocate.begin(0) }
+ assert_raise(TypeError) { MatchData.allocate.end(0) }
+ assert_raise(TypeError) { MatchData.allocate.to_a }
+ assert_raise(TypeError) { MatchData.allocate[:foo] }
+ assert_raise(TypeError) { MatchData.allocate.captures }
+ assert_raise(TypeError) { MatchData.allocate.values_at }
+ assert_raise(TypeError) { MatchData.allocate.pre_match }
+ assert_raise(TypeError) { MatchData.allocate.post_match }
+ assert_raise(TypeError) { MatchData.allocate.to_s }
+ assert_match(/^#<MatchData:.*>$/, MatchData.allocate.inspect)
+ assert_raise(TypeError) { MatchData.allocate.string }
+ $~ = MatchData.allocate
+ assert_raise(TypeError) { $& }
+ assert_raise(TypeError) { $` }
+ assert_raise(TypeError) { $' }
+ assert_raise(TypeError) { $+ }
+ end
+
+ def test_unicode
+ assert_match(/^\u3042{0}\p{Any}$/, "a")
+ assert_match(/^\u3042{0}\p{Any}$/, "\u3041")
+ assert_match(/^\u3042{0}\p{Any}$/, "\0")
+ assert_no_match(/^\u3042{0}\p{Any}$/, "\0\0")
+ assert_no_match(/^\u3042{0}\p{Any}$/, "")
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{' + "\u3042" + '}$/') }
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{' + 'a' * 1000 + '}$/') }
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{foobarbazqux}$/') }
+ assert_match(/^(\uff21)(a)\1\2$/i, "\uff21A\uff41a")
+ assert_no_match(/^(\uff21)\1$/i, "\uff21A")
+ assert_no_match(/^(\uff41)\1$/i, "\uff41a")
+ assert_match(/^\u00df$/i, "\u00df")
+ assert_match(/^\u00df$/i, "ss")
+ #assert_match(/^(\u00df)\1$/i, "\u00dfss") # this must be bug...
+ assert_match(/^\u00df{2}$/i, "\u00dfss")
+ assert_match(/^\u00c5$/i, "\u00c5")
+ assert_match(/^\u00c5$/i, "\u00e5")
+ assert_match(/^\u00c5$/i, "\u212b")
+ assert_match(/^(\u00c5)\1\1$/i, "\u00c5\u00e5\u212b")
+ assert_match(/^\u0149$/i, "\u0149")
+ assert_match(/^\u0149$/i, "\u02bcn")
+ #assert_match(/^(\u0149)\1$/i, "\u0149\u02bcn") # this must be bug...
+ assert_match(/^\u0149{2}$/i, "\u0149\u02bcn")
+ assert_match(/^\u0390$/i, "\u0390")
+ assert_match(/^\u0390$/i, "\u03b9\u0308\u0301")
+ #assert_match(/^(\u0390)\1$/i, "\u0390\u03b9\u0308\u0301") # this must be bug...
+ assert_match(/^\u0390{2}$/i, "\u0390\u03b9\u0308\u0301")
+ assert_match(/^\ufb05$/i, "\ufb05")
+ assert_match(/^\ufb05$/i, "\ufb06")
+ assert_match(/^\ufb05$/i, "st")
+ #assert_match(/^(\ufb05)\1\1$/i, "\ufb05\ufb06st") # this must be bug...
+ assert_match(/^\ufb05{3}$/i, "\ufb05\ufb06st")
+ assert_match(/^\u03b9\u0308\u0301$/i, "\u0390")
+ assert_nothing_raised { 0x03ffffff.chr("utf-8").size }
+ assert_nothing_raised { 0x7fffffff.chr("utf-8").size }
+ end
end
Added: MacRuby/trunk/test/ruby/test_require.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_require.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_require.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,235 @@
+require 'test/unit'
+
+require 'tempfile'
+require_relative 'envutil'
+
+class TestRequire < Test::Unit::TestCase
+ def ruby(*r, &b)
+ EnvUtil.rubyexec(*r, &b)
+ end
+
+ def test_require_invalid_shared_object
+ t = Tempfile.new(["test_ruby_test_require", ".so"])
+ t.puts "dummy"
+ t.close
+
+ ruby do |w, r, e|
+ w.puts "begin"
+ w.puts " require \"#{ t.path }\""
+ w.puts "rescue LoadError"
+ w.puts " p :ok"
+ w.puts "end"
+ w.close
+ assert_equal(":ok", r.read.chomp)
+ end
+ end
+
+ def test_require_too_long_filename
+ ruby do |w, r, e|
+ w.puts "begin"
+ w.puts " require '#{ "foo/" * 10000 }foo'"
+ w.puts "rescue LoadError"
+ w.puts " p :ok"
+ w.puts "end"
+ w.close
+ e.read
+ assert_equal(":ok", r.read.chomp)
+ end
+ end
+
+ def test_require_path_home
+ env_rubypath, env_home = ENV["RUBYPATH"], ENV["HOME"]
+
+ ENV["RUBYPATH"] = "~"
+ ENV["HOME"] = "/foo" * 10000
+ ruby("-S", "test_ruby_test_require") do |w, r, e|
+ w.close
+ e.read
+ assert_equal("", r.read)
+ end
+
+ ENV["RUBYPATH"] = "~" + "/foo" * 10000
+ ENV["HOME"] = "/foo"
+ ruby("-S", "test_ruby_test_require") do |w, r, e|
+ w.close
+ e.read
+ assert_equal("", r.read)
+ end
+
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ t.puts "p :ok"
+ t.close
+ ENV["RUBYPATH"] = "~"
+ ENV["HOME"], name = File.split(t.path)
+ ruby("-S", name) do |w, r, e|
+ w.close
+ assert_equal(":ok", r.read.chomp)
+ assert_equal("", e.read)
+ end
+
+ ensure
+ env_rubypath ? ENV["RUBYPATH"] = env_rubypath : ENV.delete("RUBYPATH")
+ env_home ? ENV["HOME"] = env_home : ENV.delete("HOME")
+ end
+
+ def test_define_class
+ begin
+ require "socket"
+ rescue LoadError
+ return
+ end
+
+ ruby do |w, r, e|
+ w.puts "BasicSocket = 1"
+ w.puts "begin"
+ w.puts " require 'socket'"
+ w.puts " p :ng"
+ w.puts "rescue TypeError"
+ w.puts " p :ok"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":ok", r.read.chomp)
+ end
+
+ ruby do |w, r, e|
+ w.puts "class BasicSocket; end"
+ w.puts "begin"
+ w.puts " require 'socket'"
+ w.puts " p :ng"
+ w.puts "rescue NameError"
+ w.puts " p :ok"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":ok", r.read.chomp)
+ end
+
+ ruby do |w, r, e|
+ w.puts "class BasicSocket < IO; end"
+ w.puts "begin"
+ w.puts " require 'socket'"
+ w.puts " p :ok"
+ w.puts "rescue Exception"
+ w.puts " p :ng"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":ok", r.read.chomp)
+ end
+ end
+
+ def test_define_class_under
+ begin
+ require "zlib"
+ rescue LoadError
+ return
+ end
+
+ ruby do |w, r, e|
+ w.puts "module Zlib; end"
+ w.puts "Zlib::Error = 1"
+ w.puts "begin"
+ w.puts " require 'zlib'"
+ w.puts " p :ng"
+ w.puts "rescue TypeError"
+ w.puts " p :ok"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":ok", r.read.chomp)
+ end
+
+ ruby do |w, r, e|
+ w.puts "module Zlib; end"
+ w.puts "class Zlib::Error; end"
+ w.puts "begin"
+ w.puts " require 'zlib'"
+ w.puts " p :ng"
+ w.puts "rescue NameError"
+ w.puts " p :ok"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":ok", r.read.chomp)
+ end
+
+ ruby do |w, r, e|
+ w.puts "module Zlib; end"
+ w.puts "class Zlib::Error < StandardError; end"
+ w.puts "begin"
+ w.puts " require 'zlib'"
+ w.puts " p :ok"
+ w.puts "rescue Exception"
+ w.puts " p :ng"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":ok", r.read.chomp)
+ end
+ end
+
+ def test_define_module
+ begin
+ require "zlib"
+ rescue LoadError
+ return
+ end
+
+ ruby do |w, r, e|
+ w.puts "Zlib = 1"
+ w.puts "begin"
+ w.puts " require 'zlib'"
+ w.puts " p :ng"
+ w.puts "rescue TypeError"
+ w.puts " p :ok"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":ok", r.read.chomp)
+ end
+ end
+
+ def test_define_module_under
+ begin
+ require "socket"
+ rescue LoadError
+ return
+ end
+
+ ruby do |w, r, e|
+ w.puts "class BasicSocket < IO; end"
+ w.puts "class Socket < BasicSocket; end"
+ w.puts "Socket::Constants = 1"
+ w.puts "begin"
+ w.puts " require 'socket'"
+ w.puts " p :ng"
+ w.puts "rescue TypeError"
+ w.puts " p :ok"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal(":ok", r.read.chomp)
+ end
+ end
+
+ def test_load
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ t.puts "module Foo; end"
+ t.puts "at_exit { p :wrap_end }"
+ t.puts "at_exit { raise 'error in at_exit test' }"
+ t.puts "p :ok"
+ t.close
+
+ ruby do |w, r, e|
+ w.puts "load(#{ t.path.dump }, true)"
+ w.puts "GC.start"
+ w.puts "p :end"
+ w.close
+ assert_match(/error in at_exit test/, e.read)
+ assert_equal(":ok\n:end\n:wrap_end", r.read.chomp)
+ end
+
+ assert_raise(ArgumentError) { at_exit }
+ end
+end
Modified: MacRuby/trunk/test/ruby/test_rubyoptions.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_rubyoptions.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_rubyoptions.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -84,7 +84,9 @@
def test_verbose
ruby('-vve', '') do |w, r, e|
- assert_match(/^ruby #{RUBY_VERSION} .*? \[#{RUBY_PLATFORM}\]$/, r.read)
+ description = r.read
+ assert_match(/^ruby #{RUBY_VERSION} .*? \[#{RUBY_PLATFORM}\]$/, description)
+ assert_equal RUBY_DESCRIPTION, description.chomp
end
ruby('--verbose', '-e', 'p $VERBOSE') do |w, r, e|
Added: MacRuby/trunk/test/ruby/test_shift_jis.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_shift_jis.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_shift_jis.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,27 @@
+# vim: set fileencoding=shift_jis
+
+require "test/unit"
+
+class TestShiftJIS < Test::Unit::TestCase
+ def test_mbc_case_fold
+ assert_match(/(\x82\x81)(a)\1\2/i, "\x82\x81a\x82\x81A")
+ assert_no_match(/(\x82\x81)(a)\1\2/i, "\x82\x81a\x82`A")
+ end
+
+ def test_property
+ assert_match(/\x82\xA0{0}\p{Hiragana}{4}/, "\x82Ђ炪\x82\xC8")
+ assert_no_match(/\x82\xA0{0}\p{Hiragana}{4}/, "\x83J\x83^\x83J\x83i")
+ assert_no_match(/\x82\xA0{0}\p{Hiragana}{4}/, "\x8A\xBF\x8E\x9A\x8A\xBF\x8E\x9A")
+ assert_no_match(/\x82\xA0{0}\p{Katakana}{4}/, "\x82Ђ炪\x82\xC8")
+ assert_match(/\x82\xA0{0}\p{Katakana}{4}/, "\x83J\x83^\x83J\x83i")
+ assert_no_match(/\x82\xA0{0}\p{Katakana}{4}/, "\x8A\xBF\x8E\x9A\x8A\xBF\x8E\x9A")
+ assert_raise(RegexpError) { Regexp.new('\x82\xA0{0}\p{foobarbaz}') }
+ end
+
+ def test_code_to_mbclen
+ s = "\x82\xA0\x82\xA2\x82\xA4\x82\xA6\x82\xA8"
+ s << 0x82a9
+ assert_equal("\x82\xA0\x82\xA2\x82\xA4\x82\xA6\x82\xA8\x82\xA9", s)
+ assert_raise(ArgumentError) { s << 0x82 }
+ end
+end
Modified: MacRuby/trunk/test/ruby/test_signal.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_signal.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_signal.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -64,4 +64,103 @@
w0.close
end
end
+
+ def test_invalid_signal_name
+ return unless Process.respond_to?(:kill)
+
+ assert_raise(ArgumentError) { Process.kill(:XXXXXXXXXX, $$) }
+ end
+
+ def test_signal_exception
+ assert_raise(ArgumentError) { SignalException.new }
+ assert_raise(ArgumentError) { SignalException.new(-1) }
+ assert_raise(ArgumentError) { SignalException.new(:XXXXXXXXXX) }
+ Signal.list.each do |signm, signo|
+ next if signm == "EXIT"
+ assert_equal(SignalException.new(signm).signo, signo)
+ assert_equal(SignalException.new(signm.to_sym).signo, signo)
+ assert_equal(SignalException.new(signo).signo, signo)
+ end
+ end
+
+ def test_interrupt
+ assert_raise(Interrupt) { raise Interrupt.new }
+ end
+
+ def test_signal2
+ return unless Process.respond_to?(:kill)
+ begin
+ x = false
+ oldtrap = Signal.trap(:INT) {|sig| x = true }
+ GC.start
+
+ assert_raise(ArgumentError) { Process.kill }
+
+ Timeout.timeout(10) do
+ x = false
+ Process.kill(SignalException.new(:INT).signo, $$)
+ nil until x
+
+ x = false
+ Process.kill("INT", $$)
+ nil until x
+
+ x = false
+ Process.kill("SIGINT", $$)
+ nil until x
+
+ x = false
+ o = Object.new
+ def o.to_str; "SIGINT"; end
+ Process.kill(o, $$)
+ nil until x
+ end
+
+ assert_raise(ArgumentError) { Process.kill(Object.new, $$) }
+
+ ensure
+ Signal.trap(:INT, oldtrap) if oldtrap
+ end
+ end
+
+ def test_trap
+ return unless Process.respond_to?(:kill)
+ begin
+ oldtrap = Signal.trap(:INT) {|sig| }
+
+ assert_raise(ArgumentError) { Signal.trap }
+
+ assert_raise(SecurityError) do
+ s = proc {}.taint
+ Signal.trap(:INT, s)
+ end
+
+ # FIXME!
+ Signal.trap(:INT, nil)
+ Signal.trap(:INT, "")
+ Signal.trap(:INT, "SIG_IGN")
+ Signal.trap(:INT, "IGNORE")
+
+ Signal.trap(:INT, "SIG_DFL")
+ Signal.trap(:INT, "SYSTEM_DEFAULT")
+
+ Signal.trap(:INT, "EXIT")
+
+ assert_raise(ArgumentError) { Signal.trap(:INT, "xxxxxx") }
+ assert_raise(ArgumentError) { Signal.trap(:INT, "xxxx") }
+
+ Signal.trap(SignalException.new(:INT).signo, "SIG_DFL")
+
+ assert_raise(ArgumentError) { Signal.trap(-1, "xxxx") }
+
+ o = Object.new
+ def o.to_str; "SIGINT"; end
+ Signal.trap(o, "SIG_DFL")
+
+ assert_raise(ArgumentError) { Signal.trap("XXXXXXXXXX", "SIG_DFL") }
+
+ ensure
+ Signal.trap(:INT, oldtrap) if oldtrap
+ end
+ end
end
Modified: MacRuby/trunk/test/ruby/test_sprintf.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_sprintf.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_sprintf.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -185,6 +185,7 @@
def test_float
assert_equal("36893488147419111424",
sprintf("%20.0f", 36893488147419107329.0))
+ assert_equal(" Inf", sprintf("% 0e", 1.0/0.0), "moved from btest/knownbug")
end
BSIZ = 120
Modified: MacRuby/trunk/test/ruby/test_string.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_string.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_string.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,4 +1,5 @@
require 'test/unit'
+require_relative 'envutil'
# use of $= is deprecated after 1.7.1
def pre_1_7_1
@@ -624,6 +625,8 @@
a.taint
assert(a.gsub(/./, S('X')).tainted?)
+ assert_equal("z", "abc".gsub(/./, "a" => "z"), "moved from btest/knownbug")
+
assert_raise(ArgumentError) { "foo".gsub }
end
@@ -1071,6 +1074,7 @@
assert_equal([], "".split(//, 1))
assert_equal(["\0"], "\0".split(//))
assert_equal(["*.c", "lib", "ext"], "\n\n\n\n\n\n*.c\n\n\n\nlib\n\n\n\n\next\n".split)
+ assert_equal("[2, 3]", [1,2,3].slice!(1,10000).inspect, "moved from btest/knownbug")
end
def test_squeeze
@@ -1509,6 +1513,73 @@
assert_equal(676, count)
end
+ def test_mod_check
+ assert_raise(RuntimeError) {
+ s = ""
+ s.sub!(/\A/) { s.replace "z" * 2000; "zzz" }
+ }
+ end
+
+ def test_frozen_check
+ assert_raise(RuntimeError) {
+ s = ""
+ s.sub!(/\A/) { s.freeze; "zzz" }
+ }
+ end
+
+ def test_tainted_str_new
+ a = []
+ a << a
+ s = a.inspect
+ assert(s.tainted?)
+ assert_equal("[[...]]", s)
+ end
+
+ class S2 < String
+ end
+ def test_str_new4
+ s = (0..54).to_a.join # length = 100
+ s2 = S2.new(s[10,90])
+ s3 = s2[10,80]
+ assert_equal((10..54).to_a.to_a.join, s2)
+ assert_equal((15..54).to_a.to_a.join, s3)
+ end
+
+ def test_rb_str_new4
+ s = "a" * 100
+ s2 = s[10,90]
+ assert_equal("a" * 90, s2)
+ s3 = s2[10,80]
+ assert_equal("a" * 80, s3)
+ end
+
+ class StringLike
+ def initialize(str)
+ @str = str
+ end
+
+ def to_str
+ @str
+ end
+ end
+
+ def test_rb_str_to_str
+ #assert_equal("ab", "a" + StringLike.new("b"))
+ end
+
+ def test_rb_str_shared_replace
+ s = "a" * 100
+ s.succ!
+ assert_equal("a" * 99 + "b", s)
+ s = ""
+ s.succ!
+ assert_equal("", s)
+ end
+
+ def test_times
+ assert_raise(ArgumentError) { "a" * (-1) }
+ end
+
def test_splice!
l = S("1234\n234\n34\n4\n")
assert_equal(S("1234\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
@@ -1522,7 +1593,7 @@
assert("abc".end_with?("c"))
end
- def test_times
+ def test_times2
s1 = ''
100.times {|n|
s2 = "a" * n
@@ -1608,4 +1679,8 @@
end
assert_equal(:foo, c.new.foo)
end
+
+ def test_gsub_enumerator
+ assert_normal_exit %q{"abc".gsub(/./).next}, "[ruby-dev:34828]"
+ end
end
Modified: MacRuby/trunk/test/ruby/test_struct.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_struct.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_struct.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -206,4 +206,10 @@
o = klass.new(1)
assert_equal(1, o.size)
end
+
+ def test_error
+ assert_raise(TypeError){
+ Struct.new(0)
+ }
+ end
end
Modified: MacRuby/trunk/test/ruby/test_thread.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_thread.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_thread.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -499,4 +499,10 @@
}.join
t.join
end
+
+ def test_uninitialized
+ c = Class.new(Thread)
+ c.class_eval { def initialize; end }
+ assert_raise(ThreadError) { c.new.start }
+ end
end
Modified: MacRuby/trunk/test/ruby/test_utf16.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_utf16.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_utf16.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -290,4 +290,69 @@
assert_equal(e, "abc".encode("utf-16be").count("^b".encode("utf-16be")))
assert_equal(e, "abc".encode("utf-16le").count("^b".encode("utf-16le")))
end
+
+ def test_header
+ assert_raise(ArgumentError) { eval("# encoding:utf-16le\nfoo") }
+ assert_raise(ArgumentError) { eval("# encoding:utf-16be\nfoo") }
+ end
+
+
+ def test_is_mbc_newline
+ sl = "f\0o\0o\0\n\0b\0a\0r\0\n\0b\0a\0z\0\n\0".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\0\n\0b\0a\0r\0\n\0b\0a\0z\0\n".force_encoding("utf-16be")
+ al = sl.lines.to_a
+ ab = sb.lines.to_a
+ assert_equal("f\0o\0o\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("b\0a\0r\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("b\0a\0z\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("\0f\0o\0o\0\n".force_encoding("utf-16be"), ab.shift)
+ assert_equal("\0b\0a\0r\0\n".force_encoding("utf-16be"), ab.shift)
+ assert_equal("\0b\0a\0z\0\n".force_encoding("utf-16be"), ab.shift)
+
+ sl = "f\0o\0o\0\n\0".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\0\n".force_encoding("utf-16be")
+ sl2 = "f\0o\0o\0".force_encoding("utf-16le")
+ sb2 = "\0f\0o\0o".force_encoding("utf-16be")
+ assert_equal(sl2, sl.chomp)
+ assert_equal(sl2, sl.chomp.chomp)
+ assert_equal(sb2, sb.chomp)
+ assert_equal(sb2, sb.chomp.chomp)
+
+ sl = "f\0o\0o\0\n".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\n".force_encoding("utf-16be")
+ assert_equal(sl, sl.chomp)
+ assert_equal(sb, sb.chomp)
+ end
+
+ def test_code_to_mbc
+ assert_equal("a\0".force_encoding("utf-16le"), "a".ord.chr("utf-16le"))
+ assert_equal("\0a".force_encoding("utf-16be"), "a".ord.chr("utf-16be"))
+ end
+
+ def utf8_to_utf16(s, e)
+ s.chars.map {|c| c.ord.chr(e) }.join
+ end
+
+ def test_mbc_case_fold
+ rl = Regexp.new(utf8_to_utf16("^(\u3042)(a)\\1\\2$", "utf-16le"), "i")
+ rb = Regexp.new(utf8_to_utf16("^(\u3042)(a)\\1\\2$", "utf-16be"), "i")
+ assert_equal(Encoding.find("utf-16le"), rl.encoding)
+ assert_equal(Encoding.find("utf-16be"), rb.encoding)
+ assert_match(rl, utf8_to_utf16("\u3042a\u3042a", "utf-16le"))
+ assert_match(rb, utf8_to_utf16("\u3042a\u3042a", "utf-16be"))
+ end
+
+ def test_surrogate_pair
+ sl = "\x42\xd8\xb7\xdf".force_encoding("utf-16le")
+ sb = "\xd8\x42\xdf\xb7".force_encoding("utf-16be")
+
+ assert_equal(1, sl.size)
+ assert_equal(1, sb.size)
+ assert_equal(0x20bb7, sl.ord)
+ assert_equal(0x20bb7, sb.ord)
+ assert_equal(sl, 0x20bb7.chr("utf-16le"))
+ assert_equal(sb, 0x20bb7.chr("utf-16be"))
+ assert_equal("", sl.chop)
+ assert_equal("", sb.chop)
+ end
end
Modified: MacRuby/trunk/test/ruby/test_utf32.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_utf32.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/ruby/test_utf32.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -20,8 +20,74 @@
def test_substr
assert_str_equal(
+ "abcdefgh".force_encoding("utf-32le"),
+ "abcdefgh".force_encoding("utf-32le")[0,3])
+ assert_str_equal(
"abcdefgh".force_encoding("utf-32be"),
"abcdefgh".force_encoding("utf-32be")[0,3])
end
+
+ def test_mbc_len
+ al = "abcdefghijkl".force_encoding("utf-32le").each_char.to_a
+ ab = "abcdefghijkl".force_encoding("utf-32be").each_char.to_a
+ assert_equal("abcd".force_encoding("utf-32le"), al.shift)
+ assert_equal("efgh".force_encoding("utf-32le"), al.shift)
+ assert_equal("ijkl".force_encoding("utf-32le"), al.shift)
+ assert_equal("abcd".force_encoding("utf-32be"), ab.shift)
+ assert_equal("efgh".force_encoding("utf-32be"), ab.shift)
+ assert_equal("ijkl".force_encoding("utf-32be"), ab.shift)
+ end
+
+ def ascii_to_utf16le(s)
+ s.unpack("C*").map {|x| [x,0,0,0] }.flatten.pack("C*").force_encoding("utf-32le")
+ end
+
+ def ascii_to_utf16be(s)
+ s.unpack("C*").map {|x| [0,0,0,x] }.flatten.pack("C*").force_encoding("utf-32be")
+ end
+
+ def test_mbc_newline
+ al = ascii_to_utf16le("foo\nbar\nbaz\n").lines.to_a
+ ab = ascii_to_utf16be("foo\nbar\nbaz\n").lines.to_a
+
+ assert_equal(ascii_to_utf16le("foo\n"), al.shift)
+ assert_equal(ascii_to_utf16le("bar\n"), al.shift)
+ assert_equal(ascii_to_utf16le("baz\n"), al.shift)
+ assert_equal(ascii_to_utf16be("foo\n"), ab.shift)
+ assert_equal(ascii_to_utf16be("bar\n"), ab.shift)
+ assert_equal(ascii_to_utf16be("baz\n"), ab.shift)
+
+ sl = "a\0".force_encoding("utf-32le")
+ sb = "a\0".force_encoding("utf-32be")
+ assert_equal(sl, sl.chomp)
+ assert_equal(sb, sb.chomp)
+ end
+
+ def test_mbc_to_code
+ sl = "a\0\0\0".force_encoding("utf-32le")
+ sb = "\0\0\0a".force_encoding("utf-32be")
+ assert_equal("a".ord, sl.ord)
+ assert_equal("a".ord, sb.ord)
+ end
+
+ def utf8_to_utf32(s, e)
+ s.chars.map {|c| c.ord.chr(e) }.join
+ end
+
+ def test_mbc_case_fold
+ rl = Regexp.new(utf8_to_utf32("^(\u3042)(a)\\1\\2$", "utf-32le"), "i")
+ rb = Regexp.new(utf8_to_utf32("^(\u3042)(a)\\1\\2$", "utf-32be"), "i")
+ assert_equal(Encoding.find("utf-32le"), rl.encoding)
+ assert_equal(Encoding.find("utf-32be"), rb.encoding)
+ assert_match(rl, utf8_to_utf32("\u3042a\u3042a", "utf-32le"))
+ assert_match(rb, utf8_to_utf32("\u3042a\u3042a", "utf-32be"))
+ end
+
+ def test_code_to_mbc
+ sl = "a\0\0\0".force_encoding("utf-32le")
+ sb = "\0\0\0a".force_encoding("utf-32be")
+ assert_equal(sl, "a".ord.chr("utf-32le"))
+ assert_equal(sb, "a".ord.chr("utf-32be"))
+ end
end
Added: MacRuby/trunk/test/ruby/test_windows_1251.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_windows_1251.rb (rev 0)
+++ MacRuby/trunk/test/ruby/test_windows_1251.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,16 @@
+# encoding:windows-1251
+
+require "test/unit"
+
+class TestWindows1251 < Test::Unit::TestCase
+ def test_windows_1251
+ (0xc0..0xdf).each do |c|
+ c1 = c.chr("windows-1251")
+ c2 = (c + 0x20).chr("windows-1251")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ end
+end
Modified: MacRuby/trunk/test/test_delegate.rb
===================================================================
--- MacRuby/trunk/test/test_delegate.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/test_delegate.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -12,4 +12,9 @@
obj.extend M
assert_equal(:m, obj.m, "[ruby-dev:33116]")
end
+
+ def test_systemcallerror_eq
+ e = SystemCallError.new(0)
+ assert((SimpleDelegator.new(e) == e) == (e == SimpleDelegator.new(e)), "[ruby-dev:34808]")
+ end
end
Added: MacRuby/trunk/test/webrick/.htaccess
===================================================================
--- MacRuby/trunk/test/webrick/.htaccess (rev 0)
+++ MacRuby/trunk/test/webrick/.htaccess 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1 @@
+this file should not be published.
Modified: MacRuby/trunk/test/webrick/test_cgi.rb
===================================================================
--- MacRuby/trunk/test/webrick/test_cgi.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/webrick/test_cgi.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,20 +1,13 @@
require "webrick"
require File.join(File.dirname(__FILE__), "utils.rb")
require "test/unit"
-begin
- loadpath = $:.dup
- $:.replace($: | [File.expand_path("../ruby", File.dirname(__FILE__))])
- require 'envutil'
-ensure
- $:.replace(loadpath)
-end
class TestWEBrickCGI < Test::Unit::TestCase
def test_cgi
accepted = started = stopped = 0
requested0 = requested1 = 0
config = {
- :CGIInterpreter => EnvUtil.rubybin,
+ :CGIInterpreter => TestWEBrick::RubyBin,
:DocumentRoot => File.dirname(__FILE__),
:DirectoryIndex => ["webrick.cgi"],
:RequestHandler => Proc.new{|req, res|
Modified: MacRuby/trunk/test/webrick/test_filehandler.rb
===================================================================
--- MacRuby/trunk/test/webrick/test_filehandler.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/webrick/test_filehandler.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -9,6 +9,10 @@
klass.new(WEBrick::Config::HTTP, filename)
end
+ def windows?
+ File.directory?("\\")
+ end
+
def get_res_body(res)
if defined? res.body.read
res.body.read
@@ -119,10 +123,82 @@
http = Net::HTTP.new(addr, port)
req = Net::HTTP::Get.new("/../../")
http.request(req){|res| assert_equal("400", res.code) }
- req = Net::HTTP::Get.new(
- "/..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5cboot.ini"
- )
+ req = Net::HTTP::Get.new("/..%5c../#{File.basename(__FILE__)}")
+ http.request(req){|res| assert_equal(windows? ? "200" : "404", res.code) }
+ req = Net::HTTP::Get.new("/..%5c..%5cruby.c")
http.request(req){|res| assert_equal("404", res.code) }
end
end
+
+ def test_unwise_in_path
+ if windows?
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/..%5c..")
+ http.request(req){|res| assert_equal("301", res.code) }
+ end
+ end
+ end
+
+ def test_short_filename
+ config = {
+ :CGIInterpreter => TestWEBrick::RubyBin,
+ :DocumentRoot => File.dirname(__FILE__),
+ :CGIPathEnv => ENV['PATH'],
+ }
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+
+ req = Net::HTTP::Get.new("/webric~1.cgi/test")
+ http.request(req) do |res|
+ if windows?
+ assert_equal("200", res.code)
+ assert_equal("/test", res.body)
+ else
+ assert_equal("404", res.code)
+ end
+ end
+
+ req = Net::HTTP::Get.new("/.htaccess")
+ http.request(req) {|res| assert_equal("404", res.code) }
+ req = Net::HTTP::Get.new("/htacce~1")
+ http.request(req) {|res| assert_equal("404", res.code) }
+ req = Net::HTTP::Get.new("/HTACCE~1")
+ http.request(req) {|res| assert_equal("404", res.code) }
+ end
+ end
+
+ def test_script_disclosure
+ config = {
+ :CGIInterpreter => TestWEBrick::RubyBin,
+ :DocumentRoot => File.dirname(__FILE__),
+ :CGIPathEnv => ENV['PATH'],
+ }
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+
+ req = Net::HTTP::Get.new("/webrick.cgi/test")
+ http.request(req) do |res|
+ assert_equal("200", res.code)
+ assert_equal("/test", res.body)
+ end
+
+ response_assertion = Proc.new do |res|
+ if windows?
+ assert_equal("200", res.code)
+ assert_equal("/test", res.body)
+ else
+ assert_equal("404", res.code)
+ end
+ end
+ req = Net::HTTP::Get.new("/webrick.cgi%20/test")
+ http.request(req, &response_assertion)
+ req = Net::HTTP::Get.new("/webrick.cgi./test")
+ http.request(req, &response_assertion)
+ req = Net::HTTP::Get.new("/webrick.cgi::$DATA/test")
+ http.request(req, &response_assertion)
+ end
+ end
end
Modified: MacRuby/trunk/test/webrick/utils.rb
===================================================================
--- MacRuby/trunk/test/webrick/utils.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/test/webrick/utils.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,3 +1,10 @@
+begin
+ loadpath = $:.dup
+ $:.replace($: | [File.expand_path("../ruby", File.dirname(__FILE__))])
+ require 'envutil'
+ensure
+ $:.replace(loadpath)
+end
require "webrick"
begin
require "webrick/https"
@@ -12,6 +19,11 @@
return self
end
+ RubyBin = "\"#{EnvUtil.rubybin}\""
+ RubyBin << " \"-I#{File.expand_path("../..", File.dirname(__FILE__))}/lib\""
+ RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/common\""
+ RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/#{RUBY_PLATFORM}\""
+
module_function
def start_server(klass, config={}, &block)
Added: MacRuby/trunk/test/webrick/webrick_long_filename.cgi
===================================================================
--- MacRuby/trunk/test/webrick/webrick_long_filename.cgi (rev 0)
+++ MacRuby/trunk/test/webrick/webrick_long_filename.cgi 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,36 @@
+#!ruby -d
+require "webrick/cgi"
+
+class TestApp < WEBrick::CGI
+ def do_GET(req, res)
+ res["content-type"] = "text/plain"
+ if (p = req.path_info) && p.length > 0
+ res.body = p
+ elsif (q = req.query).size > 0
+ res.body = q.keys.sort.collect{|key|
+ q[key].list.sort.collect{|v|
+ "#{key}=#{v}"
+ }.join(", ")
+ }.join(", ")
+ elsif %r{/$} =~ req.request_uri.to_s
+ res.body = ""
+ res.body << req.request_uri.to_s << "\n"
+ res.body << req.script_name
+ elsif !req.cookies.empty?
+ res.body = req.cookies.inject(""){|result, cookie|
+ result << "%s=%s\n" % [cookie.name, cookie.value]
+ }
+ res.cookies << WEBrick::Cookie.new("Customer", "WILE_E_COYOTE")
+ res.cookies << WEBrick::Cookie.new("Shipping", "FedEx")
+ else
+ res.body = req.script_name
+ end
+ end
+
+ def do_POST(req, res)
+ do_GET(req, res)
+ end
+end
+
+cgi = TestApp.new
+cgi.start
Modified: MacRuby/trunk/thread.c
===================================================================
--- MacRuby/trunk/thread.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/thread.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
thread.c -
- $Author: akr $
+ $Author: nobu $
Copyright (C) 2004-2007 Koichi Sasada
@@ -79,8 +79,9 @@
#define THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
-static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *ptr,
- rb_unblock_function_t **oldfunc, void **oldptr);
+static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *arg,
+ struct rb_unblock_callback *old);
+static void reset_unblock_function(rb_thread_t *th, const struct rb_unblock_callback *old);
#define GVL_UNLOCK_BEGIN() do { \
rb_thread_t *_th_stored = GET_THREAD(); \
@@ -95,9 +96,8 @@
#define BLOCKING_REGION(exec, ubf, ubfarg) do { \
rb_thread_t *__th = GET_THREAD(); \
int __prev_status = __th->status; \
- rb_unblock_function_t *__oldubf; \
- void *__oldubfarg; \
- set_unblock_function(__th, ubf, ubfarg, &__oldubf, &__oldubfarg); \
+ struct rb_unblock_callback __oldubf; \
+ set_unblock_function(__th, ubf, ubfarg, &__oldubf); \
__th->status = THREAD_STOPPED; \
thread_debug("enter blocking region (%p)\n", __th); \
GVL_UNLOCK_BEGIN(); {\
@@ -106,7 +106,7 @@
GVL_UNLOCK_END(); \
thread_debug("leave blocking region (%p)\n", __th); \
remove_signal_thread_list(__th); \
- set_unblock_function(__th, __oldubf, __oldubfarg, 0, 0); \
+ reset_unblock_function(__th, &__oldubf); \
if (__th->status == THREAD_STOPPED) { \
__th->status = __prev_status; \
} \
@@ -195,7 +195,7 @@
static void
set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *arg,
- rb_unblock_function_t **oldfunc, void **oldarg)
+ struct rb_unblock_callback *old)
{
check_ints:
RUBY_VM_CHECK_INTS(); /* check signal or so */
@@ -205,21 +205,28 @@
goto check_ints;
}
else {
- if (oldfunc) *oldfunc = th->unblock_function;
- if (oldarg) *oldarg = th->unblock_function_arg;
- th->unblock_function = func;
- th->unblock_function_arg = arg;
+ if (old) *old = th->unblock;
+ th->unblock.func = func;
+ th->unblock.arg = arg;
}
native_mutex_unlock(&th->interrupt_lock);
}
static void
+reset_unblock_function(rb_thread_t *th, const struct rb_unblock_callback *old)
+{
+ native_mutex_lock(&th->interrupt_lock);
+ th->unblock = *old;
+ native_mutex_unlock(&th->interrupt_lock);
+}
+
+static void
rb_thread_interrupt(rb_thread_t *th)
{
native_mutex_lock(&th->interrupt_lock);
RUBY_VM_SET_INTERRUPT(th);
- if (th->unblock_function) {
- (th->unblock_function)(th->unblock_function_arg);
+ if (th->unblock.func) {
+ (th->unblock.func)(th->unblock.arg);
}
else {
/* none */
@@ -816,6 +823,7 @@
void
rb_thread_execute_interrupts(rb_thread_t *th)
{
+ if (th->raised_flag) return;
while (th->interrupt_flag) {
int status = th->status;
th->status = THREAD_RUNNABLE;
@@ -1465,7 +1473,7 @@
static VALUE
rb_thread_inspect(VALUE thread)
{
- char *cname = rb_obj_classname(thread);
+ const char *cname = rb_obj_classname(thread);
rb_thread_t *th;
const char *status;
VALUE str;
@@ -2487,7 +2495,7 @@
rb_mutex_unlock(VALUE self)
{
mutex_t *mutex;
- char *err = NULL;
+ const char *err = NULL;
GetMutexPtr(self, mutex);
native_mutex_lock(&mutex->lock);
@@ -3035,7 +3043,7 @@
return trace;
}
-static char *
+static const char *
get_event_name(rb_event_flag_t event)
{
switch (event) {
@@ -3252,6 +3260,9 @@
}
rb_thread_create_timer_thread();
+
+ (void)native_mutex_trylock;
+ (void)ruby_thread_set_native;
}
int
Modified: MacRuby/trunk/thread_pthread.c
===================================================================
--- MacRuby/trunk/thread_pthread.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/thread_pthread.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -149,6 +149,7 @@
pthread_key_create(&ruby_native_thread_key, NULL);
th->thread_id = pthread_self();
+ native_cond_initialize(&th->native_thread_data.sleep_cond);
ruby_thread_set_native(th);
native_mutex_initialize(&signal_thread_list_lock);
posix_signal(SIGVTALRM, null_func);
@@ -363,12 +364,12 @@
max = sched_get_priority_max(policy);
min = sched_get_priority_min(policy);
- if (min < priority) {
+ if (min > priority) {
+ priority = min;
+ }
+ else if (max < priority) {
priority = max;
}
- else if (max > priority) {
- priority = min;
- }
sp.sched_priority = priority;
pthread_setschedparam(th->thread_id, policy, &sp);
@@ -429,8 +430,8 @@
GVL_UNLOCK_BEGIN();
{
pthread_mutex_lock(&th->interrupt_lock);
- th->unblock_function = ubf_pthread_cond_signal;
- th->unblock_function_arg = th;
+ th->unblock.func = ubf_pthread_cond_signal;
+ th->unblock.arg = th;
if (RUBY_VM_INTERRUPTED(th)) {
/* interrupted. return immediate */
@@ -438,9 +439,11 @@
}
else {
if (tv == 0 || ts.tv_sec < tvn.tv_sec /* overflow */ ) {
+ int r;
thread_debug("native_sleep: pthread_cond_wait start\n");
- pthread_cond_wait(&th->native_thread_data.sleep_cond,
+ r = pthread_cond_wait(&th->native_thread_data.sleep_cond,
&th->interrupt_lock);
+ if (r) rb_bug("pthread_cond_wait: %d", r);
thread_debug("native_sleep: pthread_cond_wait end\n");
}
else {
@@ -449,11 +452,13 @@
(unsigned long)ts.tv_sec, ts.tv_nsec);
r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond,
&th->interrupt_lock, &ts);
+ if (r && r != ETIMEDOUT) rb_bug("pthread_cond_timedwait: %d", r);
+
thread_debug("native_sleep: pthread_cond_timedwait end (%d)\n", r);
}
}
- th->unblock_function = 0;
- th->unblock_function_arg = 0;
+ th->unblock.func = 0;
+ th->unblock.arg = 0;
pthread_mutex_unlock(&th->interrupt_lock);
th->status = prev_status;
Modified: MacRuby/trunk/thread_win32.c
===================================================================
--- MacRuby/trunk/thread_win32.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/thread_win32.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -220,8 +220,8 @@
int status = th->status;
th->status = THREAD_STOPPED;
- th->unblock_function = ubf_handle;
- th->unblock_function_arg = th;
+ th->unblock.func = ubf_handle;
+ th->unblock.arg = th;
if (RUBY_VM_INTERRUPTED(th)) {
/* interrupted. return immediate */
@@ -232,8 +232,8 @@
thread_debug("native_sleep done (%lu)\n", ret);
}
- th->unblock_function = 0;
- th->unblock_function_arg = 0;
+ th->unblock.func = 0;
+ th->unblock.arg = 0;
th->status = status;
}
GVL_UNLOCK_END();
Modified: MacRuby/trunk/time.c
===================================================================
--- MacRuby/trunk/time.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/time.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
time.c -
- $Author: akr $
+ $Author: nobu $
created at: Tue Dec 28 14:31:59 JST 1993
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -333,7 +333,7 @@
return t;
}
-static const char *const months[] = {
+static const char months[][4] = {
"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec",
};
@@ -829,7 +829,10 @@
make_time_t(struct tm *tptr, int utc_p)
{
time_t t;
- struct tm *tmp, buf;
+#ifdef NEGATIVE_TIME_T
+ struct tm *tmp;
+#endif
+ struct tm buf;
buf = *tptr;
if (utc_p) {
#if defined(HAVE_TIMEGM)
Modified: MacRuby/trunk/tool/instruction.rb
===================================================================
--- MacRuby/trunk/tool/instruction.rb 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/tool/instruction.rb 2008-06-05 08:11:58 UTC (rev 247)
@@ -66,13 +66,14 @@
ret = "int inc = 0;\n"
@opes.each_with_index{|(t, v), i|
- if t == 'rb_num_t'
- ret << " unsigned long #{v} = FIX2INT(opes[#{i}]);\n"
+ if t == 'rb_num_t' && ((re = /\b#{v}\b/n) =~ @sp_inc ||
+ @defopes.any?{|t, val| re =~ val})
+ ret << " #{t} #{v} = FIX2INT(opes[#{i}]);\n"
end
}
@defopes.each_with_index{|((t, var), val), i|
- if t == 'rb_num_t' && val != '*'
- ret << " unsigned long #{var} = #{val};\n"
+ if t == 'rb_num_t' && val != '*' && /\b#{var}\b/ =~ @sp_inc
+ ret << " #{t} #{var} = #{val};\n"
end
}
@@ -707,7 +708,10 @@
break
end
- ops << " #{type} #{var} = (#{type})GET_OPERAND(#{i+1});"
+ re = /\b#{var}\b/n
+ if re =~ insn.body or re =~ insn.sp_inc or insn.rets.any?{|t, v| re =~ v}
+ ops << " #{type} #{var} = (#{type})GET_OPERAND(#{i+1});"
+ end
n += 1
}
@opn = n
Modified: MacRuby/trunk/transcode.c
===================================================================
--- MacRuby/trunk/transcode.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/transcode.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
transcode.c -
- $Author: nobu $
+ $Author: naruse $
created at: Tue Oct 30 16:10:22 JST 2007
Copyright (C) 2007 Martin Duerst
@@ -329,7 +329,7 @@
my_transcoding.ruby_string_dest = dest;
(*my_transcoder->preprocessor)(&fromp, &bp, (sp+slen), (bp+blen), &my_transcoding);
if (fromp != sp+slen) {
- rb_raise(rb_eArgError, "not fully converted, %d bytes left", sp+slen-fromp);
+ rb_raise(rb_eArgError, "not fully converted, %td bytes left", sp+slen-fromp);
}
buf = (unsigned char *)RSTRING_PTR(dest);
*bp = '\0';
@@ -346,7 +346,7 @@
transcode_loop(&fromp, &bp, (sp+slen), (bp+blen), my_transcoder, &my_transcoding, options);
if (fromp != sp+slen) {
- rb_raise(rb_eArgError, "not fully converted, %d bytes left", sp+slen-fromp);
+ rb_raise(rb_eArgError, "not fully converted, %td bytes left", sp+slen-fromp);
}
buf = (unsigned char *)RSTRING_PTR(dest);
*bp = '\0';
@@ -361,7 +361,7 @@
my_transcoding.ruby_string_dest = dest;
(*my_transcoder->postprocessor)(&fromp, &bp, (sp+slen), (bp+blen), &my_transcoding);
if (fromp != sp+slen) {
- rb_raise(rb_eArgError, "not fully converted, %d bytes left", sp+slen-fromp);
+ rb_raise(rb_eArgError, "not fully converted, %td bytes left", sp+slen-fromp);
}
buf = (unsigned char *)RSTRING_PTR(dest);
*bp = '\0';
@@ -400,7 +400,7 @@
*/
static VALUE
-rb_str_transcode_bang(int argc, VALUE *argv, VALUE str)
+str_encode_bang(int argc, VALUE *argv, VALUE str)
{
VALUE newstr = str;
int encidx = str_transcode(argc, argv, &newstr);
@@ -434,30 +434,29 @@
* to be added.
*/
-static VALUE
-rb_str_transcode(int argc, VALUE *argv, VALUE str)
-{
- str = rb_str_dup(str);
- return rb_str_transcode_bang(argc, argv, str);
-}
-
#else // WITH_OBJC
static VALUE
-rb_str_transcode(int argc, VALUE *argv, VALUE self)
+str_encode_bang(int argc, VALUE *argv, VALUE self)
{
/* TODO */
return self;
}
+#endif
+
static VALUE
-rb_str_transcode_bang(int argc, VALUE *argv, VALUE self)
+str_encode(int argc, VALUE *argv, VALUE str)
{
- /* TODO */
- return self;
+ str = rb_str_dup(str);
+ return str_encode_bang(argc, argv, str);
}
-#endif
+VALUE
+rb_str_transcode(VALUE str, VALUE to)
+{
+ return str_encode(1, &to, str);
+}
void
Init_transcode(void)
@@ -470,6 +469,6 @@
sym_ignore = ID2SYM(rb_intern("ignore"));
#endif
- rb_define_method(rb_cString, "encode", rb_str_transcode, -1);
- rb_define_method(rb_cString, "encode!", rb_str_transcode_bang, -1);
+ rb_define_method(rb_cString, "encode", str_encode, -1);
+ rb_define_method(rb_cString, "encode!", str_encode_bang, -1);
}
Modified: MacRuby/trunk/util.c
===================================================================
--- MacRuby/trunk/util.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/util.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -5,7 +5,7 @@
$Author: nobu $
created at: Fri Mar 10 17:22:34 JST 1995
- Copyright (C) 1993-2007 Yukihiro Matsumoto
+ Copyright (C) 1993-2008 Yukihiro Matsumoto
**********************************************************************/
@@ -48,7 +48,7 @@
unsigned long
ruby_scan_hex(const char *start, int len, int *retlen)
{
- static char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
+ static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
register const char *s = start;
register unsigned long retval = 0;
char *tmp;
@@ -999,8 +999,6 @@
#define IEEE_Arith
#endif
-#include "errno.h"
-
#ifdef Bad_float_h
#ifdef IEEE_Arith
@@ -2205,6 +2203,7 @@
const char *s2;
#endif
+ errno = 0;
sign = nz0 = nz = 0;
dval(rv) = 0.;
for (s = s00;;s++)
@@ -2384,7 +2383,7 @@
#endif
dval(rv) = tens[k - 9] * dval(rv) + z;
}
- bd0 = 0;
+ bd0 = bb = bd = bs = delta = 0;
if (nd <= DBL_DIG
#ifndef RND_PRODQUOT
#ifndef Honor_FLT_ROUNDS
@@ -3202,7 +3201,7 @@
}
static char *
-nrv_alloc(char *s, char **rve, int n)
+nrv_alloc(const char *s, char **rve, int n)
{
char *rv, *t;
@@ -3310,7 +3309,7 @@
int denorm;
ULong x;
#endif
- Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+ Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S;
double d2, ds, eps;
char *s, *s0;
#ifdef Honor_FLT_ROUNDS
@@ -3663,7 +3662,6 @@
m2 = b2;
m5 = b5;
- mhi = mlo = 0;
if (leftright) {
i =
#ifndef Sudden_Underflow
Modified: MacRuby/trunk/variable.c
===================================================================
--- MacRuby/trunk/variable.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/variable.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
variable.c -
- $Author: akr $
+ $Author: nobu $
created at: Tue Apr 19 23:55:15 JST 1994
Copyright (C) 1993-2007 Yukihiro Matsumoto
@@ -284,13 +284,13 @@
return rb_class_path(rb_class_real(klass));
}
-char *
+const char *
rb_class2name(VALUE klass)
{
- return (char *)RSTRING_CPTR(rb_class_name(klass));
+ return RSTRING_CPTR(rb_class_name(klass));
}
-char *
+const char *
rb_obj_classname(VALUE obj)
{
return rb_class2name(CLASS_OF(obj));
@@ -1030,7 +1030,6 @@
#if WITH_OBJC
CFMutableDictionaryRef obj_dict;
CFMutableDictionaryRef clone_dict;
- VALUE val;
if (generic_iv_dict == NULL)
return;
@@ -1145,7 +1144,7 @@
if (OBJ_FROZEN(obj)) rb_error_frozen("object");
#if WITH_OBJC
if (!rb_special_const_p(obj) && rb_objc_is_non_native(obj)) {
- rb_objc_flag_set(obj, FL_EXIVAR, true);
+ rb_objc_flag_set((const void *)obj, FL_EXIVAR, true);
generic_ivar_set(obj, id, val);
return val;
}
Modified: MacRuby/trunk/version.h
===================================================================
--- MacRuby/trunk/version.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/version.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -1,15 +1,15 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2008-05-17"
+#define RUBY_RELEASE_DATE "2008-06-03"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20080517
+#define RUBY_RELEASE_CODE 20080603
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 9
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2008
-#define RUBY_RELEASE_MONTH 5
-#define RUBY_RELEASE_DAY 17
+#define RUBY_RELEASE_MONTH 6
+#define RUBY_RELEASE_DAY 3
#ifdef RUBY_EXTERN
RUBY_EXTERN const int ruby_version_code;
Modified: MacRuby/trunk/vm.c
===================================================================
--- MacRuby/trunk/vm.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/vm.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
vm.c -
- $Author: mame $
+ $Author: nobu $
Copyright (C) 2004-2007 Koichi Sasada
@@ -16,6 +16,7 @@
#include "insnhelper.h"
#include "vm_insnhelper.c"
+#include "vm_eval.c"
#define BUFSIZE 0x100
#define PROCDEBUG 0
@@ -32,8 +33,6 @@
void vm_analysis_register(int reg, int isset);
void vm_analysis_insn(int insn);
-static NODE *lfp_set_special_cref(VALUE *lfp, NODE * cref);
-
#if OPT_STACK_CACHING
static VALUE finish_insn_seq[1] = { BIN(finish_SC_ax_ax) };
#elif OPT_CALL_THREADED_CODE
@@ -51,7 +50,7 @@
/* control stack frame */
static inline VALUE
-rb_vm_set_finish_env(rb_thread_t *th)
+rb_vm_set_finish_env(rb_thread_t * th)
{
vm_push_frame(th, 0, FRAME_MAGIC_FINISH,
Qnil, th->cfp->lfp[0], 0,
@@ -60,8 +59,8 @@
return Qtrue;
}
-void
-rb_vm_set_top_stack(rb_thread_t *th, VALUE iseqval)
+static void
+vm_set_top_stack(rb_thread_t * th, VALUE iseqval)
{
rb_iseq_t *iseq;
GetISeqPtr(iseqval, iseq);
@@ -78,11 +77,11 @@
th->cfp->sp, 0, iseq->local_size);
}
-void
-rb_vm_set_eval_stack(rb_thread_t *th, VALUE iseqval)
+static void
+vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref)
{
rb_iseq_t *iseq;
- rb_block_t *block = th->base_block;
+ rb_block_t * const block = th->base_block;
GetISeqPtr(iseqval, iseq);
/* for return */
@@ -90,17 +89,32 @@
vm_push_frame(th, iseq, FRAME_MAGIC_EVAL, block->self,
GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded,
th->cfp->sp, block->lfp, iseq->local_size);
+
+ if (cref) {
+ th->cfp->dfp[-1] = (VALUE)cref;
+ }
}
+rb_control_frame_t *
+vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
+{
+ while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
+ if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
+ return cfp;
+ }
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+ }
+ return 0;
+}
+
/* Env */
static void
-env_free(void *ptr)
+env_free(void * const ptr)
{
- rb_env_t *env;
RUBY_FREE_ENTER("env");
if (ptr) {
- env = ptr;
+ const rb_env_t * const env = ptr;
RUBY_FREE_UNLESS_NULL(env->env);
ruby_xfree(ptr);
}
@@ -108,12 +122,12 @@
}
static void
-env_mark(void *ptr)
+env_mark(void * const ptr)
{
- rb_env_t *env;
RUBY_MARK_ENTER("env");
if (ptr) {
- env = ptr;
+ const rb_env_t * const env = ptr;
+
if (env->env) {
/* TODO: should mark more restricted range */
RUBY_GC_INFO("env->env\n");
@@ -152,7 +166,7 @@
static VALUE check_env_value(VALUE envval);
static int
-check_env(rb_env_t *env)
+check_env(rb_env_t * const env)
{
printf("---\n");
printf("envptr: %p\n", &env->block.dfp[0]);
@@ -186,8 +200,8 @@
}
static VALUE
-vm_make_env_each(rb_thread_t *th, rb_control_frame_t *cfp,
- VALUE *envptr, VALUE *endptr)
+vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp,
+ VALUE *envptr, VALUE * const endptr)
{
VALUE envval, penvval = 0;
rb_env_t *env;
@@ -263,12 +277,6 @@
env->block.dfp = cfp->dfp;
env->block.iseq = cfp->iseq;
- if (VMDEBUG &&
- (!(cfp->lfp[-1] == Qnil ||
- BUILTIN_TYPE(cfp->lfp[-1]) == T_VALUES))) {
- rb_bug("invalid svar");
- }
-
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
/* TODO */
env->block.iseq = 0;
@@ -277,7 +285,7 @@
}
static int
-collect_local_variables_in_env(rb_env_t *env, VALUE ary)
+collect_local_variables_in_env(rb_env_t * const env, const VALUE ary)
{
int i;
for (i = 0; i < env->block.iseq->local_table_size; i++) {
@@ -287,14 +295,16 @@
}
}
if (env->prev_envval) {
- GetEnvPtr(env->prev_envval, env);
- collect_local_variables_in_env(env, ary);
+ rb_env_t *prevenv;
+ GetEnvPtr(env->prev_envval, prevenv);
+ collect_local_variables_in_env(prevenv, ary);
}
return 0;
}
int
-vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary)
+vm_collect_local_variables_in_heap(rb_thread_t * const th,
+ VALUE * const dfp, const VALUE ary)
{
if (ENV_IN_HEAP_P(th, dfp)) {
rb_env_t *env;
@@ -308,7 +318,7 @@
}
VALUE
-vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp)
+vm_make_env_object(rb_thread_t * th, rb_control_frame_t *cfp)
{
VALUE envval;
@@ -327,7 +337,7 @@
}
void
-vm_stack_to_heap(rb_thread_t *th)
+vm_stack_to_heap(rb_thread_t * const th)
{
rb_control_frame_t *cfp = th->cfp;
while ((cfp = vm_get_ruby_level_cfp(th, cfp)) != 0) {
@@ -358,7 +368,7 @@
VALUE
vm_make_proc(rb_thread_t *th,
- rb_control_frame_t *cfp, rb_block_t *block)
+ rb_control_frame_t *cfp, const rb_block_t *block)
{
VALUE procval, envval, blockprocval = 0;
rb_proc_t *proc;
@@ -389,7 +399,6 @@
proc->block.proc = procval;
proc->envval = envval;
proc->safe_level = th->safe_level;
- proc->special_cref_stack = lfp_get_special_cref(block->lfp);
if (VMDEBUG) {
if (th->stack < block->dfp && block->dfp < th->stack + th->stack_size) {
@@ -403,153 +412,18 @@
return procval;
}
-/* C -> Ruby: method */
-
-VALUE
-vm_call0(rb_thread_t *th, VALUE klass, VALUE recv,
- VALUE id, ID oid, int argc, const VALUE *argv,
- NODE * body, int nosuper)
-{
- VALUE val;
- rb_block_t *blockptr = 0;
-
- if (0) printf("id: %s, nd: %s, argc: %d, passed: %p\n",
- rb_id2name(id), ruby_node_name(nd_type(body)),
- argc, th->passed_block);
-
- if (th->passed_block) {
- blockptr = th->passed_block;
- th->passed_block = 0;
- }
- switch (nd_type(body)) {
- case RUBY_VM_METHOD_NODE:{
- rb_control_frame_t *reg_cfp;
- VALUE iseqval = (VALUE)body->nd_body;
- int i;
-
- rb_vm_set_finish_env(th);
- reg_cfp = th->cfp;
-
- CHECK_STACK_OVERFLOW(reg_cfp, argc + 1);
-
- *reg_cfp->sp++ = recv;
- for (i = 0; i < argc; i++) {
- *reg_cfp->sp++ = argv[i];
- }
-
- vm_setup_method(th, reg_cfp, argc, blockptr, 0, iseqval, recv, klass);
- val = vm_eval_body(th);
- break;
- }
- case NODE_CFUNC: {
- EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass);
- {
- rb_control_frame_t *reg_cfp = th->cfp;
- rb_control_frame_t *cfp =
- vm_push_frame(th, 0, FRAME_MAGIC_CFUNC,
- recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
-
- cfp->method_id = id;
- cfp->method_class = klass;
-
- val = call_cfunc(body->nd_cfnc, recv, body->nd_argc, argc, argv);
-
- if (reg_cfp != th->cfp + 1) {
- SDR2(reg_cfp);
- SDR2(th->cfp-5);
- rb_bug("cfp consistency error - call0");
- th->cfp = reg_cfp;
- }
- vm_pop_frame(th);
- }
- EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass);
- break;
- }
- case NODE_ATTRSET:{
- if (argc != 1) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
- }
- val = rb_ivar_set(recv, body->nd_vid, argv[0]);
- break;
- }
- case NODE_IVAR: {
- if (argc != 0) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)",
- argc);
- }
- val = rb_attr_get(recv, body->nd_vid);
- break;
- }
- case NODE_BMETHOD:{
- val = vm_call_bmethod(th, id, body->nd_cval,
- recv, klass, argc, (VALUE *)argv, blockptr);
- break;
- }
- default:
- rb_bug("unsupported: vm_call0(%s)", ruby_node_name(nd_type(body)));
- }
- RUBY_VM_CHECK_INTS();
- return val;
-}
-
-static VALUE
-vm_call_super(rb_thread_t *th, int argc, const VALUE *argv)
-{
- VALUE recv = th->cfp->self;
- VALUE klass;
- ID id;
- NODE *body;
- rb_control_frame_t *cfp = th->cfp;
-
- if (!cfp->iseq) {
- klass = cfp->method_class;
- klass = RCLASS_SUPER(klass);
-
- if (klass == 0) {
- klass = vm_search_normal_superclass(cfp->method_class, recv);
- }
-
- id = cfp->method_id;
- }
- else {
- rb_bug("vm_call_super: should not be reached");
- }
-
- body = rb_method_node(klass, id); /* this returns NODE_METHOD */
-
- if (body) {
- body = body->nd_body;
- }
- else {
- dp(recv);
- dp(klass);
- dpi(id);
- rb_bug("vm_call_super: not found");
- }
-
- return vm_call0(th, klass, recv, id, id, argc, argv, body, CALL_SUPER);
-}
-
-VALUE
-rb_call_super(int argc, const VALUE *argv)
-{
- PASS_PASSED_BLOCK();
- return vm_call_super(GET_THREAD(), argc, argv);
-}
-
/* C -> Ruby: block */
-static VALUE
-invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self,
- int argc, VALUE *argv, rb_block_t *blockptr)
+static inline VALUE
+invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
+ VALUE self, int argc, const VALUE *argv,
+ const rb_block_t *blockptr, const NODE *cref)
{
- VALUE val;
if (BUILTIN_TYPE(block->iseq) != T_NODE) {
- rb_iseq_t *iseq = block->iseq;
- rb_control_frame_t *cfp = th->cfp;
- int i, opt_pc;
- const int arg_size = iseq->arg_size;
- const int type = block_proc_is_lambda(block->proc) ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_BLOCK;
+ const rb_iseq_t *iseq = block->iseq;
+ const rb_control_frame_t *cfp = th->cfp;
+ int i, opt_pc, arg_size = iseq->arg_size;
+ int type = block_proc_is_lambda(block->proc) ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_BLOCK;
rb_vm_set_finish_env(th);
@@ -567,41 +441,56 @@
iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp,
iseq->local_size - arg_size);
- val = vm_eval_body(th);
+ if (cref) {
+ GC_WB(&th->cfp->dfp[-1], cref);
+ }
+
+ return vm_eval_body(th);
}
else {
- val = vm_yield_with_cfunc(th, block, self, argc, argv);
+ return vm_yield_with_cfunc(th, block, self, argc, argv);
}
- return val;
}
-VALUE
-vm_yield(rb_thread_t *th, int argc, VALUE *argv)
+static inline const rb_block_t *
+check_block(rb_thread_t *th)
{
- rb_block_t *block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
+ const rb_block_t *blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
- if (block == 0) {
+ if (blockptr == 0) {
vm_localjump_error("no block given", Qnil, 0);
}
- return invoke_block(th, block, block->self, argc, argv, 0);
+ return blockptr;
}
+static inline VALUE
+vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref)
+{
+ const rb_block_t *blockptr = check_block(th);
+ return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, cref);
+}
+
+static inline VALUE
+vm_yield(rb_thread_t *th, int argc, const VALUE *argv)
+{
+ const rb_block_t *blockptr = check_block(th);
+ return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0);
+}
+
VALUE
-vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
- VALUE self, int argc, VALUE *argv, rb_block_t *blockptr)
+vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
+ int argc, const VALUE *argv, rb_block_t * blockptr)
{
VALUE val = Qundef;
int state;
volatile int stored_safe = th->safe_level;
- volatile NODE *stored_special_cref_stack =
- lfp_set_special_cref(proc->block.lfp, proc->special_cref_stack);
rb_control_frame_t * volatile cfp = th->cfp;
TH_PUSH_TAG(th);
if ((state = EXEC_TAG()) == 0) {
th->safe_level = proc->safe_level;
- val = invoke_block(th, &proc->block, self, argc, argv, blockptr);
+ val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0);
}
TH_POP_TAG();
@@ -609,8 +498,6 @@
th->safe_level = stored_safe;
}
- lfp_set_special_cref(proc->block.lfp, (NODE*)stored_special_cref_stack);
-
if (state) {
if (state == TAG_RETURN && proc->is_lambda) {
VALUE err = th->errinfo;
@@ -634,7 +521,7 @@
/* special variable */
-VALUE
+static VALUE
vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key)
{
while (cfp->pc == 0) {
@@ -643,8 +530,8 @@
return lfp_svar_get(th, cfp->lfp, key);
}
-void
-vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, VALUE val)
+static void
+vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, const VALUE val)
{
while (cfp->pc == 0) {
cfp++;
@@ -693,10 +580,10 @@
/* backtrace */
int
-vm_get_sourceline(rb_control_frame_t *cfp)
+vm_get_sourceline(const rb_control_frame_t *cfp)
{
int line_no = 0;
- rb_iseq_t *iseq = cfp->iseq;
+ const rb_iseq_t *iseq = cfp->iseq;
if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
int i;
@@ -716,9 +603,8 @@
static VALUE
vm_backtrace_each(rb_thread_t *th,
- rb_control_frame_t *limit_cfp,
- rb_control_frame_t *cfp,
- char *file, int line_no, VALUE ary)
+ const rb_control_frame_t *limit_cfp, const rb_control_frame_t *cfp,
+ const char * file, int line_no, VALUE ary)
{
VALUE str;
@@ -746,12 +632,12 @@
return rb_ary_reverse(ary);
}
-VALUE
+static inline VALUE
vm_backtrace(rb_thread_t *th, int lev)
{
VALUE ary;
- rb_control_frame_t *cfp = th->cfp;
- rb_control_frame_t *top_of_cfp = (void *)(th->stack + th->stack_size);
+ const rb_control_frame_t *cfp = th->cfp;
+ const rb_control_frame_t *top_of_cfp = (void *)(th->stack + th->stack_size);
top_of_cfp -= 2;
if (lev < 0) {
@@ -773,48 +659,40 @@
return ary;
}
-/* cref */
-
-static void
-check_svar(void)
+const char *
+rb_sourcefile(void)
{
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = th->cfp;
- while ((void *)(cfp + 1) < (void *)(th->stack + th->stack_size)) {
- /* printf("cfp: %p\n", cfp->type); */
- if (cfp->lfp && cfp->lfp[-1] != Qnil &&
- TYPE(cfp->lfp[-1]) != T_VALUES) {
- /* dp(cfp->lfp[-1]); */
- rb_bug("!!!invalid svar!!!");
- }
- cfp++;
+ rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+
+ if (cfp) {
+ return RSTRING_CPTR(cfp->iseq->filename);
}
+ else {
+ return 0;
+ }
}
-static NODE *
-lfp_set_special_cref(VALUE *lfp, NODE * cref)
+int
+rb_sourceline(void)
{
- struct RValues *values = (void *) lfp[-1];
- NODE *old_cref;
+ rb_thread_t *th = GET_THREAD();
+ rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- if (VMDEBUG) {
- check_svar();
+ if (cfp) {
+ return vm_get_sourceline(cfp);
}
-
- if (cref == 0 && ((VALUE)values == Qnil || values->basic.klass == 0)) {
- old_cref = 0;
- }
else {
- old_cref = (NODE *)lfp_svar_get(GET_THREAD(), lfp, 2);
- lfp_svar_set(GET_THREAD(), lfp, 2, (VALUE)cref);
+ return 0;
}
- return old_cref;
}
NODE *
-vm_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack)
+vm_cref(void)
{
- return lfp_set_special_cref(lfp, cref_stack);
+ rb_thread_t *th = GET_THREAD();
+ rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
}
#if 0
@@ -829,29 +707,22 @@
}
#endif
-NODE *
-vm_get_cref(rb_thread_t *th, rb_iseq_t *iseq, rb_control_frame_t *cfp)
-{
- return get_cref(iseq, cfp->lfp);
-}
-
-NODE *
+static NODE *
vm_cref_push(rb_thread_t *th, VALUE klass, int noex)
{
NODE *cref = NEW_BLOCK(klass);
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
cref->nd_file = 0;
- cref->nd_next = get_cref(cfp->iseq, cfp->lfp);
+ cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
cref->nd_visi = noex;
return cref;
}
-VALUE
-vm_get_cbase(rb_thread_t *th)
+static inline VALUE
+vm_get_cbase(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
{
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- NODE *cref = get_cref(cfp->iseq, cfp->lfp);
+ NODE *cref = vm_get_cref(iseq, lfp, dfp);
VALUE klass = Qundef;
while (cref) {
@@ -860,9 +731,18 @@
}
cref = cref->nd_next;
}
+
return klass;
}
+VALUE
+rb_vm_cbase(void)
+{
+ rb_thread_t *th = GET_THREAD();
+ rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ return vm_get_cbase(cfp->iseq, cfp->lfp, cfp->dfp);
+}
+
/* jump */
static VALUE
@@ -960,7 +840,7 @@
}
void
-rb_iter_break()
+rb_iter_break(void)
{
vm_iter_break(GET_THREAD());
}
@@ -970,8 +850,8 @@
VALUE ruby_vm_redefined_flag = 0;
static st_table *vm_opt_method_table = 0;
-void
-rb_vm_check_redefinition_opt_method(NODE *node)
+static void
+rb_vm_check_redefinition_opt_method(const NODE *node)
{
VALUE bop;
@@ -1043,16 +923,16 @@
C1 : pushed by send insn (CFUNC)
struct CONTROL_FRAME {
- VALUE *pc; // cfp[0]
- VALUE *sp; // cfp[1]
- VALUE *bp; // cfp[2]
- rb_iseq_t *iseq; // cfp[3]
- VALUE flag; // cfp[4]
- VALUE self; // cfp[5]
- VALUE *lfp; // cfp[6]
- VALUE *dfp; // cfp[7]
- rb_iseq_t * block_iseq; // cfp[8]
- VALUE proc; // cfp[9] always 0
+ VALUE *pc; // cfp[0], program counter
+ VALUE *sp; // cfp[1], stack pointer
+ VALUE *bp; // cfp[2], base pointer
+ rb_iseq_t *iseq; // cfp[3], iseq
+ VALUE flag; // cfp[4], magic
+ VALUE self; // cfp[5], self
+ VALUE *lfp; // cfp[6], local frame pointer
+ VALUE *dfp; // cfp[7], dynamic frame pointer
+ rb_iseq_t * block_iseq; // cfp[8], block iseq
+ VALUE proc; // cfp[9], always 0
};
struct BLOCK {
@@ -1060,15 +940,11 @@
VALUE *lfp;
VALUE *dfp;
rb_iseq_t *block_iseq;
+ VALUE proc;
};
- struct PROC {
- VALUE proc_sig = 0;
- struct BLOCK;
- };
-
struct METHOD_CONTROL_FRAME {
- struct CONTROL_FRAME;
+ rb_control_frame_t frame;
};
struct METHOD_FRAME {
@@ -1078,12 +954,13 @@
VALUE param0;
...
VALUE paramN;
+ VALUE cref;
VALUE special; // lfp [1]
struct block_object *block_ptr | 0x01; // lfp [0]
};
struct BLOCK_CONTROL_FRAME {
- struct STACK_FRAME;
+ rb_control_frame_t frame;
};
struct BLOCK_FRAME {
@@ -1093,17 +970,19 @@
VALUE param0;
...
VALUE paramN;
+ VALUE cref;
VALUE *(prev_ptr | 0x01); // DFP[0]
};
struct CLASS_CONTROL_FRAME {
- struct STACK_FRAME;
+ rb_control_frame_t frame;
};
struct CLASS_FRAME {
VALUE param0;
...
VALUE paramN;
+ VALUE cref;
VALUE prev_dfp; // for frame jump
};
@@ -1130,15 +1009,10 @@
VALUE *dfp; // lfp
rb_iseq_t * block_iseq; // 0
};
-
- struct C_METHDO_FRAME{
- VALUE block_ptr;
- VALUE special;
- };
*/
-VALUE
+static VALUE
vm_eval_body(rb_thread_t *th)
{
int state;
@@ -1267,9 +1141,7 @@
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
cfp->sp = cfp->bp + entry->sp;
- if (!(state == TAG_REDO) &&
- !(state == TAG_NEXT && !escape_dfp) &&
- !(state == TAG_BREAK && !escape_dfp)) {
+ if (state != TAG_REDO) {
#if OPT_STACK_CACHING
initial = (GET_THROWOBJ_VAL(err));
#else
@@ -1284,12 +1156,10 @@
}
else if (state == TAG_REDO) {
type = CATCH_TYPE_REDO;
- escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
goto search_restart_point;
}
else if (state == TAG_NEXT) {
type = CATCH_TYPE_NEXT;
- escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
goto search_restart_point;
}
else {
@@ -1320,7 +1190,7 @@
cfp->sp[0] = err;
vm_push_frame(th, catch_iseq, FRAME_MAGIC_BLOCK,
cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
- cfp->sp + 1, cfp->lfp, catch_iseq->local_size - 1);
+ cfp->sp + 1 /* push value */, cfp->lfp, catch_iseq->local_size - 1);
state = 0;
th->errinfo = Qnil;
@@ -1353,7 +1223,7 @@
VALUE val;
volatile VALUE tmp;
- rb_vm_set_top_stack(th, iseqval);
+ vm_set_top_stack(th, iseqval);
if (!rb_const_defined(rb_cObject, rb_intern("TOPLEVEL_BINDING"))) {
rb_define_global_const("TOPLEVEL_BINDING", rb_binding_new());
@@ -1364,7 +1234,8 @@
}
int
-rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp)
+rb_thread_method_id_and_class(rb_thread_t *th,
+ ID *idp, VALUE *klassp)
{
rb_control_frame_t *cfp = th->cfp;
rb_iseq_t *iseq = cfp->iseq;
@@ -1399,9 +1270,9 @@
}
VALUE
-rb_thread_current_status(rb_thread_t *th)
+rb_thread_current_status(const rb_thread_t *th)
{
- rb_control_frame_t *cfp = th->cfp;
+ const rb_control_frame_t *cfp = th->cfp;
VALUE str = Qnil;
if (cfp->iseq != 0) {
@@ -1423,15 +1294,17 @@
}
VALUE
-rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, rb_block_t *blockptr, VALUE filename)
+rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
+ const rb_block_t *blockptr, VALUE filename)
{
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *reg_cfp = th->cfp;
+ const rb_control_frame_t *reg_cfp = th->cfp;
volatile VALUE iseqval = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP);
VALUE val;
vm_push_frame(th, DATA_PTR(iseqval), FRAME_MAGIC_TOP,
recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
+
val = (*func)(arg);
vm_pop_frame(th);
@@ -1439,7 +1312,7 @@
}
int
-rb_vm_cfunc_funcall_p(rb_control_frame_t *cfp)
+rb_vm_cfunc_funcall_p(const rb_control_frame_t *cfp)
{
if (vm_cfunc_flags(cfp) & (VM_CALL_FCALL_BIT | VM_CALL_VCALL_BIT))
return Qtrue;
@@ -1468,7 +1341,9 @@
static int
vm_mark_each_thread_func(st_data_t key, st_data_t value, st_data_t dummy)
{
+#if !WITH_OBJC
VALUE thval = (VALUE)key;
+#endif
rb_gc_mark(thval);
return ST_CONTINUE;
}
@@ -1558,6 +1433,7 @@
#endif
}
+#ifdef USE_THREAD_RECYCLE
static rb_thread_t *
thread_recycle_struct(void)
{
@@ -1565,6 +1441,7 @@
memset(p, 0, sizeof(rb_thread_t));
return p;
}
+#endif
static void
thread_free(void *ptr)
@@ -1737,6 +1614,8 @@
extern VALUE *rb_gc_register_stack_start;
#endif
+/* debug functions */
+
static VALUE
sdr(void)
{
@@ -1784,7 +1663,6 @@
/* ::Thread */
rb_cThread = rb_define_class("Thread", rb_cObject);
rb_undef_alloc_func(rb_cThread);
- rb_define_method(rb_cThread, "initialize", ruby_thread_init, 0);
/* ::VM::USAGE_ANALYSIS_* */
rb_define_const(rb_cVM, "USAGE_ANALYSIS_INSN", rb_hash_new());
@@ -1824,8 +1702,13 @@
rb_define_const(rb_cVM, "INSTRUCTION_NAMES", insns_name_array());
/* debug functions ::VM::SDR(), ::VM::NSDR() */
- /* rb_define_singleton_method(rb_cVM, "SDR", sdr, 0); */
- /* rb_define_singleton_method(rb_cVM, "NSDR", nsdr, 0); */
+#if VMDEBUG
+ rb_define_singleton_method(rb_cVM, "SDR", sdr, 0);
+ rb_define_singleton_method(rb_cVM, "NSDR", nsdr, 0);
+#else
+ (void)sdr;
+ (void)nsdr;
+#endif
/* VM bootstrap: phase 2 */
{
@@ -1912,13 +1795,13 @@
}
VALUE
-rb_vm_top_self()
+rb_vm_top_self(void)
{
return GET_VM()->top_self;
}
void
-Init_top_self()
+Init_top_self(void)
{
rb_vm_t *vm = GET_VM();
Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/vm.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
vm.h -
- $Author: ko1 $
+ $Author: nobu $
created at: 04/01/01 16:56:59 JST
Copyright (C) 2004-2007 Koichi Sasada
@@ -13,7 +13,6 @@
#define RUBY_VM_H
typedef long OFFSET;
-typedef unsigned long rb_num_t;
typedef unsigned long lindex_t;
typedef unsigned long dindex_t;
typedef rb_num_t GENTRY;
Modified: MacRuby/trunk/vm_core.h
===================================================================
--- MacRuby/trunk/vm_core.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/vm_core.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -17,6 +17,7 @@
#include <setjmp.h>
#include "ruby/ruby.h"
+#include "ruby/mvm.h"
#include "ruby/signal.h"
#include "ruby/st.h"
#include "ruby/node.h"
@@ -88,6 +89,8 @@
#define UNLIKELY(x) (x)
#endif /* __GNUC__ >= 3 */
+typedef unsigned long rb_num_t;
+
#define ISEQ_TYPE_TOP INT2FIX(1)
#define ISEQ_TYPE_METHOD INT2FIX(2)
#define ISEQ_TYPE_BLOCK INT2FIX(3)
@@ -283,7 +286,8 @@
#define GetVMPtr(obj, ptr) \
GetCoreDataFromValue(obj, rb_vm_t, ptr)
-typedef struct rb_vm_struct {
+struct rb_vm_struct
+{
VALUE self;
rb_thread_lock_t global_interpreter_lock;
@@ -295,6 +299,7 @@
VALUE thgroup_default;
VALUE last_status; /* $? */
+ int running;
int thread_abort_on_exception;
unsigned long trace_flag;
@@ -317,7 +322,7 @@
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
struct rb_objspace *objspace;
#endif
-} rb_vm_t;
+};
typedef struct {
VALUE *pc; /* cfp[0] */
@@ -370,7 +375,10 @@
#define RUBY_VM_VALUE_CACHE_SIZE 0x1000
#define USE_VALUE_CACHE 0
-typedef struct rb_thread_struct rb_thread_t;
+struct rb_unblock_callback {
+ rb_unblock_function_t *func;
+ void *arg;
+};
struct rb_thread_struct
{
@@ -415,9 +423,8 @@
int exec_signal;
int interrupt_flag;
- rb_unblock_function_t *unblock_function;
- void *unblock_function_arg;
rb_thread_lock_t interrupt_lock;
+ struct rb_unblock_callback unblock;
struct rb_vm_tag *tag;
struct rb_vm_trap_tag *trap_tag;
@@ -447,7 +454,6 @@
VALUE *machine_register_stack_end;
size_t machine_register_stack_maxsize;
#endif
-
jmp_buf machine_regs;
int mark_stack_len;
@@ -498,8 +504,6 @@
int safe_level;
int is_from_method;
int is_lambda;
-
- NODE *special_cref_stack;
} rb_proc_t;
#define GetEnvPtr(obj, ptr) \
@@ -518,7 +522,6 @@
typedef struct {
VALUE env;
- NODE *cref_stack;
} rb_binding_t;
@@ -607,19 +610,11 @@
void rb_disable_interrupt(void);
int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp);
-VALUE vm_eval_body(rb_thread_t *th);
VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
- int argc, VALUE *argv, rb_block_t *blockptr);
-VALUE vm_make_proc(rb_thread_t *th, rb_control_frame_t *cfp, rb_block_t *block);
+ int argc, const VALUE *argv, rb_block_t *blockptr);
+VALUE vm_make_proc(rb_thread_t *th, rb_control_frame_t *cfp, const rb_block_t *block);
VALUE vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
-VALUE vm_backtrace(rb_thread_t *, int);
-VALUE vm_yield(rb_thread_t *th, int argc, VALUE *argv);
-VALUE vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, VALUE id, ID oid,
- int argc, const VALUE *argv, NODE *body, int nosuper);
-
-int vm_get_sourceline(rb_control_frame_t *);
-
NOINLINE(void rb_gc_save_machine_context(rb_thread_t *));
RUBY_EXTERN VALUE sysstack_error;
Modified: MacRuby/trunk/vm_dump.c
===================================================================
--- MacRuby/trunk/vm_dump.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/vm_dump.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
vm_dump.c -
- $Author: akr $
+ $Author: naruse $
Copyright (C) 2004-2007 Koichi Sasada
@@ -21,8 +21,8 @@
control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
{
int pc = -1, bp = -1, line = 0;
- unsigned int lfp = cfp->lfp - th->stack;
- unsigned int dfp = cfp->dfp - th->stack;
+ ptrdiff_t lfp = cfp->lfp - th->stack;
+ ptrdiff_t dfp = cfp->dfp - th->stack;
char lfp_in_heap = ' ', dfp_in_heap = ' ';
char posbuf[MAX_POSBUF+1];
@@ -34,11 +34,11 @@
}
if (lfp < 0 || lfp > th->stack_size) {
- lfp = (unsigned int)cfp->lfp;
+ lfp = (ptrdiff_t)cfp->lfp;
lfp_in_heap = 'p';
}
if (dfp < 0 || dfp > th->stack_size) {
- dfp = (unsigned int)cfp->dfp;
+ dfp = (ptrdiff_t)cfp->dfp;
dfp_in_heap = 'p';
}
if (cfp->bp) {
@@ -97,6 +97,8 @@
iseq_name = "<ifunc>";
}
else {
+ int vm_get_sourceline(rb_control_frame_t *);
+
pc = cfp->pc - cfp->iseq->iseq_encoded;
iseq_name = RSTRING_CPTR(cfp->iseq->name);
line = vm_get_sourceline(cfp);
@@ -113,7 +115,7 @@
line = -1;
}
- fprintf(stderr, "c:%04d ",
+ fprintf(stderr, "c:%04td ",
(rb_control_frame_t *)(th->stack + th->stack_size) - cfp);
if (pc == -1) {
fprintf(stderr, "p:---- ");
@@ -121,9 +123,9 @@
else {
fprintf(stderr, "p:%04d ", pc);
}
- fprintf(stderr, "s:%04d b:%04d ", cfp->sp - th->stack, bp);
- fprintf(stderr, lfp_in_heap == ' ' ? "l:%06d " : "l:%06x ", lfp % 10000);
- fprintf(stderr, dfp_in_heap == ' ' ? "d:%06d " : "d:%06x ", dfp % 10000);
+ fprintf(stderr, "s:%04td b:%04d ", cfp->sp - th->stack, bp);
+ fprintf(stderr, lfp_in_heap == ' ' ? "l:%06td " : "l:%06tx ", lfp % 10000);
+ fprintf(stderr, dfp_in_heap == ' ' ? "d:%06td " : "d:%06tx ", dfp % 10000);
fprintf(stderr, "%-6s ", magic);
if (line) {
fprintf(stderr, "%s", posbuf);
@@ -140,7 +142,7 @@
void
vm_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp)
{
-#if 0
+#if 1
VALUE *sp = cfp->sp, *bp = cfp->bp;
VALUE *lfp = cfp->lfp;
VALUE *dfp = cfp->dfp;
@@ -148,11 +150,11 @@
fprintf(stderr, "-- stack frame ------------\n");
for (p = st = th->stack; p < sp; p++) {
- fprintf(stderr, "%04ld (%p): %08lx", p - st, p, *p);
+ fprintf(stderr, "%04ld (%p): %08"PRIxVALUE, (long)(p - st), p, *p);
t = (VALUE *)*p;
if (th->stack <= t && t < sp) {
- fprintf(stderr, " (= %ld)", (VALUE *)GC_GUARDED_PTR_REF(t) - th->stack);
+ fprintf(stderr, " (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF(t) - th->stack));
}
if (p == lfp)
@@ -175,6 +177,13 @@
}
void
+vm_stack_dump_raw_current(void)
+{
+ rb_thread_t *th = GET_THREAD();
+ vm_stack_dump_raw(th, th->cfp);
+}
+
+void
env_dump_raw(rb_env_t *env, VALUE *lfp, VALUE *dfp)
{
int i;
@@ -299,7 +308,7 @@
else {
rstr = rb_inspect(*ptr);
}
- fprintf(stderr, " stack %2d: %8s (%d)\n", i, StringValueCStr(rstr),
+ fprintf(stderr, " stack %2d: %8s (%td)\n", i, StringValueCStr(rstr),
ptr - th->stack);
}
}
@@ -336,7 +345,7 @@
dfp = -1;
cfpi = ((rb_control_frame_t *)(th->stack + th->stack_size)) - cfp;
- fprintf(stderr, " [PC] %04d, [SP] %04d, [LFP] %04d, [DFP] %04d, [CFP] %04d\n",
+ fprintf(stderr, " [PC] %04d, [SP] %04td, [LFP] %04d, [DFP] %04d, [CFP] %04d\n",
pc, cfp->sp - th->stack, lfp, dfp, cfpi);
}
@@ -357,7 +366,7 @@
VALUE *seq = iseq->iseq;
int pc = cfp->pc - iseq->iseq_encoded;
- printf("%3d ", VM_CFP_CNT(th, cfp));
+ printf("%3td ", VM_CFP_CNT(th, cfp));
ruby_iseq_disasm_insn(0, seq, pc, iseq, 0);
}
@@ -562,17 +571,18 @@
return Qnil;
}
+VALUE rb_make_backtrace(void);
+
void
rb_vm_bugreport(void)
{
- rb_thread_t *th = GET_THREAD();
VALUE bt;
if (GET_THREAD()->vm) {
int i;
SDR();
- bt = vm_backtrace(th, 0);
+ bt = rb_make_backtrace();
if (TYPE(bt) == T_ARRAY)
for (i = 0; i < RARRAY_LEN(bt); i++) {
dp(RARRAY_AT(bt, i));
Added: MacRuby/trunk/vm_eval.c
===================================================================
--- MacRuby/trunk/vm_eval.c (rev 0)
+++ MacRuby/trunk/vm_eval.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,1344 @@
+/**********************************************************************
+
+ vm_eval.c -
+
+ $Author: nobu $
+ created at: Sat May 24 16:02:32 JST 2008
+
+ Copyright (C) 1993-2007 Yukihiro Matsumoto
+ Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
+ Copyright (C) 2000 Information-technology Promotion Agency, Japan
+
+**********************************************************************/
+
+#include "ruby/ruby.h"
+#include "ruby/node.h"
+#include "ruby/st.h"
+
+#include "vm_method.c"
+
+static inline VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status);
+static inline VALUE rb_vm_set_finish_env(rb_thread_t * th);
+static inline VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref);
+static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv);
+static inline VALUE vm_backtrace(rb_thread_t *th, int lev);
+static NODE *vm_cref_push(rb_thread_t *th, VALUE klass, int noex);
+static VALUE vm_eval_body(rb_thread_t *th);
+static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref);
+
+static inline VALUE
+vm_call0(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid,
+ int argc, const VALUE *argv, const NODE *body, int nosuper)
+{
+ VALUE val;
+ rb_block_t *blockptr = 0;
+
+ if (0) printf("id: %s, nd: %s, argc: %d, passed: %p\n",
+ rb_id2name(id), ruby_node_name(nd_type(body)),
+ argc, th->passed_block);
+
+ if (th->passed_block) {
+ blockptr = th->passed_block;
+ th->passed_block = 0;
+ }
+ switch (nd_type(body)) {
+ case RUBY_VM_METHOD_NODE:{
+ rb_control_frame_t *reg_cfp;
+ VALUE iseqval = (VALUE)body->nd_body;
+ int i;
+
+ rb_vm_set_finish_env(th);
+ reg_cfp = th->cfp;
+
+ CHECK_STACK_OVERFLOW(reg_cfp, argc + 1);
+
+ *reg_cfp->sp++ = recv;
+ for (i = 0; i < argc; i++) {
+ *reg_cfp->sp++ = argv[i];
+ }
+
+ vm_setup_method(th, reg_cfp, argc, blockptr, 0, iseqval, recv, klass);
+ val = vm_eval_body(th);
+ break;
+ }
+ case NODE_CFUNC: {
+ EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass);
+ {
+ rb_control_frame_t *reg_cfp = th->cfp;
+ rb_control_frame_t *cfp =
+ vm_push_frame(th, 0, FRAME_MAGIC_CFUNC,
+ recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
+
+ cfp->method_id = id;
+ cfp->method_class = klass;
+
+ val = call_cfunc(body->nd_cfnc, recv, body->nd_argc, argc, argv);
+
+ if (reg_cfp != th->cfp + 1) {
+ SDR2(reg_cfp);
+ SDR2(th->cfp-5);
+ rb_bug("cfp consistency error - call0");
+ th->cfp = reg_cfp;
+ }
+ vm_pop_frame(th);
+ }
+ EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass);
+ break;
+ }
+ case NODE_ATTRSET:{
+ if (argc != 1) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
+ }
+ val = rb_ivar_set(recv, body->nd_vid, argv[0]);
+ break;
+ }
+ case NODE_IVAR: {
+ if (argc != 0) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)",
+ argc);
+ }
+ val = rb_attr_get(recv, body->nd_vid);
+ break;
+ }
+ case NODE_BMETHOD:{
+ val = vm_call_bmethod(th, id, body->nd_cval,
+ recv, klass, argc, (VALUE *)argv, blockptr);
+ break;
+ }
+ default:
+ rb_bug("unsupported: vm_call0(%s)", ruby_node_name(nd_type(body)));
+ }
+ RUBY_VM_CHECK_INTS();
+ return val;
+}
+
+VALUE
+rb_vm_call(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid,
+ int argc, const VALUE *argv, const NODE *body, int nosuper)
+{
+ return vm_call0(th, klass, recv, id, oid, argc, argv, body, nosuper);
+}
+
+static inline VALUE
+vm_call_super(rb_thread_t * const th, const int argc, const VALUE * const argv)
+{
+ VALUE recv = th->cfp->self;
+ VALUE klass;
+ ID id;
+ NODE *body;
+ rb_control_frame_t *cfp = th->cfp;
+
+ if (!cfp->iseq) {
+ klass = cfp->method_class;
+ klass = RCLASS_SUPER(klass);
+
+ if (klass == 0) {
+ klass = vm_search_normal_superclass(cfp->method_class, recv);
+ }
+
+ id = cfp->method_id;
+ }
+ else {
+ rb_bug("vm_call_super: should not be reached");
+ }
+
+ body = rb_method_node(klass, id); /* this returns NODE_METHOD */
+
+ if (body) {
+ body = body->nd_body;
+ }
+ else {
+ dp(recv);
+ dp(klass);
+ dpi(id);
+ rb_bug("vm_call_super: not found");
+ }
+
+ return vm_call0(th, klass, recv, id, id, argc, argv, body, CALL_SUPER);
+}
+
+VALUE
+rb_call_super(int argc, const VALUE *argv)
+{
+ PASS_PASSED_BLOCK();
+ return vm_call_super(GET_THREAD(), argc, argv);
+}
+
+static inline void
+stack_check(void)
+{
+ rb_thread_t *th = GET_THREAD();
+
+ if (!rb_thread_raised_p(th, RAISED_STACKOVERFLOW) && ruby_stack_check()) {
+ rb_thread_raised_set(th, RAISED_STACKOVERFLOW);
+ rb_exc_raise(sysstack_error);
+ }
+}
+
+static inline VALUE
+rb_call0(VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv,
+ int scope, VALUE self)
+{
+ NODE *body, *method;
+ int noex;
+ ID id = mid;
+ struct cache_entry *ent;
+ rb_thread_t *th = GET_THREAD();
+#if WITH_OBJC
+ unsigned redo = 0;
+#endif
+
+rb_call0_redo:
+
+#if WITH_OBJC
+# define REDO_PERHAPS() \
+ do { \
+ if (!redo && mid != missing) { \
+ ID newid = rb_objc_missing_sel(mid, argc); \
+ if (newid != mid) { \
+ id = mid = newid; \
+ redo = 1; \
+ goto rb_call0_redo; \
+ } \
+ } \
+ } \
+ while (0)
+#else
+# define REDO_PERHAPS()
+#endif
+
+ if (!klass) {
+ rb_raise(rb_eNotImpError,
+ "method `%s' called on terminated object (%p)",
+ rb_id2name(mid), (void *)recv);
+ }
+ /* is it in the method cache? */
+ ent = cache + EXPR1(klass, mid);
+
+ if (ent->mid == mid && ent->klass == klass) {
+ if (!ent->method) {
+ REDO_PERHAPS();
+ return method_missing(recv, mid, argc, argv,
+ scope == 2 ? NOEX_VCALL : 0);
+ }
+ id = ent->mid0;
+ noex = ent->method->nd_noex;
+ klass = ent->method->nd_clss;
+ body = ent->method->nd_body;
+ }
+ else if ((method = rb_get_method_body(klass, id, &id)) != 0) {
+ noex = method->nd_noex;
+ klass = method->nd_clss;
+ body = method->nd_body;
+ }
+ else {
+ REDO_PERHAPS();
+ if (scope == 3) {
+ return method_missing(recv, mid, argc, argv, NOEX_SUPER);
+ }
+ return method_missing(recv, mid, argc, argv,
+ scope == 2 ? NOEX_VCALL : 0);
+ }
+
+
+ if (mid != missing) {
+ /* receiver specified form for private method */
+ if (UNLIKELY(noex)) {
+ if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == 0) {
+ return method_missing(recv, mid, argc, argv, NOEX_PRIVATE);
+ }
+
+ /* self must be kind of a specified form for protected method */
+ if (((noex & NOEX_MASK) & NOEX_PROTECTED) && scope == 0) {
+ VALUE defined_class = klass;
+
+ if (TYPE(defined_class) == T_ICLASS) {
+ defined_class = RBASIC(defined_class)->klass;
+ }
+
+ if (self == Qundef) {
+ self = th->cfp->self;
+ }
+ if (!rb_obj_is_kind_of(self, rb_class_real(defined_class))) {
+ return method_missing(recv, mid, argc, argv, NOEX_PROTECTED);
+ }
+ }
+
+ if (NOEX_SAFE(noex) > th->safe_level) {
+ rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(mid));
+ }
+ }
+ }
+
+ stack_check();
+ return vm_call0(th, klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
+}
+
+static inline VALUE
+rb_call(VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int scope)
+{
+ return rb_call0(klass, recv, mid, argc, argv, scope, Qundef);
+}
+
+/*
+ * call-seq:
+ * obj.method_missing(symbol [, *args] ) => result
+ *
+ * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
+ * <i>symbol</i> is the symbol for the method called, and <i>args</i>
+ * are any arguments that were passed to it. By default, the interpreter
+ * raises an error when this method is called. However, it is possible
+ * to override the method to provide more dynamic behavior.
+ * If it is decided that a particular method should not be handled, then
+ * <i>super</i> should be called, so that ancestors can pick up the
+ * missing method.
+ * The example below creates
+ * a class <code>Roman</code>, which responds to methods with names
+ * consisting of roman numerals, returning the corresponding integer
+ * values.
+ *
+ * class Roman
+ * def romanToInt(str)
+ * # ...
+ * end
+ * def method_missing(methId)
+ * str = methId.id2name
+ * romanToInt(str)
+ * end
+ * end
+ *
+ * r = Roman.new
+ * r.iv #=> 4
+ * r.xxiii #=> 23
+ * r.mm #=> 2000
+ */
+
+static VALUE
+rb_method_missing(int argc, const VALUE *argv, VALUE obj)
+{
+ ID id;
+ VALUE exc = rb_eNoMethodError;
+ const char *format = 0;
+ rb_thread_t *th = GET_THREAD();
+ int last_call_status = th->method_missing_reason;
+ if (argc == 0 || !SYMBOL_P(argv[0])) {
+ rb_raise(rb_eArgError, "no id given");
+ }
+
+ stack_check();
+
+ id = SYM2ID(argv[0]);
+
+ if (last_call_status & NOEX_PRIVATE) {
+ format = "private method `%s' called for %s";
+ }
+ else if (last_call_status & NOEX_PROTECTED) {
+ format = "protected method `%s' called for %s";
+ }
+ else if (last_call_status & NOEX_VCALL) {
+ format = "undefined local variable or method `%s' for %s";
+ exc = rb_eNameError;
+ }
+ else if (last_call_status & NOEX_SUPER) {
+ format = "super: no superclass method `%s' for %s";
+ }
+ if (!format) {
+ format = "undefined method `%s' for %s";
+ }
+
+ {
+ int n = 0;
+ VALUE args[3];
+ args[n++] = rb_funcall(rb_const_get(exc, rb_intern("message")), '!',
+ 3, rb_str_new2(format), obj, argv[0]);
+ args[n++] = argv[0];
+ if (exc == rb_eNoMethodError) {
+ args[n++] = rb_ary_new4(argc - 1, argv + 1);
+ }
+ exc = rb_class_new_instance(n, args, exc);
+
+ th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
+ rb_exc_raise(exc);
+ }
+
+ return Qnil; /* not reached */
+}
+
+static inline VALUE
+method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
+{
+ VALUE *nargv;
+ GET_THREAD()->method_missing_reason = call_status;
+
+ if (id == missing) {
+ rb_method_missing(argc, argv, obj);
+ }
+ else if (id == ID_ALLOCATOR) {
+ rb_raise(rb_eTypeError, "allocator undefined for %s",
+ rb_class2name(obj));
+ }
+
+ nargv = ALLOCA_N(VALUE, argc + 1);
+ nargv[0] = ID2SYM(id);
+ MEMCPY(nargv + 1, argv, VALUE, argc);
+
+ return rb_funcall2(obj, missing, argc + 1, nargv);
+}
+
+VALUE
+rb_apply(VALUE recv, ID mid, VALUE args)
+{
+ int argc;
+ VALUE *argv;
+
+ argc = RARRAY_LEN(args); /* Assigns LONG, but argc is INT */
+ argv = ALLOCA_N(VALUE, argc);
+ MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
+ return rb_call(CLASS_OF(recv), recv, mid, argc, argv, CALL_FCALL);
+}
+
+VALUE
+rb_funcall(VALUE recv, ID mid, int n, ...)
+{
+ VALUE *argv;
+ va_list ar;
+ va_init_list(ar, n);
+
+ if (n > 0) {
+ long i;
+
+ argv = ALLOCA_N(VALUE, n);
+
+ for (i = 0; i < n; i++) {
+ argv[i] = va_arg(ar, VALUE);
+ }
+ va_end(ar);
+ }
+ else {
+ argv = 0;
+ }
+ return rb_call(CLASS_OF(recv), recv, mid, n, argv, CALL_FCALL);
+}
+
+VALUE
+rb_funcall2(VALUE recv, ID mid, int argc, const VALUE *argv)
+{
+ return rb_call(CLASS_OF(recv), recv, mid, argc, argv, CALL_FCALL);
+}
+
+VALUE
+rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
+{
+ return rb_call(CLASS_OF(recv), recv, mid, argc, argv, CALL_PUBLIC);
+}
+
+static VALUE
+send_internal(int argc, VALUE *argv, VALUE recv, int scope)
+{
+ VALUE vid;
+ VALUE self = RUBY_VM_PREVIOUS_CONTROL_FRAME(GET_THREAD()->cfp)->self;
+
+ if (argc == 0) {
+ rb_raise(rb_eArgError, "no method name given");
+ }
+
+ vid = *argv++; argc--;
+ PASS_PASSED_BLOCK();
+ return rb_call0(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, scope, self);
+}
+
+/*
+ * call-seq:
+ * obj.send(symbol [, args...]) => obj
+ * obj.__send__(symbol [, args...]) => obj
+ *
+ * Invokes the method identified by _symbol_, passing it any
+ * arguments specified. You can use <code>__send__</code> if the name
+ * +send+ clashes with an existing method in _obj_.
+ *
+ * class Klass
+ * def hello(*args)
+ * "Hello " + args.join(' ')
+ * end
+ * end
+ * k = Klass.new
+ * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
+ */
+
+VALUE
+rb_f_send(int argc, VALUE *argv, VALUE recv)
+{
+ return send_internal(argc, argv, recv, NOEX_NOSUPER | NOEX_PRIVATE);
+}
+
+/*
+ * call-seq:
+ * obj.public_send(symbol [, args...]) => obj
+ *
+ * Invokes the method identified by _symbol_, passing it any
+ * arguments specified. Unlike send, public_send calls public
+ * methods only.
+ *
+ * 1.public_send(:puts, "hello") # causes NoMethodError
+ */
+
+VALUE
+rb_f_public_send(int argc, VALUE *argv, VALUE recv)
+{
+ return send_internal(argc, argv, recv, NOEX_PUBLIC);
+}
+
+/* yield */
+
+static inline VALUE
+rb_yield_0(int argc, const VALUE * argv)
+{
+ return vm_yield(GET_THREAD(), argc, argv);
+}
+
+VALUE
+rb_yield(VALUE val)
+{
+ if (val == Qundef) {
+ return rb_yield_0(0, 0);
+ }
+ else {
+ return rb_yield_0(1, &val);
+ }
+}
+
+VALUE
+rb_yield_values(int n, ...)
+{
+ if (n == 0) {
+ return rb_yield_0(0, 0);
+ }
+ else {
+ int i;
+ VALUE *argv;
+ va_list args;
+ argv = ALLOCA_N(VALUE, n);
+
+ va_init_list(args, n);
+ for (i=0; i<n; i++) {
+ argv[i] = va_arg(args, VALUE);
+ }
+ va_end(args);
+
+ return rb_yield_0(n, argv);
+ }
+}
+
+VALUE
+rb_yield_values2(int argc, const VALUE *argv)
+{
+ return rb_yield_0(argc, argv);
+}
+
+VALUE
+rb_yield_splat(VALUE values)
+{
+ VALUE tmp = rb_check_array_type(values);
+ volatile VALUE v;
+ if (NIL_P(tmp)) {
+ rb_raise(rb_eArgError, "not an array");
+ }
+ v = rb_yield_0(RARRAY_LEN(tmp), RARRAY_PTR(tmp));
+ return v;
+}
+
+static VALUE
+loop_i(void)
+{
+ for (;;) {
+ rb_yield_0(0, 0);
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * loop {|| block }
+ *
+ * Repeatedly executes the block.
+ *
+ * loop do
+ * print "Input: "
+ * line = gets
+ * break if !line or line =~ /^qQ/
+ * # ...
+ * end
+ *
+ * StopIteration raised in the block breaks the loop.
+ */
+
+static VALUE
+rb_f_loop(void)
+{
+ rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
+ return Qnil; /* dummy */
+}
+
+VALUE
+rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
+ VALUE (* bl_proc) (ANYARGS), VALUE data2)
+{
+ int state;
+ volatile VALUE retval = Qnil;
+ NODE *node = NEW_IFUNC(bl_proc, data2);
+ rb_thread_t *th = GET_THREAD();
+ rb_control_frame_t *cfp = th->cfp;
+
+ TH_PUSH_TAG(th);
+ state = TH_EXEC_TAG();
+ if (state == 0) {
+ iter_retry:
+ {
+ rb_block_t *blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(th->cfp);
+ blockptr->iseq = (void *)node;
+ blockptr->proc = 0;
+ th->passed_block = blockptr;
+ }
+ retval = (*it_proc) (data1);
+ }
+ else {
+ VALUE err = th->errinfo;
+ if (state == TAG_BREAK) {
+ VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
+ VALUE *cdfp = cfp->dfp;
+
+ if (cdfp == escape_dfp) {
+ state = 0;
+ th->state = 0;
+ th->errinfo = Qnil;
+ th->cfp = cfp;
+ }
+ else{
+ /* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
+ }
+ }
+ else if (state == TAG_RETRY) {
+ VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
+ VALUE *cdfp = cfp->dfp;
+
+ if (cdfp == escape_dfp) {
+ state = 0;
+ th->state = 0;
+ th->errinfo = Qnil;
+ th->cfp = cfp;
+ goto iter_retry;
+ }
+ }
+ }
+ TH_POP_TAG();
+
+ switch (state) {
+ case 0:
+ break;
+ default:
+ TH_JUMP_TAG(th, state);
+ }
+ return retval;
+}
+
+struct iter_method_arg {
+ VALUE obj;
+ ID mid;
+ int argc;
+ VALUE *argv;
+};
+
+static VALUE
+iterate_method(VALUE obj)
+{
+ const struct iter_method_arg * arg =
+ (struct iter_method_arg *) obj;
+
+ return rb_call(CLASS_OF(arg->obj), arg->obj, arg->mid,
+ arg->argc, arg->argv, CALL_FCALL);
+}
+
+VALUE
+rb_block_call(VALUE obj, ID mid, int argc, VALUE * argv,
+ VALUE (*bl_proc) (ANYARGS), VALUE data2)
+{
+ struct iter_method_arg arg;
+
+ arg.obj = obj;
+ arg.mid = mid;
+ arg.argc = argc;
+ arg.argv = argv;
+ return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
+}
+
+VALUE
+rb_each(VALUE obj)
+{
+ return rb_call(CLASS_OF(obj), obj, idEach, 0, 0, CALL_FCALL);
+}
+
+static VALUE
+eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *file, int line)
+{
+ int state;
+ VALUE result = Qundef;
+ VALUE envval;
+ rb_binding_t *bind = 0;
+ rb_thread_t *th = GET_THREAD();
+ rb_env_t *env = NULL;
+ rb_block_t block;
+
+ if (file == 0) {
+ file = rb_sourcefile();
+ line = rb_sourceline();
+ }
+
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ rb_iseq_t *iseq;
+ volatile VALUE iseqval;
+
+ if (scope != Qnil) {
+ if (rb_obj_is_kind_of(scope, rb_cBinding)) {
+ GetBindingPtr(scope, bind);
+ envval = bind->env;
+ }
+ else {
+ rb_raise(rb_eTypeError,
+ "wrong argument type %s (expected Binding)",
+ rb_obj_classname(scope));
+ }
+ GetEnvPtr(envval, env);
+ th->base_block = &env->block;
+ }
+ else {
+ rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
+ th->base_block = █
+ th->base_block->self = self;
+ th->base_block->iseq = cfp->iseq; /* TODO */
+ }
+
+ /* make eval iseq */
+ th->parse_in_eval++;
+ iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
+ th->parse_in_eval--;
+
+ vm_set_eval_stack(th, iseqval, cref);
+ th->base_block = 0;
+
+ if (0) { /* for debug */
+ extern VALUE ruby_iseq_disasm(VALUE);
+ printf("%s\n", RSTRING_CPTR(ruby_iseq_disasm(iseqval)));
+ }
+
+ /* save new env */
+ GetISeqPtr(iseqval, iseq);
+ if (bind && iseq->local_size > 0) {
+ bind->env = vm_make_env_object(th, th->cfp);
+ }
+
+ /* kick */
+ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
+ result = vm_eval_body(th);
+ }
+ POP_TAG();
+
+ if (state) {
+ if (state == TAG_RAISE) {
+ VALUE errinfo = th->errinfo;
+ if (strcmp(file, "(eval)") == 0) {
+ VALUE mesg, errat, bt2;
+ extern VALUE rb_get_backtrace(VALUE info);
+
+ errat = rb_get_backtrace(errinfo);
+ mesg = rb_attr_get(errinfo, rb_intern("mesg"));
+ if (!NIL_P(errat) && TYPE(errat) == T_ARRAY &&
+ (bt2 = vm_backtrace(th, -2), RARRAY_LEN(bt2) > 0)) {
+ if (!NIL_P(mesg) && TYPE(mesg) == T_STRING && !RSTRING_CLEN(mesg)) {
+ rb_str_update(mesg, 0, 0, rb_str_new2(": "));
+ rb_str_update(mesg, 0, 0, RARRAY_AT(errat, 0));
+ }
+ rb_ary_store(errat, 0, RARRAY_AT(bt2, 0));
+ }
+ }
+ rb_exc_raise(errinfo);
+ }
+ JUMP_TAG(state);
+ }
+ return result;
+}
+
+static VALUE
+eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line)
+{
+ return eval_string_with_cref(self, src, scope, 0, file, line);
+}
+
+/*
+ * call-seq:
+ * eval(string [, binding [, filename [,lineno]]]) => obj
+ *
+ * Evaluates the Ruby expression(s) in <em>string</em>. If
+ * <em>binding</em> is given, the evaluation is performed in its
+ * context. The binding may be a <code>Binding</code> object or a
+ * <code>Proc</code> object. If the optional <em>filename</em> and
+ * <em>lineno</em> parameters are present, they will be used when
+ * reporting syntax errors.
+ *
+ * def getBinding(str)
+ * return binding
+ * end
+ * str = "hello"
+ * eval "str + ' Fred'" #=> "hello Fred"
+ * eval "str + ' Fred'", getBinding("bye") #=> "bye Fred"
+ */
+
+VALUE
+rb_f_eval(int argc, VALUE *argv, VALUE self)
+{
+ VALUE src, scope, vfile, vline;
+ const char *file = "(eval)";
+ int line = 1;
+
+ rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
+ if (rb_safe_level() >= 4) {
+ StringValue(src);
+ if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {
+ rb_raise(rb_eSecurityError,
+ "Insecure: can't modify trusted binding");
+ }
+ }
+ else {
+ SafeStringValue(src);
+ }
+ if (argc >= 3) {
+ StringValue(vfile);
+ }
+ if (argc >= 4) {
+ line = NUM2INT(vline);
+ }
+
+ if (!NIL_P(vfile))
+ file = RSTRING_CPTR(vfile);
+ return eval_string(self, src, scope, file, line);
+}
+
+VALUE
+rb_eval_string(const char *str)
+{
+ return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
+}
+
+VALUE
+rb_eval_string_protect(const char *str, int *state)
+{
+ return rb_protect((VALUE (*)(VALUE))rb_eval_string, (VALUE)str, state);
+}
+
+VALUE
+rb_eval_string_wrap(const char *str, int *state)
+{
+ int status;
+ rb_thread_t *th = GET_THREAD();
+ VALUE self = th->top_self;
+ VALUE wrapper = th->top_wrapper;
+ VALUE val;
+
+ th->top_wrapper = rb_module_new();
+ th->top_self = rb_obj_clone(rb_vm_top_self());
+ rb_extend_object(th->top_self, th->top_wrapper);
+
+ val = rb_eval_string_protect(str, &status);
+
+ th->top_self = self;
+ th->top_wrapper = wrapper;
+
+ if (state) {
+ *state = status;
+ }
+ else if (status) {
+ JUMP_TAG(status);
+ }
+ return val;
+}
+
+VALUE
+rb_eval_cmd(VALUE cmd, VALUE arg, int level)
+{
+ int state;
+ VALUE val = Qnil; /* OK */
+ volatile int safe = rb_safe_level();
+
+ if (OBJ_TAINTED(cmd)) {
+ level = 4;
+ }
+
+ if (TYPE(cmd) != T_STRING) {
+ PUSH_TAG();
+ rb_set_safe_level_force(level);
+ if ((state = EXEC_TAG()) == 0) {
+ val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LEN(arg),
+ RARRAY_PTR(arg));
+ }
+ POP_TAG();
+
+ rb_set_safe_level_force(safe);
+
+ if (state)
+ JUMP_TAG(state);
+ return val;
+ }
+
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0);
+ }
+ POP_TAG();
+
+ rb_set_safe_level_force(safe);
+ if (state) vm_jump_tag_but_local_jump(state, val);
+ return val;
+}
+
+/* block eval under the class/module context */
+
+static VALUE
+yield_under(VALUE under, VALUE self, VALUE values)
+{
+ rb_thread_t *th = GET_THREAD();
+ rb_block_t block, *blockptr;
+ NODE *cref = vm_cref_push(th, under, NOEX_PUBLIC);
+
+ if ((blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0])) != 0) {
+ block = *blockptr;
+ block.self = self;
+ th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
+ }
+
+ if (values == Qundef) {
+ return vm_yield_with_cref(th, 0, 0, cref);
+ }
+ else {
+ return vm_yield_with_cref(th, RARRAY_LEN(values), RARRAY_PTR(values), cref);
+ }
+}
+
+/* string eval under the class/module context */
+static VALUE
+eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
+{
+ NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC);
+
+ if (rb_safe_level() >= 4) {
+ StringValue(src);
+ }
+ else {
+ SafeStringValue(src);
+ }
+
+ return eval_string_with_cref(self, src, Qnil, cref, file, line);
+}
+
+static VALUE
+specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
+{
+ if (rb_block_given_p()) {
+ if (argc > 0) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
+ }
+ return yield_under(klass, self, Qundef);
+ }
+ else {
+ const char *file = "(eval)";
+ int line = 1;
+
+ if (argc == 0) {
+ rb_raise(rb_eArgError, "block not supplied");
+ }
+ else {
+ if (rb_safe_level() >= 4) {
+ StringValue(argv[0]);
+ }
+ else {
+ SafeStringValue(argv[0]);
+ }
+ if (argc > 3) {
+ const char *name = rb_id2name(rb_frame_callee());
+ rb_raise(rb_eArgError,
+ "wrong number of arguments: %s(src) or %s{..}",
+ name, name);
+ }
+ if (argc > 2)
+ line = NUM2INT(argv[2]);
+ if (argc > 1) {
+ file = StringValuePtr(argv[1]);
+ }
+ }
+ return eval_under(klass, self, argv[0], file, line);
+ }
+}
+
+/*
+ * call-seq:
+ * obj.instance_eval(string [, filename [, lineno]] ) => obj
+ * obj.instance_eval {| | block } => obj
+ *
+ * Evaluates a string containing Ruby source code, or the given block,
+ * within the context of the receiver (_obj_). In order to set the
+ * context, the variable +self+ is set to _obj_ while
+ * the code is executing, giving the code access to _obj_'s
+ * instance variables. In the version of <code>instance_eval</code>
+ * that takes a +String+, the optional second and third
+ * parameters supply a filename and starting line number that are used
+ * when reporting compilation errors.
+ *
+ * class KlassWithSecret
+ * def initialize
+ * @secret = 99
+ * end
+ * end
+ * k = KlassWithSecret.new
+ * k.instance_eval { @secret } #=> 99
+ */
+
+VALUE
+rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
+{
+ VALUE klass;
+
+ if (SPECIAL_CONST_P(self)) {
+ klass = Qnil;
+ }
+ else {
+ klass = rb_singleton_class(self);
+ }
+ return specific_eval(argc, argv, klass, self);
+}
+
+/*
+ * call-seq:
+ * obj.instance_exec(arg...) {|var...| block } => obj
+ *
+ * Executes the given block within the context of the receiver
+ * (_obj_). In order to set the context, the variable +self+ is set
+ * to _obj_ while the code is executing, giving the code access to
+ * _obj_'s instance variables. Arguments are passed as block parameters.
+ *
+ * class KlassWithSecret
+ * def initialize
+ * @secret = 99
+ * end
+ * end
+ * k = KlassWithSecret.new
+ * k.instance_exec(5) {|x| @secret+x } #=> 104
+ */
+
+VALUE
+rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
+{
+ VALUE klass;
+
+ if (SPECIAL_CONST_P(self)) {
+ klass = Qnil;
+ }
+ else {
+ klass = rb_singleton_class(self);
+ }
+ return yield_under(klass, self, rb_ary_new4(argc, argv));
+}
+
+/*
+ * call-seq:
+ * mod.class_eval(string [, filename [, lineno]]) => obj
+ * mod.module_eval {|| block } => obj
+ *
+ * Evaluates the string or block in the context of _mod_. This can
+ * be used to add methods to a class. <code>module_eval</code> returns
+ * the result of evaluating its argument. The optional _filename_
+ * and _lineno_ parameters set the text for error messages.
+ *
+ * class Thing
+ * end
+ * a = %q{def hello() "Hello there!" end}
+ * Thing.module_eval(a)
+ * puts Thing.new.hello()
+ * Thing.module_eval("invalid code", "dummy", 123)
+ *
+ * <em>produces:</em>
+ *
+ * Hello there!
+ * dummy:123:in `module_eval': undefined local variable
+ * or method `code' for Thing:Class
+ */
+
+VALUE
+rb_mod_module_eval(int argc, VALUE *argv, VALUE mod)
+{
+ return specific_eval(argc, argv, mod, mod);
+}
+
+/*
+ * call-seq:
+ * mod.module_exec(arg...) {|var...| block } => obj
+ * mod.class_exec(arg...) {|var...| block } => obj
+ *
+ * Evaluates the given block in the context of the class/module.
+ * The method defined in the block will belong to the receiver.
+ *
+ * class Thing
+ * end
+ * Thing.class_exec{
+ * def hello() "Hello there!" end
+ * }
+ * puts Thing.new.hello()
+ *
+ * <em>produces:</em>
+ *
+ * Hello there!
+ */
+
+VALUE
+rb_mod_module_exec(int argc, VALUE *argv, VALUE mod)
+{
+ return yield_under(mod, mod, rb_ary_new4(argc, argv));
+}
+
+NORETURN(static VALUE rb_f_throw _((int, VALUE *)));
+
+/*
+ * call-seq:
+ * throw(symbol [, obj])
+ *
+ * Transfers control to the end of the active +catch+ block
+ * waiting for _symbol_. Raises +NameError+ if there
+ * is no +catch+ block for the symbol. The optional second
+ * parameter supplies a return value for the +catch+ block,
+ * which otherwise defaults to +nil+. For examples, see
+ * <code>Kernel::catch</code>.
+ */
+
+static VALUE
+rb_f_throw(int argc, VALUE *argv)
+{
+ VALUE tag, value;
+ rb_thread_t *th = GET_THREAD();
+ struct rb_vm_tag *tt = th->tag;
+
+ rb_scan_args(argc, argv, "11", &tag, &value);
+ while (tt) {
+ if (tt->tag == tag) {
+ tt->retval = value;
+ break;
+ }
+ tt = tt->prev;
+ }
+ if (!tt) {
+ VALUE desc = rb_inspect(tag);
+ rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_CPTR(desc));
+ }
+ rb_trap_restore_mask();
+ th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW);
+
+ JUMP_TAG(TAG_THROW);
+#ifndef __GNUC__
+ return Qnil; /* not reached */
+#endif
+}
+
+void
+rb_throw(const char *tag, VALUE val)
+{
+ VALUE argv[2];
+
+ argv[0] = ID2SYM(rb_intern(tag));
+ argv[1] = val;
+ rb_f_throw(2, argv);
+}
+
+void
+rb_throw_obj(VALUE tag, VALUE val)
+{
+ VALUE argv[2];
+
+ argv[0] = tag;
+ argv[1] = val;
+ rb_f_throw(2, argv);
+}
+
+/*
+ * call-seq:
+ * catch(symbol) {| | block } > obj
+ *
+ * +catch+ executes its block. If a +throw+ is
+ * executed, Ruby searches up its stack for a +catch+ block
+ * with a tag corresponding to the +throw+'s
+ * _symbol_. If found, that block is terminated, and
+ * +catch+ returns the value given to +throw+. If
+ * +throw+ is not called, the block terminates normally, and
+ * the value of +catch+ is the value of the last expression
+ * evaluated. +catch+ expressions may be nested, and the
+ * +throw+ call need not be in lexical scope.
+ *
+ * def routine(n)
+ * puts n
+ * throw :done if n <= 0
+ * routine(n-1)
+ * end
+ *
+ *
+ * catch(:done) { routine(3) }
+ *
+ * <em>produces:</em>
+ *
+ * 3
+ * 2
+ * 1
+ * 0
+ */
+
+static VALUE
+rb_f_catch(int argc, VALUE *argv)
+{
+ VALUE tag;
+ int state;
+ VALUE val = Qnil; /* OK */
+ rb_thread_t *th = GET_THREAD();
+ rb_control_frame_t *saved_cfp = th->cfp;
+
+ if (argc == 0) {
+ tag = rb_obj_alloc(rb_cObject);
+ }
+ else {
+ rb_scan_args(argc, argv, "01", &tag);
+ }
+ PUSH_TAG();
+
+ th->tag->tag = tag;
+
+ if ((state = EXEC_TAG()) == 0) {
+ val = rb_yield_0(1, &tag);
+ }
+ else if (state == TAG_THROW && RNODE(th->errinfo)->u1.value == tag) {
+ th->cfp = saved_cfp;
+ val = th->tag->retval;
+ th->errinfo = Qnil;
+ state = 0;
+ }
+ POP_TAG();
+ if (state)
+ JUMP_TAG(state);
+
+ return val;
+}
+
+static VALUE
+catch_null_i(VALUE dmy)
+{
+ return rb_funcall(Qnil, rb_intern("catch"), 0, 0);
+}
+
+static VALUE
+catch_i(VALUE tag)
+{
+ return rb_funcall(Qnil, rb_intern("catch"), 1, tag);
+}
+
+VALUE
+rb_catch(const char *tag, VALUE (*func)(), VALUE data)
+{
+ if (!tag) {
+ return rb_iterate(catch_null_i, 0, func, data);
+ }
+ return rb_iterate(catch_i, ID2SYM(rb_intern(tag)), func, data);
+}
+
+VALUE
+rb_catch_obj(VALUE tag, VALUE (*func)(), VALUE data)
+{
+ return rb_iterate((VALUE (*)_((VALUE)))catch_i, tag, func, data);
+}
+
+/*
+ * call-seq:
+ * caller(start=1) => array
+ *
+ * Returns the current execution stack---an array containing strings in
+ * the form ``<em>file:line</em>'' or ``<em>file:line: in
+ * `method'</em>''. The optional _start_ parameter
+ * determines the number of initial stack entries to omit from the
+ * result.
+ *
+ * def a(skip)
+ * caller(skip)
+ * end
+ * def b(skip)
+ * a(skip)
+ * end
+ * def c(skip)
+ * b(skip)
+ * end
+ * c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"]
+ * c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"]
+ * c(2) #=> ["prog:8:in `c'", "prog:12"]
+ * c(3) #=> ["prog:13"]
+ */
+
+static VALUE
+rb_f_caller(int argc, VALUE *argv)
+{
+ VALUE level;
+ int lev;
+
+ rb_scan_args(argc, argv, "01", &level);
+
+ if (NIL_P(level))
+ lev = 1;
+ else
+ lev = NUM2INT(level);
+ if (lev < 0)
+ rb_raise(rb_eArgError, "negative level (%d)", lev);
+
+ return vm_backtrace(GET_THREAD(), lev);
+}
+
+void
+rb_backtrace(void)
+{
+ long i;
+ VALUE ary;
+
+ ary = vm_backtrace(GET_THREAD(), -1);
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ printf("\tfrom %s\n", RSTRING_CPTR(RARRAY_AT(ary, i)));
+ }
+}
+
+VALUE
+rb_make_backtrace(void)
+{
+ return vm_backtrace(GET_THREAD(), -1);
+}
+
+void
+Init_vm_eval(void)
+{
+ rb_define_global_function("catch", rb_f_catch, -1);
+ rb_define_global_function("throw", rb_f_throw, -1);
+
+ rb_define_global_function("loop", rb_f_loop, 0);
+
+ rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
+ rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
+ rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
+
+ rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
+ rb_define_method(rb_mKernel, "send", rb_f_send, -1);
+ rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
+
+ rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
+ rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
+
+ rb_define_global_function("caller", rb_f_caller, -1);
+}
+
Property changes on: MacRuby/trunk/vm_eval.c
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: MacRuby/trunk/vm_evalbody.c
===================================================================
--- MacRuby/trunk/vm_evalbody.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/vm_evalbody.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -3,7 +3,7 @@
vm_evalbody.c -
- $Author: shyouhei $
+ $Author: ko1 $
Copyright (C) 2004-2007 Koichi Sasada
@@ -26,7 +26,7 @@
/* #define DECL_SC_REG(r, reg) VALUE reg_##r */
#if !OPT_CALL_THREADED_CODE
-VALUE
+static VALUE
vm_eval(rb_thread_t *th, VALUE initial)
{
@@ -140,3 +140,9 @@
return ret;
}
#endif
+
+const void **
+vm_get_insns_address_table(void)
+{
+ return (const void **)vm_eval(0, 0);
+}
Modified: MacRuby/trunk/vm_insnhelper.c
===================================================================
--- MacRuby/trunk/vm_insnhelper.c 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/vm_insnhelper.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -2,7 +2,7 @@
insnhelper.c - instruction helper functions.
- $Author: matz $
+ $Author: ko1 $
Copyright (C) 2007 Koichi Sasada
@@ -21,14 +21,16 @@
#endif
static inline rb_control_frame_t *
-vm_push_frame(rb_thread_t *th, rb_iseq_t *iseq, VALUE type,
- VALUE self, VALUE specval, VALUE *pc,
- VALUE *sp, VALUE *lfp, int local_size)
+vm_push_frame(rb_thread_t * th, const rb_iseq_t * iseq,
+ VALUE type, VALUE self, VALUE specval,
+ const VALUE *pc, VALUE *sp, VALUE *lfp,
+ int local_size)
{
- VALUE *dfp;
- rb_control_frame_t *cfp;
+ rb_control_frame_t * const cfp = th->cfp = th->cfp - 1;
int i;
+ /* setup vm value stack */
+
/* nil initialize */
for (i=0; i < local_size; i++) {
*sp = Qnil;
@@ -37,21 +39,21 @@
/* set special val */
*sp = GC_GUARDED_PTR(specval);
- dfp = sp;
if (lfp == 0) {
lfp = sp;
}
- cfp = th->cfp = th->cfp - 1;
- cfp->pc = pc;
+ /* setup vm control frame stack */
+
+ cfp->pc = (VALUE *)pc;
cfp->sp = sp + 1;
cfp->bp = sp + 1;
- cfp->iseq = iseq;
+ cfp->iseq = (rb_iseq_t *) iseq;
cfp->flag = type;
cfp->self = self;
cfp->lfp = lfp;
- cfp->dfp = dfp;
+ cfp->dfp = sp;
cfp->proc = 0;
#define COLLECT_PROFILE 0
@@ -96,24 +98,25 @@
/* method dispatch */
-static int
-vm_callee_setup_arg(rb_thread_t *th, rb_iseq_t *iseq,
- int argc, VALUE *argv, rb_block_t **block)
+static inline int
+vm_callee_setup_arg(rb_thread_t *th, const rb_iseq_t * iseq,
+ int orig_argc, VALUE * orig_argv, const rb_block_t **block)
{
const int m = iseq->argc;
- const int orig_argc = argc;
if (LIKELY(iseq->arg_simple & 0x01)) {
/* simple check */
- if (argc != m) {
+ if (orig_argc != m) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
- argc, m);
+ orig_argc, m);
}
return 0;
}
else {
- VALUE * const dst = argv;
+ int argc = orig_argc;
+ VALUE *argv = orig_argv;
int opt_pc = 0;
+
th->mark_stack_len = argc + iseq->arg_size;
/* mandatory */
@@ -133,7 +136,7 @@
argv = new_argv;
}
- MEMCPY(&dst[iseq->arg_post_start], &argv[argc -= iseq->arg_post_len],
+ MEMCPY(&orig_argv[iseq->arg_post_start], &argv[argc -= iseq->arg_post_len],
VALUE, iseq->arg_post_len);
}
@@ -154,7 +157,7 @@
else {
int i;
for (i = argc; i<opts; i++) {
- dst[i + m] = Qnil;
+ orig_argv[i + m] = Qnil;
}
opt_pc = iseq->arg_opt_table[argc];
argc = 0;
@@ -163,14 +166,14 @@
/* rest arguments */
if (iseq->arg_rest != -1) {
- dst[iseq->arg_rest] = rb_ary_new4(argc, argv);
+ orig_argv[iseq->arg_rest] = rb_ary_new4(argc, argv);
argc = 0;
}
/* block arguments */
if (block && iseq->arg_block != -1) {
VALUE blockval = Qnil;
- rb_block_t * const blockptr = *block;
+ const rb_block_t *blockptr = *block;
if (argc != 0) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
@@ -192,7 +195,7 @@
}
}
- dst[iseq->arg_block] = blockval; /* Proc or nil */
+ orig_argv[iseq->arg_block] = blockval; /* Proc or nil */
}
th->mark_stack_len = 0;
@@ -201,7 +204,7 @@
}
static inline int
-caller_setup_args(rb_thread_t *th, rb_control_frame_t *cfp, VALUE flag,
+caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, VALUE flag,
int argc, rb_iseq_t *blockiseq, rb_block_t **block)
{
rb_block_t *blockptr = 0;
@@ -263,7 +266,8 @@
}
static inline VALUE
-call_cfunc(VALUE (*func)(), VALUE recv, int len, int argc, const VALUE *argv)
+call_cfunc(VALUE (*func)(), VALUE recv,
+ int len, int argc, const VALUE *argv)
{
/* printf("len: %d, argc: %d\n", len, argc); */
@@ -350,9 +354,9 @@
}
static inline VALUE
-vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp, int num,
- ID id, VALUE recv, VALUE klass, VALUE flag,
- NODE *mn, rb_block_t *blockptr)
+vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp,
+ int num, ID id, VALUE recv, VALUE klass,
+ VALUE flag, const NODE *mn, const rb_block_t *blockptr)
{
VALUE val;
@@ -379,8 +383,8 @@
return val;
}
-static int
-vm_cfunc_flags(rb_control_frame_t *cfp)
+static inline int
+vm_cfunc_flags(const rb_control_frame_t *cfp)
{
if (RUBYVM_CFUNC_FRAME_P(cfp))
return cfp->flag >> FRAME_MAGIC_MASK_BITS;
@@ -405,10 +409,10 @@
}
static inline VALUE
-vm_method_missing(rb_thread_t *th, ID id, VALUE recv, int num,
- rb_block_t *blockptr, int opt)
+vm_method_missing(rb_thread_t *th, ID id, VALUE recv,
+ int num, rb_block_t *blockptr, int opt)
{
- rb_control_frame_t *reg_cfp = th->cfp;
+ rb_control_frame_t * const reg_cfp = th->cfp;
VALUE *argv = STACK_ADDR_FROM_TOP(num + 1);
VALUE val;
argv[0] = ID2SYM(id);
@@ -421,8 +425,8 @@
static inline void
vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp,
- int argc, rb_block_t *blockptr, VALUE flag,
- VALUE iseqval, VALUE recv, VALUE klass)
+ const int argc, const rb_block_t *blockptr, const VALUE flag,
+ const VALUE iseqval, const VALUE recv, const VALUE klass)
{
rb_iseq_t *iseq;
int opt_pc, i;
@@ -454,7 +458,7 @@
}
else {
VALUE *p_rsp;
- cfp = ++th->cfp; /* pop cf */
+ th->cfp++; /* pop cf */
p_rsp = th->cfp->sp;
/* copy arguments */
@@ -476,15 +480,15 @@
}
static inline VALUE
-vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
- int num, rb_block_t *blockptr, VALUE flag,
- ID id, NODE *mn, VALUE recv, VALUE klass)
+vm_call_method(rb_thread_t * const th, rb_control_frame_t * const cfp,
+ const int num, rb_block_t * const blockptr, const VALUE flag,
+ const ID id, const NODE * mn, const VALUE recv, VALUE klass)
{
VALUE val;
start_method_dispatch:
- if ((mn != 0)) {
+ if (mn != 0) {
if ((mn->nd_noex == 0)) {
/* dispatch method */
NODE *node;
@@ -606,8 +610,9 @@
}
static inline void
-vm_send_optimize(rb_control_frame_t *reg_cfp,
- NODE **mn, rb_num_t *flag, rb_num_t *num, ID *id, VALUE klass)
+vm_send_optimize(rb_control_frame_t * const reg_cfp, NODE ** const mn,
+ rb_num_t * const flag, rb_num_t * const num,
+ ID * const id, const VALUE klass)
{
if (*mn && nd_type((*mn)->nd_body) == NODE_CFUNC) {
NODE *node = (*mn)->nd_body;
@@ -634,7 +639,7 @@
/* yield */
static inline int
-block_proc_is_lambda(VALUE procval)
+block_proc_is_lambda(const VALUE procval)
{
rb_proc_t *proc;
@@ -648,8 +653,8 @@
}
static inline VALUE
-vm_yield_with_cfunc(rb_thread_t *th, rb_block_t *block,
- VALUE self, int argc, VALUE *argv)
+vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
+ VALUE self, int argc, const VALUE *argv)
{
NODE *ifunc = (NODE *) block->iseq;
VALUE val;
@@ -677,11 +682,12 @@
}
static inline int
-vm_yield_setup_args(rb_thread_t *th, rb_iseq_t *iseq,
- int argc, VALUE *argv, rb_block_t *blockptr, int lambda)
+vm_yield_setup_args(rb_thread_t * const th, const rb_iseq_t *iseq,
+ int orig_argc, VALUE *argv,
+ const rb_block_t *blockptr, int lambda)
{
if (0) { /* for debug */
- printf(" argc: %d\n", argc);
+ printf(" argc: %d\n", orig_argc);
printf("iseq argc: %d\n", iseq->argc);
printf("iseq opts: %d\n", iseq->arg_opts);
printf("iseq rest: %d\n", iseq->arg_rest);
@@ -693,10 +699,11 @@
if (lambda) {
/* call as method */
- return vm_callee_setup_arg(th, iseq, argc, argv, &blockptr);
+ return vm_callee_setup_arg(th, iseq, orig_argc, argv, &blockptr);
}
else {
int i;
+ int argc = orig_argc;
const int m = iseq->argc;
th->mark_stack_len = argc;
@@ -796,8 +803,7 @@
static VALUE
vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_num_t flag)
{
- VALUE val;
- rb_block_t *block = GET_BLOCK_PTR();
+ rb_block_t * const block = GET_BLOCK_PTR();
rb_iseq_t *iseq;
int argc = num;
@@ -811,7 +817,7 @@
if (BUILTIN_TYPE(iseq) != T_NODE) {
int opt_pc;
const int arg_size = iseq->arg_size;
- VALUE *rsp = GET_SP() - argc;
+ VALUE * const rsp = GET_SP() - argc;
SET_SP(rsp);
CHECK_STACK_OVERFLOW(GET_CFP(), iseq->stack_max);
@@ -826,51 +832,30 @@
return Qundef;
}
else {
- val = vm_yield_with_cfunc(th, block, block->self, argc, STACK_ADDR_FROM_TOP(argc));
+ VALUE val = vm_yield_with_cfunc(th, block, block->self, argc, STACK_ADDR_FROM_TOP(argc));
POPN(argc); /* TODO: should put before C/yield? */
return val;
}
}
-/* cref */
+/* svar */
-static NODE *
-lfp_get_special_cref(VALUE *lfp)
-{
- struct RValues *values;
- if (((VALUE)(values = (void *)lfp[-1])) != Qnil && values->basic.klass) {
- return (NODE *)values->basic.klass;
- }
- else {
- return 0;
- }
-}
-
-static struct RValues *
-new_value(void)
-{
- NEWOBJ(val, struct RValues);
- OBJSETUP(val, 0, T_VALUES);
- val->v1 = val->v2 = val->v3 = Qnil;
- return val;
-}
-
-static struct RValues *
+static inline NODE *
lfp_svar_place(rb_thread_t *th, VALUE *lfp)
{
- struct RValues *svar;
+ NODE *svar;
if (th->local_lfp != lfp) {
- svar = (struct RValues *)lfp[-1];
+ svar = (NODE *)lfp[-1];
if ((VALUE)svar == Qnil) {
- svar = new_value();
+ svar = NEW_IF(Qnil, Qnil, Qnil);
GC_WB(&lfp[-1], svar);
}
}
else {
- svar = (struct RValues *)th->local_svar;
+ svar = (NODE *)th->local_svar;
if ((VALUE)svar == Qnil) {
- svar = new_value();
+ svar = NEW_IF(Qnil, Qnil, Qnil);
GC_WB(&th->local_svar, (VALUE)svar);
}
}
@@ -880,17 +865,15 @@
static VALUE
lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key)
{
- struct RValues *svar = lfp_svar_place(th, lfp);
+ NODE *svar = lfp_svar_place(th, lfp);
switch (key) {
case 0:
- return svar->v1;
+ return svar->u1.value;
case 1:
- return svar->v2;
- case 2:
- return svar->basic.klass;
+ return svar->u2.value;
default: {
- VALUE hash = svar->v3;
+ const VALUE hash = svar->u3.value;
if (hash == Qnil) {
return Qnil;
@@ -905,54 +888,38 @@
static void
lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val)
{
- struct RValues *svar = lfp_svar_place(th, lfp);
+ NODE *svar = lfp_svar_place(th, lfp);
switch (key) {
case 0:
- GC_WB(&svar->v1, val);
+ GC_WB(&svar->u1.value, val);
return;
case 1:
- GC_WB(&svar->v2, val);
+ GC_WB(&svar->u2.value, val);
return;
- case 2:
- GC_WB(&svar->basic.klass, val);
- return;
default: {
- VALUE hash = svar->v3;
+ VALUE hash = svar->u3.value;
if (hash == Qnil) {
- svar->v3 = hash = rb_hash_new();
- GC_WB(&svar->v3, hash);
+ svar->u3.value = hash = rb_hash_new();
+ GC_WB(&svar->u3.value, hash);
}
rb_hash_aset(hash, key, val);
}
}
}
-static NODE *
-get_cref(rb_iseq_t *iseq, VALUE *lfp)
-{
- NODE *cref;
- if ((cref = lfp_get_special_cref(lfp)) != 0) {
- /* */
- }
- else if ((cref = iseq->cref_stack) != 0) {
- /* */
- }
- else {
- rb_bug("get_cref: unreachable");
- }
- return cref;
-}
-
static inline VALUE
vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type)
{
VALUE val;
if (type == 0) {
- if (FIXNUM_P(key)) key = FIX2INT(key);
- val = lfp_svar_get(th, lfp, key);
+ VALUE k = key;
+ if (FIXNUM_P(key)) {
+ k = FIX2INT(key);
+ }
+ val = lfp_svar_get(th, lfp, k);
}
else {
VALUE backref = lfp_svar_get(th, lfp, 1);
@@ -982,6 +949,30 @@
return val;
}
+static NODE *
+vm_get_cref(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
+{
+ NODE *cref = 0;
+
+ while (1) {
+ if (lfp == dfp) {
+ cref = iseq->cref_stack;
+ break;
+ }
+ else if (dfp[-1] != Qnil) {
+ cref = (NODE *)dfp[-1];
+ break;
+ }
+ dfp = GET_PREV_DFP(dfp);
+ }
+
+ if (cref == 0) {
+ rb_bug("vm_get_cref: unreachable");
+ }
+ return cref;
+}
+
+
static inline void
vm_check_if_namespace(VALUE klass)
{
@@ -996,51 +987,47 @@
}
static inline VALUE
-vm_get_ev_const(rb_thread_t *th, rb_iseq_t *iseq,
- VALUE klass, ID id, int is_defined)
+vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq,
+ VALUE orig_klass, ID id, int is_defined)
{
VALUE val;
- if (klass == Qnil) {
+ if (orig_klass == Qnil) {
/* in current lexical scope */
- NODE *root_cref = get_cref(iseq, th->cfp->lfp);
- NODE *cref = root_cref;
+ const NODE *root_cref = vm_get_cref(iseq, th->cfp->lfp, th->cfp->dfp);
+ const NODE *cref = root_cref;
+ VALUE klass = orig_klass;
while (cref && cref->nd_next) {
klass = cref->nd_clss;
cref = cref->nd_next;
- if (klass == 0) {
- continue;
- }
- if (NIL_P(klass)) {
- if (is_defined) {
- /* TODO: check */
- return 1;
- }
- else {
- klass = CLASS_OF(th->cfp->self);
- return rb_const_get(klass, id);
- }
- }
- search_continue:
- if (RCLASS_IV_TBL(klass) &&
- st_lookup(RCLASS_IV_TBL(klass), id, &val)) {
- if (val == Qundef) {
- rb_autoload_load(klass, id);
- goto search_continue;
- }
- else {
- if (is_defined) {
- return 1;
+ if (!NIL_P(klass)) {
+ search_continue:
+ if (RCLASS_IV_TBL(klass) &&
+ st_lookup(RCLASS_IV_TBL(klass), id, &val)) {
+ if (val == Qundef) {
+ rb_autoload_load(klass, id);
+ goto search_continue;
}
else {
- return val;
+ if (is_defined) {
+ return 1;
+ }
+ else {
+ return val;
+ }
}
}
}
}
+
+ /* search self */
klass = root_cref->nd_clss;
+ if (NIL_P(klass)) {
+ klass = CLASS_OF(th->cfp->self);
+ }
+
if (is_defined) {
return rb_const_defined(klass, id);
}
@@ -1049,28 +1036,31 @@
}
}
else {
- vm_check_if_namespace(klass);
+ vm_check_if_namespace(orig_klass);
if (is_defined) {
- return rb_const_defined_from(klass, id);
+ return rb_const_defined_from(orig_klass, id);
}
else {
- return rb_const_get_from(klass, id);
+ return rb_const_get_from(orig_klass, id);
}
}
}
static inline VALUE
-vm_get_cvar_base(rb_thread_t *th, rb_iseq_t *iseq)
+vm_get_cvar_base(NODE *cref)
{
- NODE *cref = get_cref(iseq, th->cfp->lfp);
- VALUE klass = Qnil;
+ VALUE klass;
- if (cref) {
- klass = cref->nd_clss;
+ while (cref && cref->nd_next && (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON))) {
+ cref = cref->nd_next;
+
if (!cref->nd_next) {
rb_warn("class variable access from toplevel");
}
}
+
+ klass = cref->nd_clss;
+
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class variables available");
}
@@ -1078,13 +1068,17 @@
}
static inline void
-vm_define_method(rb_thread_t *th, VALUE obj,
- ID id, rb_iseq_t *miseq, rb_num_t is_singleton, NODE *cref)
+vm_define_method(rb_thread_t *th, VALUE obj, ID id, rb_iseq_t *miseq,
+ rb_num_t is_singleton, NODE *cref)
{
NODE *newbody;
- int noex = cref->nd_visi;
VALUE klass = cref->nd_clss;
+ int noex = cref->nd_visi;
+ if (NIL_P(klass)) {
+ rb_raise(rb_eTypeError, "no class/module to add method");
+ }
+
if (is_singleton) {
if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
rb_raise(rb_eTypeError,
@@ -1102,6 +1096,7 @@
/* dup */
COPY_CREF(miseq->cref_stack, cref);
+ GC_WB(&miseq->cref_stack, cref);
miseq->klass = klass;
miseq->defined_method_id = id;
newbody = NEW_NODE(RUBY_VM_METHOD_NODE, 0, miseq->self, 0);
@@ -1119,72 +1114,54 @@
rb_control_frame_t *cfp)
{
VALUE *argv = cfp->sp - *pnum;
- ID id;
NODE *mn;
- char buf[128];
+ ID id;
- if (/* *pmn == NULL
- &&*/ *pnum == 2
- && TYPE(argv[1]) == T_ARRAY
- && rb_ary_is_named_args(argv[1])) {
-
- unsigned i, count;
-
- if ((RARRAY_LEN(argv[1]) % 2) != 0)
- rb_bug("invalid named arg ary len %d", RARRAY_LEN(argv[1]));
-
- strncpy(buf, rb_id2name(*pid), sizeof buf);
- strncat(buf, ":", sizeof buf);
-
- count = RARRAY_LEN(argv[1]);
-
- for (i = 0; i < count; i += 2) {
- VALUE sym = RARRAY_AT(argv[1], i);
- if (TYPE(sym) != T_SYMBOL)
- rb_bug("expected symbol for first pair element");
- strncat(buf, rb_id2name(SYM2ID(sym)), sizeof buf);
- strncat(buf, ":", sizeof buf);
- }
-
- id = rb_intern(buf);
- if ((mn = rb_method_node(CLASS_OF(recv), id)) != NULL
- || (mn = rb_objc_define_objc_mid_closure(recv, id, NULL)) != NULL) {
- unsigned j, newnum = 1 + (count / 2);
- void **new_argv = alloca(sizeof(void *) * newnum);
- new_argv[0] = (void *)argv[0];
- for (i = 0, j = 1; i < count; i += 2, j++) {
- new_argv[j] = (void *)RARRAY_AT(argv[1], i + 1);
- }
- argv = cfp->sp - newnum;
- cfp->bp -= newnum - *pnum;
-
- memcpy(argv, new_argv, sizeof(void *) * newnum);
- *pmn = mn;
- *pid = id;
- *pnum = newnum;
- }
- else {
- VALUE h = rb_hash_new();
- for (i = 0; i < count; i += 2) {
- rb_hash_aset(h, RARRAY_AT(argv[1], i),
- RARRAY_AT(argv[1], i+1));
- }
- argv[1] = h;
- }
- return;
- }
-
if (*pmn == NULL) {
- id = rb_objc_missing_sel(*pid, *pnum);
- if (id != *pid) {
- mn = rb_objc_define_objc_mid_closure(recv, id, NULL);
+ const char *p, *mname;
+ long i;
+ mname = rb_id2name(*pid);
+ if (*pid > 1 && (p = strchr(mname, ':')) != NULL) {
+ char buf[512];
+ strlcpy(buf, mname, sizeof buf);
+ buf[p - mname] = '\0';
+ mname = p + 1;
+ id = rb_intern(buf);
+ mn = rb_method_node(CLASS_OF(recv), id);
if (mn != NULL) {
+ VALUE h = rb_hash_new();
+ VALUE new_argv[2];
+ for (i = 1; i < *pnum; i++) {
+ p = strchr(mname, ':');
+ if (p == NULL)
+ return;
+ strlcpy(buf, mname, sizeof buf);
+ buf[p - mname] = '\0';
+ mname = p + 1;
+ rb_hash_aset(h, ID2SYM(rb_intern(buf)), argv[i]);
+ }
+ new_argv[0] = argv[0];
+ new_argv[1] = h;
+ memcpy(cfp->sp - 2, new_argv, sizeof(void *) * 2);
+ cfp->bp -= 2 - *pnum;
*pmn = mn;
*pid = id;
+ *pnum = 2;
return;
}
}
}
+
+ if (*pmn == NULL) {
+ id = rb_objc_missing_sel(*pid, *pnum);
+ if (id != *pid
+ && (mn = rb_objc_define_objc_mid_closure(recv, id, NULL))
+ != NULL) {
+ *pmn = mn;
+ *pid = id;
+ return;
+ }
+ }
else {
mn = rb_objc_define_objc_mid_closure(recv, *pid, *pmn);
if (mn != NULL) {
@@ -1239,7 +1216,9 @@
}
static void
-vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *ip, VALUE recv, VALUE sigval, ID *idp, VALUE *klassp)
+vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *ip,
+ VALUE recv, VALUE sigval,
+ ID *idp, VALUE *klassp)
{
ID id;
VALUE klass;
@@ -1285,22 +1264,18 @@
}
static VALUE
-vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t throw_state, VALUE throwobj)
+vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
+ rb_num_t throw_state, VALUE throwobj)
{
rb_num_t state = throw_state & 0xff;
rb_num_t flag = throw_state & 0x8000;
rb_num_t level = throw_state >> 16;
if (state != 0) {
- VALUE *pt;
+ VALUE *pt = 0;
int i;
if (flag != 0) {
- if (throw_state & 0x4000) {
- pt = (void *)1;
- }
- else {
- pt = 0;
- }
+ pt = (void *) 1;
}
else {
if (state == TAG_BREAK) {
@@ -1504,7 +1479,7 @@
}
static inline int
-check_cfunc(NODE *mn, void *func)
+check_cfunc(const NODE *mn, const void *func)
{
if (mn && nd_type(mn->nd_body) == NODE_CFUNC &&
mn->nd_body->nd_cfnc == func) {
@@ -1515,16 +1490,14 @@
}
}
-static VALUE
+static inline VALUE
opt_eq_func(VALUE recv, VALUE obj, IC ic)
{
VALUE val = Qundef;
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_EQ)) {
- long a = FIX2LONG(recv), b = FIX2LONG(obj);
-
- if (a == b) {
+ if (recv == obj) {
val = Qtrue;
}
else {
Added: MacRuby/trunk/vm_method.c
===================================================================
--- MacRuby/trunk/vm_method.c (rev 0)
+++ MacRuby/trunk/vm_method.c 2008-06-05 08:11:58 UTC (rev 247)
@@ -0,0 +1,1191 @@
+/* -*-c-*- */
+/*
+ * This file is included by vm_eval.c
+ */
+
+#define CACHE_SIZE 0x800
+#define CACHE_MASK 0x7ff
+#define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)
+
+static void rb_vm_check_redefinition_opt_method(const NODE *node);
+
+static ID __send__, object_id;
+static ID removed, singleton_removed, undefined, singleton_undefined;
+static ID eqq, each, aref, aset, match, missing;
+static ID added, singleton_added;
+
+struct cache_entry { /* method hash table. */
+ ID mid; /* method's id */
+ ID mid0; /* method's original id */
+ VALUE klass; /* receiver's class */
+ VALUE oklass; /* original's class */
+ NODE *method;
+};
+
+static struct cache_entry cache[CACHE_SIZE];
+#define ruby_running (GET_VM()->running)
+/* int ruby_running = 0; */
+
+void
+rb_clear_cache(void)
+{
+ struct cache_entry *ent, *end;
+
+ rb_vm_change_state();
+
+ if (!ruby_running)
+ return;
+ ent = cache;
+ end = ent + CACHE_SIZE;
+ while (ent < end) {
+ ent->mid = 0;
+ ent++;
+ }
+}
+
+static void
+rb_clear_cache_for_undef(VALUE klass, ID id)
+{
+ struct cache_entry *ent, *end;
+
+ rb_vm_change_state();
+
+ if (!ruby_running)
+ return;
+ ent = cache;
+ end = ent + CACHE_SIZE;
+ while (ent < end) {
+ if (ent->oklass == klass && ent->mid == id) {
+ ent->mid = 0;
+ }
+ ent++;
+ }
+}
+
+static void
+rb_clear_cache_by_id(ID id)
+{
+ struct cache_entry *ent, *end;
+
+ rb_vm_change_state();
+
+ if (!ruby_running)
+ return;
+ ent = cache;
+ end = ent + CACHE_SIZE;
+ while (ent < end) {
+ if (ent->mid == id) {
+ ent->mid = 0;
+ }
+ ent++;
+ }
+}
+
+void
+rb_clear_cache_by_class(VALUE klass)
+{
+ struct cache_entry *ent, *end;
+
+ rb_vm_change_state();
+
+ if (!ruby_running)
+ return;
+ ent = cache;
+ end = ent + CACHE_SIZE;
+ while (ent < end) {
+ if (ent->klass == klass || ent->oklass == klass) {
+ ent->mid = 0;
+ }
+ ent++;
+ }
+}
+
+#if WITH_OBJC
+void rb_objc_sync_ruby_method(VALUE, ID, NODE*, unsigned);
+#endif
+
+void
+rb_add_method_direct(VALUE klass, ID mid, NODE *node)
+{
+ rb_clear_cache_by_id(mid);
+ st_insert(RCLASS_M_TBL(klass), (st_data_t)mid, (st_data_t)node);
+}
+
+void
+rb_add_method(VALUE klass, ID mid, NODE * node, int noex)
+{
+ NODE *body;
+
+ if (NIL_P(klass) || klass == 0) {
+ klass = rb_cObject;
+ }
+ if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
+ rb_raise(rb_eSecurityError, "Insecure: can't define method");
+ }
+ if (!FL_TEST(klass, FL_SINGLETON) &&
+ node && nd_type(node) != NODE_ZSUPER &&
+ (mid == rb_intern("initialize") || mid == rb_intern("initialize_copy"))) {
+ noex = NOEX_PRIVATE | noex;
+ }
+ else if (FL_TEST(klass, FL_SINGLETON) && node
+ && nd_type(node) == NODE_CFUNC && mid == rb_intern("allocate")) {
+ rb_warn
+ ("defining %s.allocate is deprecated; use rb_define_alloc_func()",
+ rb_class2name(rb_iv_get(klass, "__attached__")));
+ mid = ID_ALLOCATOR;
+ }
+ if (OBJ_FROZEN(klass)) {
+ rb_error_frozen("class/module");
+ }
+ rb_clear_cache_by_id(mid);
+
+ /*
+ * NODE_METHOD (NEW_METHOD(body, klass, vis)):
+ * nd_body : method body // (2) // mark
+ * nd_clss : klass // (1) // mark
+ * nd_noex : visibility // (3)
+ *
+ * NODE_FBODY (NEW_FBODY(method, alias)):
+ * nd_body : method (NODE_METHOD) // (2) // mark
+ * nd_oid : original id // (1)
+ * nd_cnt : alias count // (3)
+ */
+ if (node) {
+ body = NEW_FBODY(NEW_METHOD(node, klass, NOEX_WITH_SAFE(noex)), 0);
+ }
+ else {
+ body = 0;
+ }
+
+ {
+ /* check re-definition */
+ st_data_t data;
+ NODE *old_node;
+
+ if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) {
+ old_node = (NODE *)data;
+ if (old_node) {
+ if (nd_type(old_node->nd_body->nd_body) == NODE_CFUNC) {
+ rb_vm_check_redefinition_opt_method(old_node);
+ }
+ if (RTEST(ruby_verbose) && node && old_node->nd_cnt == 0 && old_node->nd_body) {
+ rb_warning("method redefined; discarding old %s", rb_id2name(mid));
+ }
+ }
+ }
+ if (klass == rb_cObject && node && mid == idInitialize) {
+ rb_warn("redefining Object#initialize may cause infinite loop");
+ }
+
+ if (mid == object_id || mid == __send__) {
+ if (node && nd_type(node) == RUBY_VM_METHOD_NODE) {
+ rb_warn("redefining `%s' may cause serious problem",
+ rb_id2name(mid));
+ }
+ }
+ }
+
+ st_insert(RCLASS_M_TBL(klass), mid, (st_data_t) body);
+
+#if WITH_OBJC
+ if (node != NULL && noex == NOEX_PUBLIC) {
+ unsigned override = !FL_TEST(klass, FL_SINGLETON);
+ rb_objc_sync_ruby_method(klass, mid, node, override);
+ }
+#endif
+
+ if (node && mid != ID_ALLOCATOR && ruby_running) {
+ if (FL_TEST(klass, FL_SINGLETON)) {
+ rb_funcall(rb_iv_get(klass, "__attached__"), singleton_added, 1,
+ ID2SYM(mid));
+ }
+ else {
+ rb_funcall(klass, added, 1, ID2SYM(mid));
+ }
+ }
+}
+
+void
+rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE))
+{
+ Check_Type(klass, T_CLASS);
+ rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0),
+ NOEX_PRIVATE);
+}
+
+void
+rb_undef_alloc_func(VALUE klass)
+{
+ Check_Type(klass, T_CLASS);
+ rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
+}
+
+rb_alloc_func_t
+rb_get_alloc_func(VALUE klass)
+{
+ NODE *n;
+ Check_Type(klass, T_CLASS);
+ n = rb_method_node(CLASS_OF(klass), ID_ALLOCATOR);
+ if (!n) return 0;
+ if (nd_type(n) != NODE_METHOD) return 0;
+ n = n->nd_body;
+ if (nd_type(n) != NODE_CFUNC) return 0;
+ return (rb_alloc_func_t)n->nd_cfnc;
+}
+
+static NODE *
+search_method(VALUE klass, ID id, VALUE *klassp)
+{
+ st_data_t body;
+
+ if (!klass) {
+ return 0;
+ }
+
+ while (!st_lookup(RCLASS_M_TBL(klass), id, &body)) {
+ klass = RCLASS_SUPER(klass);
+ if (!klass)
+ return 0;
+ }
+
+ if (klassp) {
+ *klassp = klass;
+ }
+
+ return (NODE *)body;
+}
+
+/*
+ * search method body (NODE_METHOD)
+ * with : klass and id
+ * without : method cache
+ *
+ * if you need method node with method cache, use
+ * rb_method_node()
+ */
+NODE *
+rb_get_method_body(VALUE klass, ID id, ID *idp)
+{
+ NODE *volatile fbody, *body;
+ NODE *method;
+
+ if ((fbody = search_method(klass, id, 0)) == 0 || !fbody->nd_body) {
+ /* store empty info in cache */
+ struct cache_entry *ent;
+ ent = cache + EXPR1(klass, id);
+ ent->klass = klass;
+ ent->mid = ent->mid0 = id;
+ ent->method = 0;
+ ent->oklass = 0;
+ return 0;
+ }
+
+ method = fbody->nd_body;
+
+ if (ruby_running) {
+ /* store in cache */
+ struct cache_entry *ent;
+ ent = cache + EXPR1(klass, id);
+ ent->klass = klass;
+ ent->mid = id;
+ ent->mid0 = fbody->nd_oid;
+ ent->method = body = method;
+ ent->oklass = method->nd_clss;
+ }
+ else {
+ body = method;
+ }
+
+ if (idp) {
+ *idp = fbody->nd_oid;
+ }
+
+ return body;
+}
+
+NODE *
+rb_method_node(VALUE klass, ID id)
+{
+ struct cache_entry *ent;
+
+ ent = cache + EXPR1(klass, id);
+ if (ent->mid == id && ent->klass == klass && ent->method) {
+ return ent->method;
+ }
+
+ return rb_get_method_body(klass, id, 0);
+}
+
+static void
+remove_method(VALUE klass, ID mid)
+{
+ st_data_t data;
+ NODE *body = 0;
+
+ if (klass == rb_cObject) {
+ rb_secure(4);
+ }
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
+ rb_raise(rb_eSecurityError, "Insecure: can't remove method");
+ }
+ if (OBJ_FROZEN(klass))
+ rb_error_frozen("class/module");
+ if (mid == object_id || mid == __send__ || mid == idInitialize) {
+ rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
+ }
+ if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) {
+ body = (NODE *)data;
+ if (!body || !body->nd_body) body = 0;
+ else {
+ st_delete(RCLASS_M_TBL(klass), &mid, &data);
+ }
+ }
+ if (!body) {
+ rb_name_error(mid, "method `%s' not defined in %s",
+ rb_id2name(mid), rb_class2name(klass));
+ }
+
+ if (nd_type(body->nd_body->nd_body) == NODE_CFUNC) {
+ rb_vm_check_redefinition_opt_method(body);
+ }
+
+ rb_clear_cache_for_undef(klass, mid);
+ if (FL_TEST(klass, FL_SINGLETON)) {
+ rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1,
+ ID2SYM(mid));
+ }
+ else {
+ rb_funcall(klass, removed, 1, ID2SYM(mid));
+ }
+}
+
+void
+rb_remove_method(VALUE klass, const char *name)
+{
+ remove_method(klass, rb_intern(name));
+}
+
+/*
+ * call-seq:
+ * remove_method(symbol) => self
+ *
+ * Removes the method identified by _symbol_ from the current
+ * class. For an example, see <code>Module.undef_method</code>.
+ */
+
+static VALUE
+rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
+{
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ remove_method(mod, rb_to_id(argv[i]));
+ }
+ return mod;
+}
+
+#undef rb_disable_super
+#undef rb_enable_super
+
+void
+rb_disable_super(VALUE klass, const char *name)
+{
+ /* obsolete - no use */
+}
+
+void
+rb_enable_super(VALUE klass, const char *name)
+{
+ rb_warning("rb_enable_super() is obsolete");
+}
+
+static void
+rb_export_method(VALUE klass, ID name, ID noex)
+{
+ NODE *fbody;
+ VALUE origin;
+
+ if (klass == rb_cObject) {
+ rb_secure(4);
+ }
+ fbody = search_method(klass, name, &origin);
+ if (!fbody && TYPE(klass) == T_MODULE) {
+ fbody = search_method(rb_cObject, name, &origin);
+ }
+ if (!fbody || !fbody->nd_body) {
+ rb_print_undef(klass, name, 0);
+ }
+ if (fbody->nd_body->nd_noex != noex) {
+ if (nd_type(fbody->nd_body->nd_body) == NODE_CFUNC) {
+ rb_vm_check_redefinition_opt_method(fbody);
+ }
+ if (klass == origin) {
+ fbody->nd_body->nd_noex = noex;
+ }
+ else {
+ rb_add_method(klass, name, NEW_ZSUPER(), noex);
+ }
+ }
+}
+
+int
+rb_method_boundp(VALUE klass, ID id, int ex)
+{
+ NODE *method;
+
+ if ((method = rb_method_node(klass, id)) != 0) {
+ if (ex && (method->nd_noex & NOEX_PRIVATE)) {
+ return Qfalse;
+ }
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+void
+rb_attr(VALUE klass, ID id, int read, int write, int ex)
+{
+ const char *name;
+ ID attriv;
+ int noex;
+
+ if (!ex) {
+ noex = NOEX_PUBLIC;
+ }
+ else {
+ if (SCOPE_TEST(NOEX_PRIVATE)) {
+ noex = NOEX_PRIVATE;
+ rb_warning((SCOPE_CHECK(NOEX_MODFUNC)) ?
+ "attribute accessor as module_function" :
+ "private attribute?");
+ }
+ else if (SCOPE_TEST(NOEX_PROTECTED)) {
+ noex = NOEX_PROTECTED;
+ }
+ else {
+ noex = NOEX_PUBLIC;
+ }
+ }
+
+ if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
+ rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
+ }
+ name = rb_id2name(id);
+ if (!name) {
+ rb_raise(rb_eArgError, "argument needs to be symbol or string");
+ }
+ attriv = rb_intern_str(rb_sprintf("@%s", name));
+ if (read) {
+ rb_add_method(klass, id, NEW_IVAR(attriv), noex);
+ }
+ if (write) {
+ rb_add_method(klass, rb_id_attrset(id), NEW_ATTRSET(attriv), noex);
+ }
+}
+
+void
+rb_undef(VALUE klass, ID id)
+{
+ VALUE origin;
+ NODE *body;
+
+ if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) {
+ rb_secure(4);
+ }
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
+ rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
+ rb_id2name(id));
+ }
+ rb_frozen_class_p(klass);
+ if (id == object_id || id == __send__ || id == idInitialize) {
+ rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
+ }
+#if WITH_OBJC
+ /* TODO: we should only warn regarding important NSObject methods that
+ are necessary by the GC to call finalizers. */
+ if (class_respondsToSelector(RCLASS_OCID(rb_cBasicObject),
+ sel_registerName(rb_id2name(id)))) {
+ rb_warn("undefining `NSObject#%s' may cause serious problem",
+ rb_id2name(id));
+ }
+#endif
+ body = search_method(klass, id, &origin);
+ if (!body || !body->nd_body) {
+ const char *s0 = " class";
+ VALUE c = klass;
+
+ if (FL_TEST(c, FL_SINGLETON)) {
+ VALUE obj = rb_iv_get(klass, "__attached__");
+
+ switch (TYPE(obj)) {
+ case T_MODULE:
+ case T_CLASS:
+ c = obj;
+ s0 = "";
+ }
+ }
+ else if (TYPE(c) == T_MODULE) {
+ s0 = " module";
+ }
+#if WITH_OBJC
+ if (!class_respondsToSelector(RCLASS(klass)->ocklass,
+ sel_registerName(rb_id2name(id))))
+#endif
+ rb_name_error(id, "undefined method `%s' for%s `%s'",
+ rb_id2name(id), s0, rb_class2name(c));
+ }
+
+ rb_add_method(klass, id, 0, NOEX_PUBLIC);
+
+#if WITH_OBJC
+ {
+ Method method;
+ method = class_getInstanceMethod(RCLASS(klass)->ocklass,
+ sel_registerName(rb_id2name(id)));
+ if (method != NULL)
+ method_setImplementation(method, NULL);
+ }
+#endif
+
+ if (FL_TEST(klass, FL_SINGLETON)) {
+ rb_funcall(rb_iv_get(klass, "__attached__"),
+ singleton_undefined, 1, ID2SYM(id));
+ }
+ else {
+ rb_funcall(klass, undefined, 1, ID2SYM(id));
+ }
+}
+
+/*
+ * call-seq:
+ * undef_method(symbol) => self
+ *
+ * Prevents the current class from responding to calls to the named
+ * method. Contrast this with <code>remove_method</code>, which deletes
+ * the method from the particular class; Ruby will still search
+ * superclasses and mixed-in modules for a possible receiver.
+ *
+ * class Parent
+ * def hello
+ * puts "In parent"
+ * end
+ * end
+ * class Child < Parent
+ * def hello
+ * puts "In child"
+ * end
+ * end
+ *
+ *
+ * c = Child.new
+ * c.hello
+ *
+ *
+ * class Child
+ * remove_method :hello # remove from child, still in parent
+ * end
+ * c.hello
+ *
+ *
+ * class Child
+ * undef_method :hello # prevent any calls to 'hello'
+ * end
+ * c.hello
+ *
+ * <em>produces:</em>
+ *
+ * In child
+ * In parent
+ * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
+ */
+
+static VALUE
+rb_mod_undef_method(int argc, VALUE *argv, VALUE mod)
+{
+ int i;
+ for (i = 0; i < argc; i++) {
+ rb_undef(mod, rb_to_id(argv[i]));
+ }
+ return mod;
+}
+
+/*
+ * call-seq:
+ * mod.method_defined?(symbol) => true or false
+ *
+ * Returns +true+ if the named method is defined by
+ * _mod_ (or its included modules and, if _mod_ is a class,
+ * its ancestors). Public and protected methods are matched.
+ *
+ * module A
+ * def method1() end
+ * end
+ * class B
+ * def method2() end
+ * end
+ * class C < B
+ * include A
+ * def method3() end
+ * end
+ *
+ * A.method_defined? :method1 #=> true
+ * C.method_defined? "method1" #=> true
+ * C.method_defined? "method2" #=> true
+ * C.method_defined? "method3" #=> true
+ * C.method_defined? "method4" #=> false
+ */
+
+static VALUE
+rb_mod_method_defined(VALUE mod, VALUE mid)
+{
+ return rb_method_boundp(mod, rb_to_id(mid), 1);
+}
+
+#define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
+
+/*
+ * call-seq:
+ * mod.public_method_defined?(symbol) => true or false
+ *
+ * Returns +true+ if the named public method is defined by
+ * _mod_ (or its included modules and, if _mod_ is a class,
+ * its ancestors).
+ *
+ * module A
+ * def method1() end
+ * end
+ * class B
+ * protected
+ * def method2() end
+ * end
+ * class C < B
+ * include A
+ * def method3() end
+ * end
+ *
+ * A.method_defined? :method1 #=> true
+ * C.public_method_defined? "method1" #=> true
+ * C.public_method_defined? "method2" #=> false
+ * C.method_defined? "method2" #=> true
+ */
+
+static VALUE
+rb_mod_public_method_defined(VALUE mod, VALUE mid)
+{
+ ID id = rb_to_id(mid);
+ NODE *method;
+
+ method = rb_method_node(mod, id);
+ if (method) {
+ if (VISI_CHECK(method->nd_noex, NOEX_PUBLIC))
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+/*
+ * call-seq:
+ * mod.private_method_defined?(symbol) => true or false
+ *
+ * Returns +true+ if the named private method is defined by
+ * _ mod_ (or its included modules and, if _mod_ is a class,
+ * its ancestors).
+ *
+ * module A
+ * def method1() end
+ * end
+ * class B
+ * private
+ * def method2() end
+ * end
+ * class C < B
+ * include A
+ * def method3() end
+ * end
+ *
+ * A.method_defined? :method1 #=> true
+ * C.private_method_defined? "method1" #=> false
+ * C.private_method_defined? "method2" #=> true
+ * C.method_defined? "method2" #=> false
+ */
+
+static VALUE
+rb_mod_private_method_defined(VALUE mod, VALUE mid)
+{
+ ID id = rb_to_id(mid);
+ NODE *method;
+
+ method = rb_method_node(mod, id);
+ if (method) {
+ if (VISI_CHECK(method->nd_noex, NOEX_PRIVATE))
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+/*
+ * call-seq:
+ * mod.protected_method_defined?(symbol) => true or false
+ *
+ * Returns +true+ if the named protected method is defined
+ * by _mod_ (or its included modules and, if _mod_ is a
+ * class, its ancestors).
+ *
+ * module A
+ * def method1() end
+ * end
+ * class B
+ * protected
+ * def method2() end
+ * end
+ * class C < B
+ * include A
+ * def method3() end
+ * end
+ *
+ * A.method_defined? :method1 #=> true
+ * C.protected_method_defined? "method1" #=> false
+ * C.protected_method_defined? "method2" #=> true
+ * C.method_defined? "method2" #=> true
+ */
+
+static VALUE
+rb_mod_protected_method_defined(VALUE mod, VALUE mid)
+{
+ ID id = rb_to_id(mid);
+ NODE *method;
+
+ method = rb_method_node(mod, id);
+ if (method) {
+ if (VISI_CHECK(method->nd_noex, NOEX_PROTECTED))
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+void
+rb_alias(VALUE klass, ID name, ID def)
+{
+ NODE *orig_fbody, *node;
+ VALUE singleton = 0;
+ st_data_t data;
+
+ rb_frozen_class_p(klass);
+ if (klass == rb_cObject) {
+ rb_secure(4);
+ }
+ orig_fbody = search_method(klass, def, 0);
+ if (!orig_fbody || !orig_fbody->nd_body) {
+ if (TYPE(klass) == T_MODULE) {
+ orig_fbody = search_method(rb_cObject, def, 0);
+ }
+ }
+ if (!orig_fbody || !orig_fbody->nd_body) {
+ rb_print_undef(klass, def, 0);
+ }
+ if (FL_TEST(klass, FL_SINGLETON)) {
+ singleton = rb_iv_get(klass, "__attached__");
+ }
+
+ orig_fbody->nd_cnt++;
+
+ if (st_lookup(RCLASS_M_TBL(klass), name, &data)) {
+ node = (NODE *)data;
+ if (node) {
+ if (RTEST(ruby_verbose) && node->nd_cnt == 0 && node->nd_body) {
+ rb_warning("discarding old %s", rb_id2name(name));
+ }
+ if (nd_type(node->nd_body->nd_body) == NODE_CFUNC) {
+ rb_vm_check_redefinition_opt_method(node);
+ }
+ }
+ }
+
+ st_insert(RCLASS_M_TBL(klass), name,
+ (st_data_t) NEW_FBODY(
+ NEW_METHOD(orig_fbody->nd_body->nd_body,
+ orig_fbody->nd_body->nd_clss,
+ NOEX_WITH_SAFE(orig_fbody->nd_body->nd_noex)), def));
+
+#if WITH_OBJC
+ if (orig_fbody->nd_body->nd_noex == NOEX_PUBLIC)
+ rb_objc_sync_ruby_method(klass, name, orig_fbody->nd_body->nd_body, 0);
+#endif
+
+ rb_clear_cache_by_id(name);
+
+ if (!ruby_running) return;
+
+ if (singleton) {
+ rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
+ }
+ else {
+ rb_funcall(klass, added, 1, ID2SYM(name));
+ }
+}
+
+/*
+ * call-seq:
+ * alias_method(new_name, old_name) => self
+ *
+ * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
+ * be used to retain access to methods that are overridden.
+ *
+ * module Mod
+ * alias_method :orig_exit, :exit
+ * def exit(code=0)
+ * puts "Exiting with code #{code}"
+ * orig_exit(code)
+ * end
+ * end
+ * include Mod
+ * exit(99)
+ *
+ * <em>produces:</em>
+ *
+ * Exiting with code 99
+ */
+
+static VALUE
+rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
+{
+ rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
+ return mod;
+}
+
+static void
+secure_visibility(VALUE self)
+{
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
+ rb_raise(rb_eSecurityError,
+ "Insecure: can't change method visibility");
+ }
+}
+
+static void
+set_method_visibility(VALUE self, int argc, VALUE *argv, ID ex)
+{
+ int i;
+ secure_visibility(self);
+ for (i = 0; i < argc; i++) {
+ rb_export_method(self, rb_to_id(argv[i]), ex);
+ }
+ rb_clear_cache_by_class(self);
+}
+
+/*
+ * call-seq:
+ * public => self
+ * public(symbol, ...) => self
+ *
+ * With no arguments, sets the default visibility for subsequently
+ * defined methods to public. With arguments, sets the named methods to
+ * have public visibility.
+ */
+
+static VALUE
+rb_mod_public(int argc, VALUE *argv, VALUE module)
+{
+ secure_visibility(module);
+ if (argc == 0) {
+ SCOPE_SET(NOEX_PUBLIC);
+ }
+ else {
+ set_method_visibility(module, argc, argv, NOEX_PUBLIC);
+ }
+ return module;
+}
+
+/*
+ * call-seq:
+ * protected => self
+ * protected(symbol, ...) => self
+ *
+ * With no arguments, sets the default visibility for subsequently
+ * defined methods to protected. With arguments, sets the named methods
+ * to have protected visibility.
+ */
+
+static VALUE
+rb_mod_protected(int argc, VALUE *argv, VALUE module)
+{
+ secure_visibility(module);
+ if (argc == 0) {
+ SCOPE_SET(NOEX_PROTECTED);
+ }
+ else {
+ set_method_visibility(module, argc, argv, NOEX_PROTECTED);
+ }
+ return module;
+}
+
+/*
+ * call-seq:
+ * private => self
+ * private(symbol, ...) => self
+ *
+ * With no arguments, sets the default visibility for subsequently
+ * defined methods to private. With arguments, sets the named methods
+ * to have private visibility.
+ *
+ * module Mod
+ * def a() end
+ * def b() end
+ * private
+ * def c() end
+ * private :a
+ * end
+ * Mod.private_instance_methods #=> [:a, :c]
+ */
+
+static VALUE
+rb_mod_private(int argc, VALUE *argv, VALUE module)
+{
+ secure_visibility(module);
+ if (argc == 0) {
+ SCOPE_SET(NOEX_PRIVATE);
+ }
+ else {
+ set_method_visibility(module, argc, argv, NOEX_PRIVATE);
+ }
+ return module;
+}
+
+/*
+ * call-seq:
+ * mod.public_class_method(symbol, ...) => mod
+ *
+ * Makes a list of existing class methods public.
+ */
+
+static VALUE
+rb_mod_public_method(int argc, VALUE *argv, VALUE obj)
+{
+ set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PUBLIC);
+ return obj;
+}
+
+/*
+ * call-seq:
+ * mod.private_class_method(symbol, ...) => mod
+ *
+ * Makes existing class methods private. Often used to hide the default
+ * constructor <code>new</code>.
+ *
+ * class SimpleSingleton # Not thread safe
+ * private_class_method :new
+ * def SimpleSingleton.create(*args, &block)
+ * @me = new(*args, &block) if ! @me
+ * @me
+ * end
+ * end
+ */
+
+static VALUE
+rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
+{
+ set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PRIVATE);
+ return obj;
+}
+
+/*
+ * call-seq:
+ * public
+ * public(symbol, ...)
+ *
+ * With no arguments, sets the default visibility for subsequently
+ * defined methods to public. With arguments, sets the named methods to
+ * have public visibility.
+ */
+
+static VALUE
+top_public(int argc, VALUE *argv)
+{
+ return rb_mod_public(argc, argv, rb_cObject);
+}
+
+static VALUE
+top_private(int argc, VALUE *argv)
+{
+ return rb_mod_private(argc, argv, rb_cObject);
+}
+
+/*
+ * call-seq:
+ * module_function(symbol, ...) => self
+ *
+ * Creates module functions for the named methods. These functions may
+ * be called with the module as a receiver, and also become available
+ * as instance methods to classes that mix in the module. Module
+ * functions are copies of the original, and so may be changed
+ * independently. The instance-method versions are made private. If
+ * used with no arguments, subsequently defined methods become module
+ * functions.
+ *
+ * module Mod
+ * def one
+ * "This is one"
+ * end
+ * module_function :one
+ * end
+ * class Cls
+ * include Mod
+ * def callOne
+ * one
+ * end
+ * end
+ * Mod.one #=> "This is one"
+ * c = Cls.new
+ * c.callOne #=> "This is one"
+ * module Mod
+ * def one
+ * "This is the new one"
+ * end
+ * end
+ * Mod.one #=> "This is one"
+ * c.callOne #=> "This is the new one"
+ */
+
+static VALUE
+rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
+{
+ int i;
+ ID id;
+ NODE *fbody;
+
+ if (TYPE(module) != T_MODULE) {
+ rb_raise(rb_eTypeError, "module_function must be called for modules");
+ }
+
+ secure_visibility(module);
+ if (argc == 0) {
+ SCOPE_SET(NOEX_MODFUNC);
+ return module;
+ }
+
+ set_method_visibility(module, argc, argv, NOEX_PRIVATE);
+
+ for (i = 0; i < argc; i++) {
+ VALUE m = module;
+
+ id = rb_to_id(argv[i]);
+ for (;;) {
+ fbody = search_method(m, id, &m);
+ if (fbody == 0) {
+ fbody = search_method(rb_cObject, id, &m);
+ }
+ if (fbody == 0 || fbody->nd_body == 0) {
+ rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
+ }
+ if (nd_type(fbody->nd_body->nd_body) != NODE_ZSUPER) {
+ break; /* normal case: need not to follow 'super' link */
+ }
+ m = RCLASS_SUPER(m);
+ if (!m)
+ break;
+ }
+ rb_add_method(rb_singleton_class(module), id, fbody->nd_body->nd_body,
+ NOEX_PUBLIC);
+ }
+ return module;
+}
+
+/*
+ * call-seq:
+ * obj.respond_to?(symbol, include_private=false) => true or false
+ *
+ * Returns +true+> if _obj_ responds to the given
+ * method. Private methods are included in the search only if the
+ * optional second parameter evaluates to +true+.
+ */
+
+static NODE *basic_respond_to = 0;
+
+int
+rb_obj_respond_to(VALUE obj, ID id, int priv)
+{
+ VALUE klass = CLASS_OF(obj);
+
+ if (rb_method_node(klass, idRespond_to) == basic_respond_to) {
+ return rb_method_boundp(klass, id, !priv);
+ }
+ else {
+ VALUE args[2];
+ int n = 0;
+ args[n++] = ID2SYM(id);
+ if (priv)
+ args[n++] = Qtrue;
+ return RTEST(rb_funcall2(obj, idRespond_to, n, args));
+ }
+}
+
+int
+rb_respond_to(VALUE obj, ID id)
+{
+ return rb_obj_respond_to(obj, id, Qfalse);
+}
+
+/*
+ * call-seq:
+ * obj.respond_to?(symbol, include_private=false) => true or false
+ *
+ * Returns +true+> if _obj_ responds to the given
+ * method. Private methods are included in the search only if the
+ * optional second parameter evaluates to +true+.
+ */
+
+static VALUE
+obj_respond_to(int argc, VALUE *argv, VALUE obj)
+{
+ VALUE mid, priv;
+ ID id;
+
+ rb_scan_args(argc, argv, "11", &mid, &priv);
+ id = rb_to_id(mid);
+ if (rb_method_boundp(CLASS_OF(obj), id, !RTEST(priv))) {
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+void
+Init_eval_method(void)
+{
+ rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
+ basic_respond_to = rb_method_node(rb_cObject, idRespond_to);
+ rb_register_mark_object((VALUE)basic_respond_to);
+
+ rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
+ rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
+ rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
+ rb_define_private_method(rb_cModule, "public", rb_mod_public, -1);
+ rb_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
+ rb_define_private_method(rb_cModule, "private", rb_mod_private, -1);
+ rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
+
+ rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
+ rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
+ rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
+ rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
+ rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
+ rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
+
+ rb_define_singleton_method(rb_vm_top_self(), "public", top_public, -1);
+ rb_define_singleton_method(rb_vm_top_self(), "private", top_private, -1);
+
+ object_id = rb_intern("object_id");
+ __send__ = rb_intern("__send__");
+ eqq = rb_intern("===");
+ each = rb_intern("each");
+ aref = rb_intern("[]");
+ aset = rb_intern("[]=");
+ match = rb_intern("=~");
+ missing = rb_intern("method_missing");
+ added = rb_intern("method_added");
+ singleton_added = rb_intern("singleton_method_added");
+ removed = rb_intern("method_removed");
+ singleton_removed = rb_intern("singleton_method_removed");
+ undefined = rb_intern("method_undefined");
+ singleton_undefined = rb_intern("singleton_method_undefined");
+}
+
Property changes on: MacRuby/trunk/vm_method.c
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: MacRuby/trunk/vm_opts.h
===================================================================
--- MacRuby/trunk/vm_opts.h 2008-06-05 07:53:56 UTC (rev 246)
+++ MacRuby/trunk/vm_opts.h 2008-06-05 08:11:58 UTC (rev 247)
@@ -3,7 +3,7 @@
vm_opts.h - VM optimize option
- $Author: nobu $
+ $Author: ko1 $
Copyright (C) 2004-2007 Koichi Sasada
@@ -31,6 +31,7 @@
/* C compiler depend */
#define OPT_DIRECT_THREADED_CODE 1
+#define OPT_TOKEN_THREADED_CODE 0
#define OPT_CALL_THREADED_CODE 0
/* VM running option */
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080605/1cfa79c9/attachment-0001.htm
More information about the macruby-changes
mailing list