ruby-changes:15143
From: nobu <ko1@a...>
Date: Tue, 23 Mar 2010 16:39:32 +0900 (JST)
Subject: [ruby-changes:15143] Ruby:r27021 (mvm): * merged from trunk r26967:27020.
nobu 2010-03-23 16:37:09 +0900 (Tue, 23 Mar 2010) New Revision: 27021 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=27021 Log: * merged from trunk r26967:27020. Added files: branches/mvm/ext/socket/.document Modified files: branches/mvm/.merged-trunk-revision branches/mvm/ChangeLog branches/mvm/Makefile.in branches/mvm/NEWS branches/mvm/array.c branches/mvm/configure.in branches/mvm/enc/trans/big5.trans branches/mvm/enc/trans/chinese.trans branches/mvm/enc/trans/emoji.trans branches/mvm/enc/trans/emoji_iso2022_kddi.trans branches/mvm/enc/trans/emoji_sjis_docomo.trans branches/mvm/enc/trans/emoji_sjis_kddi.trans branches/mvm/enc/trans/emoji_sjis_softbank.trans branches/mvm/enc/trans/escape.trans branches/mvm/enum.c branches/mvm/ext/.document branches/mvm/ext/bigdecimal/bigdecimal.c branches/mvm/ext/dl/lib/dl/pack.rb branches/mvm/ext/socket/ancdata.c branches/mvm/ext/socket/basicsocket.c branches/mvm/ext/socket/constants.c branches/mvm/ext/socket/init.c branches/mvm/ext/socket/ipsocket.c branches/mvm/ext/socket/lib/socket.rb branches/mvm/ext/socket/mkconstants.rb branches/mvm/ext/socket/option.c branches/mvm/ext/socket/raddrinfo.c branches/mvm/ext/socket/rubysocket.h branches/mvm/ext/socket/socket.c branches/mvm/ext/socket/sockssocket.c branches/mvm/ext/socket/tcpserver.c branches/mvm/ext/socket/tcpsocket.c branches/mvm/ext/socket/udpsocket.c branches/mvm/ext/socket/unixserver.c branches/mvm/ext/socket/unixsocket.c branches/mvm/gc.c branches/mvm/io.c branches/mvm/lib/cgi/core.rb branches/mvm/lib/cgi/html.rb branches/mvm/lib/csv.rb branches/mvm/lib/date.rb branches/mvm/lib/ipaddr.rb branches/mvm/lib/irb/notifier.rb branches/mvm/lib/irb/output-method.rb branches/mvm/lib/irb/xmp.rb branches/mvm/lib/net/https.rb branches/mvm/lib/net/smtp.rb branches/mvm/lib/optparse.rb branches/mvm/lib/prime.rb branches/mvm/lib/rake/packagetask.rb branches/mvm/lib/resolv-replace.rb branches/mvm/lib/rexml/entity.rb branches/mvm/lib/rubygems/commands/dependency_command.rb branches/mvm/lib/rubygems/spec_fetcher.rb branches/mvm/lib/rubygems.rb branches/mvm/lib/shell/command-processor.rb branches/mvm/lib/shell/process-controller.rb branches/mvm/lib/thwait.rb branches/mvm/lib/uri/common.rb branches/mvm/lib/xmlrpc/server.rb branches/mvm/method.h branches/mvm/object.c branches/mvm/proc.c branches/mvm/ruby.c branches/mvm/string.c branches/mvm/symbian/setup branches/mvm/test/dl/test_cfunc.rb branches/mvm/test/dl/test_dl2.rb branches/mvm/test/dl/test_handle.rb branches/mvm/test/ruby/test_array.rb branches/mvm/test/ruby/test_io.rb branches/mvm/test/ruby/test_proc.rb branches/mvm/test/ruby/test_string.rb branches/mvm/test/uri/test_common.rb branches/mvm/test/yaml/test_hash.rb branches/mvm/tool/transcode-tblgen.rb branches/mvm/version.c branches/mvm/version.h branches/mvm/vm_eval.c branches/mvm/vm_insnhelper.c branches/mvm/vm_method.c Index: mvm/array.c =================================================================== --- mvm/array.c (revision 27020) +++ mvm/array.c (revision 27021) @@ -3363,6 +3363,8 @@ long i, j; rb_ary_modify_check(ary); + if (RARRAY_LEN(ary) <= 1) + return Qnil; if (rb_block_given_p()) { hash = ary_make_hash_by(ary); if (RARRAY_LEN(ary) == (i = RHASH_SIZE(hash))) { @@ -3408,6 +3410,8 @@ VALUE hash, uniq, v; long i; + if (RARRAY_LEN(ary) <= 1) + return rb_ary_dup(ary); if (rb_block_given_p()) { hash = ary_make_hash_by(ary); uniq = ary_new(rb_obj_class(ary), RHASH_SIZE(hash)); Index: mvm/method.h =================================================================== --- mvm/method.h (revision 27020) +++ mvm/method.h (revision 27021) @@ -49,6 +49,11 @@ int argc; } rb_method_cfunc_t; +typedef struct rb_method_attr_struct { + ID id; + VALUE location; +} rb_method_attr_t; + typedef struct rb_iseq_struct rb_iseq_t; typedef struct rb_method_definition_struct { @@ -57,7 +62,7 @@ union { rb_iseq_t *iseq; /* should be mark */ rb_method_cfunc_t cfunc; - ID attr_id; + rb_method_attr_t attr; VALUE proc; /* should be mark */ enum method_optimized_type { OPTIMIZED_METHOD_TYPE_SEND, Index: mvm/configure.in =================================================================== --- mvm/configure.in (revision 27020) +++ mvm/configure.in (revision 27021) @@ -337,7 +337,12 @@ AC_SUBST(RM, ['rm -f']) AC_SUBST(CP, ['cp']) -AC_SUBST(RMDIRS, ['$(top_srcdir)/tool/rmdirs']) +RMDIRS='$(top_srcdir)/tool/rmdirs' +mkdir "rmdirs_$$_test" "rmdirs_$$_test/a" +rmdir -p "rmdirs_$$_test/a" 2>/dev/null && +{ test -d "rmdirs_$$_test" || RMDIRS='rmdir -p'; } +rmdir "rmdirs_$$_test/a" "rmdirs_$$_test" 2>/dev/null +AC_SUBST(RMDIRS) AC_SUBST(RMALL, ['rm -fr']) AC_MSG_CHECKING([for cd using phisical directory]) @@ -2413,10 +2418,12 @@ if test "${LOAD_RELATIVE+set}"; then AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) + RUBY_EXEC_PREFIX="" RUBY_LIB_PREFIX="`eval echo "$RUBY_LIB_PREFIX" | sed 's|^NONE/|/|;s|^'"$prefix"'/|/|'`" RUBY_SITE_LIB_PATH="`eval echo "$SITE_DIR" | sed 's|^NONE/|/|;s|^'"$prefix"'/|/|'`" RUBY_VENDOR_LIB_PATH="`eval echo "$VENDOR_DIR" | sed 's|^NONE/|/|;s|^'"$prefix"'/|/|'`" else + RUBY_EXEC_PREFIX="`eval echo \\"$exec_prefix/\\" | sed 's|^NONE/|'"$prefix"'/|;s|/$||'`" RUBY_LIB_PREFIX="`eval echo \\"$RUBY_LIB_PREFIX\\" | sed 's|^NONE/|'"$prefix"'/|'`" RUBY_SITE_LIB_PATH="`eval echo \\"$SITE_DIR\\" | sed 's|^NONE/|'"$prefix"'/|'`" RUBY_VENDOR_LIB_PATH="`eval echo \\"$VENDOR_DIR\\" | sed 's|^NONE/|'"$prefix"'/|'`" @@ -2437,13 +2444,22 @@ [ RUBY_VENDOR_LIB_PATH="\"${RUBY_VENDOR_LIB_PATH}\"" ]) +pat=`echo "$RUBY_EXEC_PREFIX/" | tr -c '\012' .`'\(.*\)' +AS_CASE(["$RUBY_LIB_PREFIX"], + ["$RUBY_EXEC_PREFIX/"*], [ + RUBY_LIB_PREFIX='RUBY_EXEC_PREFIX"/'"`expr \"$RUBY_LIB_PREFIX\" : \"$pat\"`"'"' + ], + [ + RUBY_LIB_PREFIX="\"${RUBY_LIB_PREFIX}\"" + ]) if test ${RUBY_LIB_VERSION_STYLE+set}; then AC_DEFINE_UNQUOTED(RUBY_LIB_VERSION_STYLE, $RUBY_LIB_VERSION_STYLE) else AC_DEFINE_UNQUOTED(RUBY_LIB_VERSION, [$RUBY_LIB_VERSION]) fi -AC_DEFINE_UNQUOTED(RUBY_LIB_PREFIX, "${RUBY_LIB_PREFIX}") +AC_DEFINE_UNQUOTED(RUBY_EXEC_PREFIX, "${RUBY_EXEC_PREFIX}") +AC_DEFINE_UNQUOTED(RUBY_LIB_PREFIX, ${RUBY_LIB_PREFIX}) AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, ${RUBY_SITE_LIB_PATH}) AC_DEFINE_UNQUOTED(RUBY_VENDOR_LIB, ${RUBY_VENDOR_LIB_PATH}) Index: mvm/ChangeLog =================================================================== --- mvm/ChangeLog (revision 27020) +++ mvm/ChangeLog (revision 27021) @@ -1,3 +1,158 @@ +Tue Mar 23 01:13:59 2010 Tanaka Akira <akr@f...> + + * ext/socket: use rsock_ prefix for internal initialization functions. + +Mon Mar 22 20:32:22 2010 wanabe <s.wanabe@g...> + + * proc.c (rb_method_location): return attr's location if it is setup. + [Feature #2084] + + * NEWS: follow above. + + * vm_method.c (rb_add_method): save attr's location. + + * gc.c (mark_method_entry): mark attr's location. + + * method.h (rb_method_definition_t): add member to save attr's location. + + * vm_eval.c (vm_call0): follow above. + + * vm_insnhelper.c (vm_call_method): ditto. + + * vm_method.c (rb_method_definition_eq): ditto. + +Mon Mar 22 19:31:06 2010 Tadayoshi Funaba <tadf@d...> + + * lib/date.rb (Date#>>): fixed. [ruby-core:28011] + +Mon Mar 22 18:01:13 2010 Nobuyoshi Nakada <nobu@r...> + + * configure.in (RMDIRS): use rmdir -p if possible. + + * Makefile.in ({dist,real}clean-ext): fix for removing ext + directories. + +Mon Mar 22 09:06:10 2010 Tanaka Akira <akr@f...> + + * ext/socket/.document: extracted from ext/.document. + +Mon Mar 22 00:50:33 2010 Tanaka Akira <akr@f...> + + * ext/socket/rubysocket.h (rsock_revlookup_flag): declared. + +Mon Mar 22 00:01:24 2010 Alexander Zavorine <alexandre.zavorine@n...> + + * symbian/setup (config.h): RUBY_EXEC_PREFIX defined. + +Sun Mar 21 00:46:29 2010 NARUSE, Yui <naruse@r...> + + * lib/uri/common.rb (URI.encode_www_form_component): + convert strings of HTML5 ASCII incompatible encoding + to UTF-8. + + * lib/uri/common.rb (URI.encode_www_form_component): + "\x83\x41" of Shift_JIS should be encoded as "%83A". + This follows real implementations. + + * lib/uri/common.rb (URI.decode_www_form_component): + use given encoding for force_encoding. [ruby-dev:40721] + +Sun Mar 21 21:09:17 2010 Tanaka Akira <akr@f...> + + * lib/resolv-replace.rb: specify super class for rdoc. + + * lib/ipaddr.rb: ditto. + +Sun Mar 21 19:52:27 2010 Nobuyoshi Nakada <nobu@r...> + + * io.c (rb_io_initialize): add autoclose argument to control close + at finalization. [ruby-core:26222] + + * io.c (rb_io_autoclose_p, rb_io_set_autoclose): new methods. + +Sun Mar 21 19:50:04 2010 Tanaka Akira <akr@f...> + + * ext/socket: make sources rdoc friendly. + +Sun Mar 21 17:57:49 2010 Nobuyoshi Nakada <nobu@r...> + + * io.c (IO_RBUF_CAPA_FOR): use large buffer as cbuf if readconv is + needed for performance improvement. based on a patch by Roger Pack + in [ruby-core:28163]. [ruby-core:28162] + +Sun Mar 21 17:14:49 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: reuse hash object. + +Sun Mar 21 12:32:39 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (transcode_compile_tree): make + valid_encoding mandatory unless from_encoding is registered in + ValidEncoding. + (transcode_tbl_only): ditto. + (transcode_tblgen): ditto. + (ValidEncoding): new function. + + * enc/trans/escape.trans: specify valid_encoding. + + * enc/trans/emoji_sjis_docomo.trans: ditto. + + * enc/trans/emoji.trans: ditto. + + * enc/trans/emoji_iso2022_kddi.trans: ditto. + + * enc/trans/big5.trans: ditto. + + * enc/trans/emoji_sjis_softbank.trans: ditto. + + * enc/trans/emoji_sjis_kddi.trans: ditto. + + * enc/trans/chinese.trans: use ValidEncoding() instead of + ValidEncoding[]. + +Sun Mar 21 09:43:01 2010 Nobuyoshi Nakada <nobu@r...> + + * io.c (IO_[CRW]BUF_CAPA_MIN): replaced magic numbers. + +Sun Mar 21 09:22:10 2010 Tanaka Akira <akr@f...> + + * object.c (rb_obj_hash): use LONG2FIX to avoid Bignum allocation. + +Sat Mar 20 22:51:46 2010 Tanaka Akira <akr@f...> + + * string.c (rb_str_sum): use UCHAR_MAX. + +Sat Mar 20 19:16:42 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (ActionMap.unambiguous_action): use + Array#delete. + (ActionMap.merge2): defined. + (ActionMap::PostMemo): removed. + (transcode_compile_tree): use ActionMap.merge2. + +Sat Mar 20 13:26:09 2010 Tanaka Akira <akr@f...> + + * array.c (rb_ary_uniq_bang): the array is already unique if the + length is zero or one. + (rb_ary_uniq): ditto. + +Sat Mar 20 12:30:54 2010 Nobuyoshi Nakada <nobu@r...> + + * lib: fixed typo. a patch by Sho Hashimoto in [ruby-dev:40716]. + +Sat Mar 20 11:32:18 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (each_firstbyte_range): tuned for less + method calls. + +Sat Mar 20 00:59:50 2010 wanabe <s.wanabe@g...> + + * ext/dl/lib/dl/pack.rb (DL#pack): allow LLP64. + +Fri Mar 19 05:26:31 2010 Tanaka Akira <akr@f...> + + * string.c (rb_str_sum): don't call method for each byte. + Thu Mar 18 21:24:21 2010 Nobuyoshi Nakada <nobu@r...> * Makefile.in (miniruby): link $(NORMALMAINOBJ). @@ -2,2 +157,24 @@ +Thu Mar 18 21:24:21 2010 Nobuyoshi Nakada <nobu@r...> + + * Makefile.in (miniruby): link $(NORMALMAINOBJ). + +Thu Mar 18 19:52:27 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: scan singleton mappings sequentially. + +Thu Mar 18 06:28:32 2010 Nobuyoshi Nakada <nobu@r...> + + * configure.in (RUBY_EXEC_PREFIX): added to config.h. + + * ruby.c (ruby_init_loadpath_safe): TMP_RUBY_PREFIX should be + exec_prefix, not rubylibprefix. [ruby-core:28718] + + * version.c (RUBY_LIB_PREFIX): fallback to RUBY_EXEC_PREFIX. + +Thu Mar 18 05:58:27 2010 Nobuyoshi Nakada <nobu@r...> + + * ext/bigdecimal/bigdecimal.c (BigDecimal_{to_i,mod,divmod,div2}): + removed unused variables. + Thu Mar 18 04:40:56 2010 Nobuyoshi Nakada <nobu@r...> @@ -17,22 +194,22 @@ Thu Mar 18 00:00:58 2010 NARUSE, Yui <naruse@r...> - * lib/uri/common.rb (URI#{en,de}code_www_form_component): - renamed from URI#{en,de}code_www_component. [ruby-dev:40672] + * lib/uri/common.rb (URI.{en,de}code_www_form_component): + renamed from URI.{en,de}code_www_component. [ruby-dev:40672] - * lib/uri/common.rb (URI#encode_www_form_component): %-encoded + * lib/uri/common.rb (URI.encode_www_form_component): %-encoded element should have always two hex. - * lib/uri/common.rb (URI#encode_www_form_component): + * lib/uri/common.rb (URI.encode_www_form_component): better treatment for ASCII incompatible encodings and encodings whose lead byte may use 7bit. - * lib/uri/common.rb (URI#decode_www_form_component): add %20. + * lib/uri/common.rb (URI.decode_www_form_component): add %20. - * lib/uri/common.rb (URI#decode_www_form_component): add + * lib/uri/common.rb (URI.decode_www_form_component): add result's encoding as 2nd argument. - * lib/uri/common.rb (URI#decode_www_form): added. + * lib/uri/common.rb (URI.decode_www_form): added. Wed Mar 17 16:25:53 2010 Nobuyoshi Nakada <nobu@r...> Index: mvm/enc/trans/escape.trans =================================================================== --- mvm/enc/trans/escape.trans (revision 27020) +++ mvm/enc/trans/escape.trans (revision 27021) @@ -8,14 +8,14 @@ transcode_tblgen("", "amp_escape", [ ["{00-25,27-FF}", :nomap], ["26", hexstr("&")] - ]) + ], nil) transcode_tblgen("", "xml_text_escape", [ ["{00-25,27-3B,3D,3F-FF}", :nomap], ["26", hexstr("&")], ["3C", hexstr("<")], ["3E", hexstr(">")] - ]) + ], nil) transcode_tblgen("", "xml_attr_content_escape", [ ["{00-21,23-25,27-3B,3D,3F-FF}", :nomap], @@ -23,7 +23,7 @@ ["26", hexstr("&")], ["3C", hexstr("<")], ["3E", hexstr(">")] - ]) + ], nil) map_xml_attr_quote = {} map_xml_attr_quote["{00-FF}"] = :func_so Index: mvm/enc/trans/chinese.trans =================================================================== --- mvm/enc/trans/chinese.trans (revision 27020) +++ mvm/enc/trans/chinese.trans (revision 27021) @@ -1,8 +1,8 @@ #include "transcode_data.h" <% - gb2312_valid_byte_pattern = ValidEncoding['EUC-KR'] - gb12345_valid_byte_pattern = ValidEncoding['EUC-KR'] + gb2312_valid_byte_pattern = ValidEncoding('EUC-KR') + gb12345_valid_byte_pattern = ValidEncoding('EUC-KR') transcode_tblgen "GB2312", "UTF-8", [["{00-7f}", :nomap]] + Index: mvm/enc/trans/emoji_sjis_docomo.trans =================================================================== --- mvm/enc/trans/emoji_sjis_docomo.trans (revision 27020) +++ mvm/enc/trans/emoji_sjis_docomo.trans (revision 27021) @@ -9,7 +9,8 @@ CP932VDC:NEC_IBM/UCS CP932VDC:IBM/UCS CP932UDA/UCS - JISX0208:MS/UCS).join(",")) + JISX0208:MS/UCS).join(",")), + ValidEncoding('Shift_JIS') transcode_tblgen "UTF8-DOCOMO", "SJIS-DOCOMO", [["{00-7f}", :nomap]] + @@ -19,7 +20,8 @@ UCS/CP932VDC:NEC_IBM UCS/CP932VDC:IBM UCS/CP932UDA - UCS/JISX0208:MS).join(",")) + UCS/JISX0208:MS).join(",")), + ValidEncoding('UTF-8') %> <%= transcode_generated_code %> Index: mvm/enc/trans/emoji.trans =================================================================== --- mvm/enc/trans/emoji.trans (revision 27020) +++ mvm/enc/trans/emoji.trans (revision 27021) @@ -23,7 +23,7 @@ to_encoding = (to_company == "Unicode") ? "UTF-8" : "UTF8-"+to_company strict_mapping = EMOJI_EXCHANGE_TBL[from_encoding][to_encoding] - transcode_tblgen(from_encoding, to_encoding, strict_mapping + nomap_table) + transcode_tblgen(from_encoding, to_encoding, strict_mapping + nomap_table, nil) end end %> Index: mvm/enc/trans/emoji_iso2022_kddi.trans =================================================================== --- mvm/enc/trans/emoji_iso2022_kddi.trans (revision 27020) +++ mvm/enc/trans/emoji_iso2022_kddi.trans (revision 27021) @@ -32,7 +32,8 @@ CP932VDC:NEC_IBM/UCS CP932VDC:IBM/UCS CP932UDA/UCS - JISX0208:MS/UCS).join(",")) + JISX0208:MS/UCS).join(",")), + nil # mapping from UTF8-KDDI to stateless-ISO-2022-JP-KDDI transcode_tblgen "UTF8-KDDI", "stateless-ISO-2022-JP-KDDI", @@ -43,7 +44,8 @@ UCS/CP932VDC:NEC_IBM UCS/CP932VDC:IBM UCS/CP932UDA - UCS/JISX0208:MS).join(",")) + UCS/JISX0208:MS).join(",")), + ValidEncoding('UTF-8') %> <%= transcode_generated_code %> Index: mvm/enc/trans/big5.trans =================================================================== --- mvm/enc/trans/big5.trans (revision 27020) +++ mvm/enc/trans/big5.trans (revision 27021) @@ -8,10 +8,10 @@ transcode_tblgen "Big5", "UTF-8", [["{00-7f}", :nomap], *BIG5_TO_UCS_TBL] transcode_tblgen "UTF-8", "Big5", [["{00-7f}", :nomap], *BIG5_TO_UCS_TBL.map {|a,b| [b,a] }] - transcode_tblgen "Big5-HKSCS", "UTF-8", [["{00-7f}", :nomap], *BIG5_HKSCS_TO_UCS_TBL] + transcode_tblgen "Big5-HKSCS", "UTF-8", [["{00-7f}", :nomap], *BIG5_HKSCS_TO_UCS_TBL], ValidEncoding('Big5') transcode_tblgen "UTF-8", "Big5-HKSCS", [["{00-7f}", :nomap], *BIG5_HKSCS_TO_UCS_TBL.map {|a,b| [b,a] }] - transcode_tblgen "Big5-UAO", "UTF-8", [["{00-7f}", :nomap], *BIG5_UAO_TO_UCS_TBL] + transcode_tblgen "Big5-UAO", "UTF-8", [["{00-7f}", :nomap], *BIG5_UAO_TO_UCS_TBL], ValidEncoding('Big5') transcode_tblgen "UTF-8", "Big5-UAO", [["{00-7f}", :nomap], *BIG5_UAO_TO_UCS_TBL.map {|a,b| [b,a] }] %> @@ -22,4 +22,4 @@ Init_big5(void) { <%= transcode_register_code %> -} \ No newline at end of file +} Index: mvm/enc/trans/emoji_sjis_softbank.trans =================================================================== --- mvm/enc/trans/emoji_sjis_softbank.trans (revision 27020) +++ mvm/enc/trans/emoji_sjis_softbank.trans (revision 27021) @@ -9,7 +9,8 @@ CP932VDC:NEC_IBM/UCS CP932VDC:IBM/UCS CP932UDA/UCS - JISX0208:MS/UCS).join(",")) + JISX0208:MS/UCS).join(",")), + ValidEncoding('Shift_JIS') transcode_tblgen "UTF8-SoftBank", "SJIS-SoftBank", [["{00-7f}", :nomap]] + @@ -19,7 +20,8 @@ UCS/CP932VDC:NEC_IBM UCS/CP932VDC:IBM UCS/CP932UDA - UCS/JISX0208:MS).join(",")) + UCS/JISX0208:MS).join(",")), + ValidEncoding('UTF-8') %> <%= transcode_generated_code %> Index: mvm/enc/trans/emoji_sjis_kddi.trans =================================================================== --- mvm/enc/trans/emoji_sjis_kddi.trans (revision 27020) +++ mvm/enc/trans/emoji_sjis_kddi.trans (revision 27021) @@ -9,7 +9,8 @@ CP932VDC:NEC_IBM/UCS CP932VDC:IBM/UCS CP932UDA/UCS - JISX0208:MS/UCS).join(",")) + JISX0208:MS/UCS).join(",")), + ValidEncoding('Shift_JIS') transcode_tblgen "UTF8-KDDI", "SJIS-KDDI", [["{00-7f}", :nomap]] + @@ -20,7 +21,8 @@ UCS/CP932VDC:NEC_IBM UCS/CP932VDC:IBM UCS/CP932UDA - UCS/JISX0208:MS).join(",")) + UCS/JISX0208:MS).join(",")), + ValidEncoding('UTF-8') %> <%= transcode_generated_code %> Index: mvm/enum.c =================================================================== --- mvm/enum.c (revision 27020) +++ mvm/enum.c (revision 27021) @@ -2383,13 +2383,21 @@ * the block returns true for the element, * the element is beginning of a chunk. * - * The result enumerator yields the chunked elements as an array. - * So "each" method can be called as follows. + * The === and block is called from the first element to the last element + * of _enum_. + * The result for the first element is ignored. * + * The result enumerator yields the chunked elements as an array for +each+ + * method. + * +each+ method can be called as follows. + * * enum.slice_before(pattern).each {|ary| ... } * enum.slice_before {|elt| bool }.each {|ary| ... } * enum.slice_before(initial_state) {|elt, state| bool }.each {|ary| ... } * + * Other methods of Enumerator class and Enumerable module, + * such as map, etc., are also usable. + * * For example, iteration over ChangeLog entries can be implemented as * follows. * Index: mvm/string.c =================================================================== --- mvm/string.c (revision 27020) +++ mvm/string.c (revision 27021) @@ -6559,7 +6559,7 @@ * Returns a basic <em>n</em>-bit checksum of the characters in <i>str</i>, * where <em>n</em> is the optional <code>Fixnum</code> parameter, defaulting * to 16. The result is simply the sum of the binary value of each character in - * <i>str</i> modulo <code>2n - 1</code>. This is not a particularly good + * <i>str</i> modulo <code>2**n - 1</code>. This is not a particularly good * checksum. */ @@ -6570,6 +6570,8 @@ int bits; char *ptr, *p, *pend; long len; + VALUE sum = INT2FIX(0); + unsigned long sum0 = 0; if (argc == 0) { bits = 16; @@ -6581,36 +6583,42 @@ ptr = p = RSTRING_PTR(str); len = RSTRING_LEN(str); pend = p + len; - if (bits >= (int)sizeof(long)*CHAR_BIT) { - VALUE sum = INT2FIX(0); - while (p < pend) { - str_mod_check(str, ptr, len); - sum = rb_funcall(sum, '+', 1, INT2FIX((unsigned char)*p)); - p++; - } - if (bits != 0) { - VALUE mod; + while (p < pend) { + if (FIXNUM_MAX - UCHAR_MAX < sum0) { + sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0)); + str_mod_check(str, ptr, len); + sum0 = 0; + } + sum0 += (unsigned char)*p; + p++; + } - mod = rb_funcall(INT2FIX(1), rb_intern("<<"), 1, INT2FIX(bits)); - mod = rb_funcall(mod, '-', 1, INT2FIX(1)); - sum = rb_funcall(sum, '&', 1, mod); - } - return sum; + if (bits == 0) { + if (sum0) { + sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0)); + } } else { - unsigned long sum = 0; + if (sum == INT2FIX(0)) { + if (bits < (int)sizeof(long)*CHAR_BIT) { + sum0 &= (((unsigned long)1)<<bits)-1; + } + sum = LONG2FIX(sum0); + } + else { + VALUE mod; - while (p < pend) { - str_mod_check(str, ptr, len); - sum += (unsigned char)*p; - p++; - } - if (bits != 0) { - sum &= (((unsigned long)1)<<bits)-1; - } - return rb_int2inum(sum); + if (sum0) { + sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0)); + } + + mod = rb_funcall(INT2FIX(1), rb_intern("<<"), 1, INT2FIX(bits)); + mod = rb_funcall(mod, '-', 1, INT2FIX(1)); + sum = rb_funcall(sum, '&', 1, mod); + } } + return sum; } static VALUE Index: mvm/object.c =================================================================== --- mvm/object.c (revision 27020) +++ mvm/object.c (revision 27021) @@ -92,7 +92,7 @@ { VALUE oid = rb_obj_id(obj); st_index_t h = rb_hash_end(rb_hash_start(NUM2LONG(oid))); - return LONG2NUM(h); + return LONG2FIX(h); } /* Index: mvm/io.c =================================================================== --- mvm/io.c (revision 27020) +++ mvm/io.c (revision 27021) @@ -112,12 +112,17 @@ #define numberof(array) (int)(sizeof(array) / sizeof((array)[0])) +#define IO_RBUF_CAPA_MIN 8192 +#define IO_CBUF_CAPA_MIN (128*1024) +#define IO_RBUF_CAPA_FOR(fptr) (NEED_READCONV(fptr) ? IO_CBUF_CAPA_MIN : IO_RBUF_CAPA_MIN) +#define IO_WBUF_CAPA_MIN 8192 + #define orig_stdout (*rb_vm_specific_ptr(rb_vmkey_orig_stdout)) #define orig_stderr (*rb_vm_specific_ptr(rb_vmkey_orig_stderr)) static ID id_write, id_read, id_getc, id_flush, id_readpartial; static VALUE sym_mode, sym_perm, sym_extenc, sym_intenc, sym_encoding, sym_open_args; -static VALUE sym_textmode, sym_binmode; +static VALUE sym_textmode, sym_binmode, sym_autoclose; struct timeval rb_time_interval(VALUE); @@ -198,6 +203,19 @@ # endif #endif +#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) +/* Windows */ +# define NEED_NEWLINE_DECORATOR_ON_READ(fptr) (!(fptr->mode & FMODE_BINMODE)) +# define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) (!(fptr->mode & FMODE_BINMODE)) +# define TEXTMODE_NEWLINE_DECORATOR_ON_WRITE ECONV_CRLF_NEWLINE_DECORATOR +#else +/* Unix */ +# define NEED_NEWLINE_DECORATOR_ON_READ(fptr) (fptr->mode & FMODE_TEXTMODE) +# define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) 0 +#endif +#define NEED_READCONV(fptr) (fptr->encs.enc2 != NULL || NEED_NEWLINE_DECORATOR_ON_READ(fptr)) +#define NEED_WRITECONV(fptr) ((fptr->encs.enc != NULL && fptr->encs.enc != rb_ascii8bit_encoding()) || NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) || (fptr->encs.ecflags & (ECONV_DECORATOR_MASK|ECONV_STATEFUL_DECORATOR_MASK))) + #if !defined HAVE_SHUTDOWN && !defined shutdown #define shutdown(a,b) 0 #endif @@ -328,16 +346,17 @@ long len = RSTRING_LEN(str); if (fptr->rbuf == NULL) { + const int min_capa = IO_RBUF_CAPA_FOR(fptr); fptr->rbuf_off = 0; fptr->rbuf_len = 0; #if SIZEOF_LONG > SIZEOF_INT if (len > INT_MAX) rb_raise(rb_eIOError, "ungetbyte failed"); #endif - if (len > 8192) + if (len > min_capa) fptr->rbuf_capa = (int)len; else - fptr->rbuf_capa = 8192; + fptr->rbuf_capa = min_capa; fptr->rbuf = ALLOC_N(char, fptr->rbuf_capa); } if (fptr->rbuf_capa < len + fptr->rbuf_len) { @@ -697,19 +716,6 @@ } } -#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) -/* Windows */ -# define NEED_NEWLINE_DECORATOR_ON_READ(fptr) (!(fptr->mode & FMODE_BINMODE)) -# define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) (!(fptr->mode & FMODE_BINMODE)) -# define TEXTMODE_NEWLINE_DECORATOR_ON_WRITE ECONV_CRLF_NEWLINE_DECORATOR -#else -/* Unix */ -# define NEED_NEWLINE_DECORATOR_ON_READ(fptr) (fptr->mode & FMODE_TEXTMODE) -# define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) 0 -#endif -#define NEED_READCONV(fptr) (fptr->encs.enc2 != NULL || NEED_NEWLINE_DECORATOR_ON_READ(fptr)) -#define NEED_WRITECONV(fptr) ((fptr->encs.enc != NULL && fptr->encs.enc != rb_ascii8bit_encoding()) || NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) || (fptr->encs.ecflags & (ECONV_DECORATOR_MASK|ECONV_STATEFUL_DECORATOR_MASK))) - static void make_writeconv(rb_io_t *fptr) { @@ -795,7 +801,7 @@ if (fptr->wbuf == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) { fptr->wbuf_off = 0; fptr->wbuf_len = 0; - fptr->wbuf_capa = 8192; + fptr->wbuf_capa = IO_WBUF_CAPA_MIN; fptr->wbuf = ALLOC_N(char, fptr->wbuf_capa); fptr->write_lock = rb_mutex_new(); } @@ -1168,7 +1174,7 @@ if (fptr->rbuf == NULL) { fptr->rbuf_off = 0; fptr->rbuf_len = 0; - fptr->rbuf_capa = 8192; + fptr->rbuf_capa = IO_RBUF_CAPA_FOR(fptr); fptr->rbuf = ALLOC_N(char, fptr->rbuf_capa); } if (fptr->rbuf_len == 0) { @@ -1423,7 +1429,7 @@ { rb_io_t *fptr; const char *cname; - char fd_desc[256]; + char fd_desc[4+sizeof(int)*3]; const char *path; const char *st = ""; @@ -1584,7 +1590,8 @@ rb_exc_raise(rb_econv_open_exc(sname, dname, ecflags)); fptr->cbuf_off = 0; fptr->cbuf_len = 0; - fptr->cbuf_capa = size < 1024 ? 1024 : size; + if (size < IO_CBUF_CAPA_MIN) size = IO_CBUF_CAPA_MIN; + fptr->cbuf_capa = size; fptr->cbuf = ALLOC_N(char, fptr->cbuf_capa); } } @@ -6397,6 +6404,9 @@ * If the value is truth value, same as "b" in argument <code>mode</code>. * :binmode :: * If the value is truth value, same as "t" in argument <code>mode</code>. + * :autoclose :: + * If the value is +false+, the _fd_ will be kept open after this + * +IO+ instance gets finalized. * * Also <code>opt</code> can have same keys in <code>String#encode</code> for * controlling conversion between the external encoding and the internal encoding. @@ -6467,6 +6477,9 @@ rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError)); } #endif + if (!NIL_P(opt) && rb_hash_aref(opt, sym_autoclose) == Qfalse) { + fmode |= FMODE_PREP; + } MakeOpenFile(io, fp); fp->fd = fd; fp->mode = fmode; @@ -6561,6 +6574,53 @@ return io; } +/* + * call-seq: + * ios.autoclose? => true or false + * + * Returns +true+ if the underlying file descriptor of _ios_ will be + * closed automatically at its finalization, otherwise +false+. + */ + +static VALUE +rb_io_autoclose_p(VALUE io) +{ + rb_io_t *fptr; + rb_secure(4); + GetOpenFile(io, fptr); + return (fptr->mode & FMODE_PREP) ? Qfalse : Qtrue; +} + +/* + * call-seq: + * io.autoclose = bool => true or false + * + * Sets auto-close flag. + * + * f = open("/dev/null") + * IO.for_fd(f.fileno) + * # ... + * f.gets # may cause IOError + * + * f = open("/dev/null") + * IO.for_fd(f.fileno).autoclose = true + * # ... + * f.gets # won't cause IOError + */ + +static VALUE +rb_io_set_autoclose(VALUE io, VALUE autoclose) +{ + rb_io_t *fptr; + rb_secure(4); + GetOpenFile(io, fptr); + if (!RTEST(autoclose)) + fptr->mode |= FMODE_PREP; + else + fptr->mode &= ~FMODE_PREP; + return io; +} + static void argf_mark(void *ptr) { @@ -9976,6 +10036,9 @@ rb_define_method(rb_cIO, "internal_encoding", rb_io_internal_encoding, 0); rb_define_method(rb_cIO, "set_encoding", rb_io_set_encoding, -1); + rb_define_method(rb_cIO, "autoclose?", rb_io_autoclose_p, 0); + rb_define_method(rb_cIO, "autoclose=", rb_io_set_autoclose, 1); + rb_define_variable("$stdin", &rb_stdin); rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO, "<STDIN>"); rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter); @@ -10143,4 +10206,5 @@ sym_open_args = ID2SYM(rb_intern("open_args")); sym_textmode = ID2SYM(rb_intern("textmode")); sym_binmode = ID2SYM(rb_intern("binmode")); + sym_autoclose = ID2SYM(rb_intern("autoclose")); } Index: mvm/lib/rake/packagetask.rb =================================================================== --- mvm/lib/rake/packagetask.rb (revision 27020) +++ mvm/lib/rake/packagetask.rb (revision 27021) @@ -1,4 +1,4 @@ -# Define a package task libarary to aid in the definition of +# Define a package task library to aid in the definition of # redistributable package files. require 'rake' Index: mvm/lib/xmlrpc/server.rb =================================================================== --- mvm/lib/xmlrpc/server.rb (revision 27020) +++ mvm/lib/xmlrpc/server.rb (revision 27021) @@ -133,7 +133,7 @@ begin ret = obj.call(*args) # call the original service-method # could convert the return value - resuce + rescue # rescue exceptions end } Index: mvm/lib/resolv-replace.rb =================================================================== --- mvm/lib/resolv-replace.rb (revision 27020) +++ mvm/lib/resolv-replace.rb (revision 27021) @@ -2,7 +2,9 @@ require 'resolv' class << IPSocket + # :stopdoc: alias original_resolv_getaddress getaddress + # :startdoc: def getaddress(host) begin return Resolv.getaddress(host).to_s @@ -12,27 +14,35 @@ end end -class TCPSocket +class TCPSocket < IPSocket + # :stopdoc: alias original_resolv_initialize initialize + # :startdoc: def initialize(host, serv, *rest) rest[0] = IPSocket.getaddress(rest[0]) unless rest.empty? original_resolv_initialize(IPSocket.getaddress(host), serv, *rest) end end -class UDPSocket +class UDPSocket < IPSocket + # :stopdoc: alias original_resolv_bind bind + # :startdoc: def bind(host, port) host = IPSocket.getaddress(host) if host != "" original_resolv_bind(host, port) end + # :stopdoc: alias original_resolv_connect connect + # :startdoc: def connect(host, port) original_resolv_connect(IPSocket.getaddress(host), port) end + # :stopdoc: alias original_resolv_send send + # :startdoc: def send(mesg, flags, *rest) if rest.length == 2 host, port = rest @@ -55,8 +65,10 @@ end end -class SOCKSSocket +class SOCKSSocket < TCPSocket + # :stopdoc: alias original_resolv_initialize initialize + # :startdoc: def initialize(host, serv) original_resolv_initialize(IPSocket.getaddress(host), port) end Index: mvm/lib/rexml/entity.rb =================================================================== --- mvm/lib/rexml/entity.rb (revision 27020) +++ mvm/lib/rexml/entity.rb (revision 27021) @@ -25,7 +25,7 @@ # Create a new entity. Simple entities can be constructed by passing a # name, value to the constructor; this creates a generic, plain entity # reference. For anything more complicated, you have to pass a Source to - # the constructor with the entity definiton, or use the accessor methods. + # the constructor with the entity definition, or use the accessor methods. # +WARNING+: There is no validation of entity state except when the entity # is read from a stream. If you start poking around with the accessors, # you can easily create a non-conformant Entity. The best thing to do is Index: mvm/lib/rubygems/spec_fetcher.rb =================================================================== --- mvm/lib/rubygems/spec_fetcher.rb (revision 27020) +++ mvm/lib/rubygems/spec_fetcher.rb (revision 27021) @@ -53,7 +53,7 @@ end ## - # Retuns the local directory to write +uri+ to. + # Returns the local directory to write +uri+ to. def cache_dir(uri) File.join @dir, "#{uri.host}%#{uri.port}", File.dirname(uri.path) Index: mvm/lib/rubygems/commands/dependency_command.rb =================================================================== --- mvm/lib/rubygems/commands/dependency_command.rb (revision 27020) +++ mvm/lib/rubygems/commands/dependency_command.rb (revision 27021) @@ -159,7 +159,7 @@ response end - # Retuns list of [specification, dep] that are satisfied by spec. + # Returns list of [specification, dep] that are satisfied by spec. def find_reverse_dependencies(spec) result = [] Index: mvm/lib/csv.rb =================================================================== --- mvm/lib/csv.rb (revision 27020) +++ mvm/lib/csv.rb (revision 27021) @@ -1212,7 +1212,7 @@ # Note that a passed String *is* modfied by this method. Call dup() before # passing if you need a new String. # - # The +options+ parameter can be anthing CSV::new() understands. This method + # The +options+ parameter can be anything CSV::new() understands. This method # understands an additional <tt>:encoding</tt> parameter when not passed a # String to set the base Encoding for the output. CSV needs this hint if you # plan to output non-ASCII compatible data. @@ -1238,7 +1238,7 @@ # This method is a shortcut for converting a single row (Array) into a CSV # String. # - # The +options+ parameter can be anthing CSV::new() understands. This method + # The +options+ parameter can be anything CSV::new() understands. This method # understands an additional <tt>:encoding</tt> parameter to set the base # Encoding for the output. This method will try to guess your Encoding from # the first non-+nil+ field in +row+, if possible, but you may need to use @@ -1372,7 +1372,7 @@ # a into an Array. Note that if +line+ contains multiple rows, anything # beyond the first row is ignored. # - # The +options+ parameter can be anthing CSV::new() understands. + # The +options+ parameter can be anything CSV::new() understands. # def self.parse_line(line, options = Hash.new) new(line, options).shift Index: mvm/lib/rubygems.rb =================================================================== --- mvm/lib/rubygems.rb (revision 27020) +++ mvm/lib/rubygems.rb (revision 27021) @@ -310,7 +310,7 @@ ## # Find the full path to the executable for gem +name+. If the +exec_name+ # is not given, the gem's default_executable is chosen, otherwise the - # specifed executable's path is returned. +version_requirements+ allows you + # specified executable's path is returned. +version_requirements+ allows you # to specify specific gem versions. def self.bin_path(name, exec_name = nil, *version_requirements) Index: mvm/lib/thwait.rb =================================================================== --- mvm/lib/thwait.rb (revision 27020) +++ mvm/lib/thwait.rb (revision 27021) @@ -2,7 +2,7 @@ # thwait.rb - thread synchronization class # $Release Version: 0.9 $ # $Revision: 1.3 $ -# by Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.) +# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd.) # # -- # feature: Index: mvm/lib/ipaddr.rb =================================================================== --- mvm/lib/ipaddr.rb (revision 27020) +++ mvm/lib/ipaddr.rb (revision 27021) @@ -18,7 +18,7 @@ require 'socket' unless Socket.const_defined? "AF_INET6" - class Socket + class Socket < BasicSocket AF_INET6 = Object.new end @@ -444,7 +444,7 @@ # automatically from a specified string, you can specify one # explicitly by the optional second argument. # - # Otherwise an IP addess is generated from a packed in_addr value + # Otherwise an IP address is generated from a packed in_addr value # and an address family. # # The IPAddr class defines many methods and operators, and some of @@ -472,7 +472,7 @@ #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil, # Socket::AI_NUMERICHOST) begin - IPSocket.getaddress(prefix) # test if address is vaild + IPSocket.getaddress(prefix) # test if address is valid rescue raise ArgumentError, "invalid address" end Index: mvm/lib/irb/output-method.rb =================================================================== --- mvm/lib/irb/output-method.rb (revision 27020) +++ mvm/lib/irb/output-method.rb (revision 27021) @@ -1,5 +1,5 @@ # -# output-method.rb - optput methods used by irb +# output-method.rb - output methods used by irb # $Release Version: 0.9.6$ # $Revision$ # by Keiju ISHITSUKA(keiju@r...) Index: mvm/lib/irb/notifier.rb =================================================================== --- mvm/lib/irb/notifier.rb (revision 27020) +++ mvm/lib/irb/notifier.rb (revision 27021) @@ -25,7 +25,7 @@ end module_function :def_notifier - class AbstructNotifier + class AbstractNotifier def initialize(prefix, base_notifier) @prefix = prefix @base_notifier = base_notifier @@ -72,7 +72,7 @@ end end - class CompositeNotifier<AbstructNotifier + class CompositeNotifier<AbstractNotifier def initialize(prefix, base_notifier) super @@ -93,7 +93,7 @@ def level_notifier=(value) case value - when AbstructNotifier + when AbstractNotifier @level_notifier = value when Integer l = @notifiers[value] @@ -107,7 +107,7 @@ alias level= level_notifier= end - class LeveledNotifier<AbstructNotifier + class LeveledNotifier<AbstractNotifier include Comparable def initialize(base, level, prefix) Index: mvm/lib/irb/xmp.rb =================================================================== --- mvm/lib/irb/xmp.rb (revision 27020) +++ mvm/lib/irb/xmp.rb (revision 27021) @@ -75,7 +75,7 @@ if @encoding and exps.encoding != @encoding enc = Encoding.compatible?(@exps.join("\n"), exps) if enc.nil? - raise Encoding::CompatibilityError, "Encoding in which the passed exression is encoded is not compatible to the preceding's one" + raise Encoding::CompatibilityError, "Encoding in which the passed expression is encoded is not compatible to the preceding's one" else @encoding = enc end Index: mvm/lib/uri/common.rb =================================================================== --- mvm/lib/uri/common.rb (revision 27020) +++ mvm/lib/uri/common.rb (revision 27021) @@ -722,6 +722,10 @@ # :nodoc: TBLDECWWWCOMP_ = {} + # :nodoc: + HTML5ASCIIINCOMPAT = [Encoding::UTF_7, Encoding::UTF_16BE, Encoding::UTF_16LE, + Encoding::UTF_32BE, Encoding::UTF_32LE] + # Encode given +str+ to URL-encoded form data. # # This doesn't convert *, -, ., 0-9, A-Z, _, a-z, @@ -733,35 +737,19 @@ def self.encode_www_form_component(str) if TBLENCWWWCOMP_.empty? 256.times do |i| - case i - when 0x20 - TBLENCWWWCOMP_[' '] = '+' - # when 0x2A, 0x2D, 0x2E, 0x30..0x39, 0x41..0x5A, 0x5F, 0x61..0x7A - else - TBLENCWWWCOMP_[i.chr] = '%%%02X' % i - end + TBLENCWWWCOMP_[i.chr] = '%%%02X' % i end + TBLENCWWWCOMP_[' '] = '+' TBLENCWWWCOMP_.freeze end str = str.to_s - case str.encoding - when Encoding::ASCII_8BIT, Encoding::US_ASCII, Encoding::UTF_8 - str = str.dup.force_encoding(Encoding::ASCII_8BIT) - str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_) - when Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE - reg = Regexp.new('[^*\-.0-9A-Z_a-z]+'.encode(str.encoding)) - str = str.gsub(reg){ - $&.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_). - force_encoding(str.encoding) - } + if HTML5ASCIIINCOMPAT.include?(str.encoding) + str = str.encode(Encoding::UTF_8) else - if str.encoding.ascii_compatible? - str = str.gsub(/[^*\-.0-9A-Z_a-z]+/){ - $&.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_)} - else - str = str.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_) - end + str = str.dup end + str.force_encoding(Encoding::ASCII_8BIT) + str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_) str.force_encoding(Encoding::US_ASCII) end @@ -778,11 +766,11 @@ TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr - TBLDECWWWCOMP_['+'] = ' ' if i == 0x20 end + TBLDECWWWCOMP_['+'] = ' ' TBLDECWWWCOMP_.freeze end - str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(Encoding::UTF_8) + str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc) end # Generate URL-encoded form data from given +enum+. @@ -794,7 +782,8 @@ # # This doesn't convert encodings of give items, so convert them before call # this method if you want to send data as other than original encoding or - # mixed encoding data. + # mixed encoding data. (strings which is encoded in HTML5 ASCII incompatible + # encoding is converted to UTF-8) # # This doesn't treat files. When you send a file, use multipart/form-data. # Index: mvm/lib/optparse.rb =================================================================== --- mvm/lib/optparse.rb (revision 27020) +++ mvm/lib/optparse.rb (revision 27021) @@ -1563,7 +1563,7 @@ yesno = CompletingHash.new %w[- no false].each {|el| yesno[el] = false} %w[+ yes true].each {|el| yesno[el] = true} - yesno['nil'] = false # shoud be nil? + yesno['nil'] = false # should be nil? accept(TrueClass, yesno) {|arg, val| val == nil or val} # # Similar to TrueClass, but defaults to false. Index: mvm/lib/cgi/html.rb =================================================================== --- mvm/lib/cgi/html.rb (revision 27020) +++ mvm/lib/cgi/html.rb (revision 27021) @@ -455,7 +455,7 @@ # image_button("url", "name", "string") # # <INPUT TYPE="image" SRC="url" NAME="name" ALT="string"> # - # image_button("SRC" => "url", "ATL" => "strng") + # image_button("SRC" => "url", "ALT" => "string") # # <INPUT TYPE="image" SRC="url" ALT="string"> def image_button(src = "", name = nil, alt = nil) attributes = if src.kind_of?(String) Index: mvm/lib/cgi/core.rb =================================================================== --- mvm/lib/cgi/core.rb (revision 27020) +++ mvm/lib/cgi/core.rb (revision 27021) @@ -408,7 +408,7 @@ # values is an Array. attr_reader :params - # Get the uploaed files as a hash of name=>values pairs + # Get the uploaded files as a hash of name=>values pairs attr_reader :files # Set all the parameters. Index: mvm/lib/shell/process-controller.rb =================================================================== --- mvm/lib/shell/process-controller.rb (revision 27020) +++ mvm/lib/shell/process-controller.rb (revision 27021) @@ -191,7 +191,7 @@ @active_jobs.delete command ProcessController.inactivate(self) if @active_jobs.empty? - command.notify("start_jon in ierminate_jon(%id)", Shell::debug?) + command.notify("start_job in terminate_job(%id)", Shell::debug?) start_job end end @@ -281,13 +281,13 @@ command.notify("job(%id) start to waiting finish.", @shell.debug?) _pid = Process.waitpid(pid, nil) rescue Errno::ECHILD - command.notify "warn: job(%id) was done already waitipd." + command.notify "warn: job(%id) was done already waitpid." _pid = true # rescue # STDERR.puts $! ensure command.notify("Job(%id): Wait to finish when Process finished.", @shell.debug?) - # when the process ends, wait until the command termintes + # when the process ends, wait until the command terminates if USING_AT_EXIT_WHEN_PROCESS_EXIT or _pid else command.notify("notice: Process finishing...", Index: mvm/lib/shell/command-processor.rb =================================================================== --- mvm/lib/shell/command-processor.rb (revision 27020) +++ mvm/lib/shell/command-processor.rb (revision 27021) @@ -35,7 +35,7 @@ install_builtin_commands - # define CommandProccessor#methods to Shell#methods and Filter#methods + # define CommandProcessor#methods to Shell#methods and Filter#methods for m in CommandProcessor.instance_methods(false) - NoDelegateMethods add_delegate_command_to_shell(m) end Index: mvm/lib/prime.rb =================================================================== --- mvm/lib/prime.rb (revision 27020) +++ mvm/lib/prime.rb (revision 27021) @@ -473,7 +473,7 @@ end end - # Provides a +Prime+ object with compatibility to Ruby 1.8 when instanciated via +Prime+.+new+. + # Provides a +Prime+ object with compatibility to Ruby 1.8 when instantiated via +Prime+.+new+. module OldCompatibility # Returns the next prime number and forwards internal pointer. def succ Index: mvm/lib/date.rb =================================================================== --- mvm/lib/date.rb (revision 27020) +++ mvm/lib/date.rb (revision 27021) @@ -1,7 +1,7 @@ # # date.rb - date and time library # -# Author: Tadayoshi Funaba 1998-2009 +# Author: Tadayoshi Funaba 1998-2010 # # Documentation: William Webber <william@w...> # @@ -1416,7 +1416,10 @@ y, m = (year * 12 + (mon - 1) + n).divmod(12) m, = (m + 1) .divmod(1) d = mday - d -= 1 until jd2 = _valid_civil?(y, m, d, @sg) + until jd2 = _valid_civil?(y, m, d, @sg) + d -= 1 + raise ArgumentError, 'invalid date' unless d > 0 + end self + (jd2 - jd) end Index: mvm/lib/net/https.rb =================================================================== --- mvm/lib/net/https.rb (revision 27020) +++ mvm/lib/net/https.rb (revision 27021) @@ -71,7 +71,7 @@ : verify_mode, verify_mode=((|mode|)) Sets the flags for server the certification verification at - begining of SSL/TLS session. + beginning of SSL/TLS session. OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable. : verify_callback, verify_callback=((|proc|)) Index: mvm/lib/net/smtp.rb =================================================================== --- mvm/lib/net/smtp.rb (revision 27020) +++ mvm/lib/net/smtp.rb (revision 27021) @@ -118,7 +118,7 @@ # Net::SMTP.start('your.smtp.server', 25) do |smtp| # smtp.send_message msgstr, # 'your@m...', - # 'his_addess@e...' + # 'his_address@e...' # end # # === Closing the Session Index: mvm/vm_eval.c =================================================================== --- mvm/vm_eval.c (revision 27020) +++ mvm/vm_eval.c (revision 27021) @@ -89,14 +89,14 @@ if (argc != 1) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); } - val = rb_ivar_set(recv, def->body.attr_id, argv[0]); + val = rb_ivar_set(recv, def->body.attr.id, argv[0]); break; } case VM_METHOD_TYPE_IVAR: { if (argc != 0) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc); } - val = rb_attr_get(recv, def->body.attr_id); + val = rb_attr_get(recv, def->body.attr.id); break; } case VM_METHOD_TYPE_BMETHOD: { Index: mvm/proc.c =================================================================== --- mvm/proc.c (revision 27020) +++ mvm/proc.c (revision 27021) @@ -1629,15 +1629,18 @@ return rb_mod_method_arity(CLASS_OF(obj), id); } -rb_iseq_t * -rb_method_get_iseq(VALUE method) +static inline rb_method_definition_t * +method_get_def(VALUE method) { struct METHOD *data; - rb_method_definition_t *def; TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); - def = data->me.def; + return data->me.def; +} +static rb_iseq_t * +method_get_iseq(rb_method_definition_t *def) +{ switch (def->type) { case VM_METHOD_TYPE_BMETHOD: return get_proc_iseq(def->body.proc, 0); @@ -1648,6 +1651,12 @@ } } +rb_iseq_t * +rb_method_get_iseq(VALUE method) +{ + return method_get_iseq(method_get_def(method)); +} + /* * call-seq: * meth.source_location => [String, Fixnum] @@ -1659,7 +1668,13 @@ VALUE rb_method_location(VALUE method) { - return iseq_location(rb_method_get_iseq(method)); + rb_method_definition_t *def = method_get_def(method); + if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) { + if (!def->body.attr.location) + return Qnil; + return rb_ary_dup(def->body.attr.location); + } + return iseq_location(method_get_iseq(def)); } /* Index: mvm/symbian/setup =================================================================== --- mvm/symbian/setup (revision 27020) +++ mvm/symbian/setup (revision 27021) @@ -183,6 +183,7 @@ @echo>>$(1) #define DLEXT_MAXLEN 4 @echo>>$(1) #define DLEXT ".dll" @echo>>$(1) #define EXECUTABLE_EXTS ".exe",".com",".cmd",".bat" +@echo>>$(1) #define RUBY_EXEC_PREFIX "" @echo>>$(1) #define DLN_NEEDS_ALT_SEPARATOR '\\' @echo>>$(1) #define RUBY_LIB_VERSION_STYLE 3 @echo>>$(1) #define RUBY_LIB_PREFIX "C:/Data/Ruby/lib" Index: mvm/vm_method.c =================================================================== --- mvm/vm_method.c (revision 27020) +++ mvm/vm_method.c (revision 27021) @@ -263,6 +263,9 @@ rb_method_entry_t * rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex) { + rb_thread_t *th; + rb_control_frame_t *cfp; + int line; rb_method_entry_t *me = rb_add_method_def(klass, mid, type, 0, noex); rb_method_definition_t *def = ALLOC(rb_method_definition_t); me->def = def; @@ -278,7 +281,15 @@ break; case VM_METHOD_TYPE_ATTRSET: case VM_METHOD_TYPE_IVAR: - def->body.attr_id = (ID)opts; + def->body.attr.id = (ID)opts; + th = GET_THREAD(); + cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); + if (cfp && (line = rb_vm_get_sourceline(cfp))) { + VALUE location = rb_ary_new3(2, cfp->iseq->filename, INT2FIX(line)); + def->body.attr.location = rb_ary_freeze(location); + } else { + def->body.attr.location = Qfalse; + } break; case VM_METHOD_TYPE_BMETHOD: def->body.proc = (VALUE)opts; @@ -842,7 +853,7 @@ d1->body.cfunc.argc == d2->body.cfunc.argc; case VM_METHOD_TYPE_ATTRSET: case VM_METHOD_TYPE_IVAR: - return d1->body.attr_id == d2->body.attr_id; + return d1->body.attr.id == d2->body.attr.id; case VM_METHOD_TYPE_BMETHOD: return RTEST(rb_equal(d1->body.proc, d2->body.proc)); case VM_METHOD_TYPE_MISSING: Index: mvm/gc.c =================================================================== --- mvm/gc.c (revision 27020) +++ mvm/gc.c (revision 27021) @@ -1441,6 +1441,10 @@ case VM_METHOD_TYPE_BMETHOD: gc_mark(objspace, def->body.proc, lev); break; + case VM_METHOD_TYPE_ATTRSET: + case VM_METHOD_TYPE_IVAR: + gc_mark(objspace, def->body.attr.location, lev); + break; default: break; /* ignore */ } Index: mvm/Makefile.in =================================================================== --- mvm/Makefile.in (revision 27020) +++ mvm/Makefile.in (revision 27021) @@ -259,9 +259,10 @@ set dummy `for dir; do \ find $$dir -name Makefile | sed 's:^\./::;s:/Makefile$$:~:' | sort | sed 's:~$$::'; \ done`; shift; \ + cd ..; \ for dir; do \ echo $(@:-ext=)ing "$$dir"; \ - (cd "$$dir" && exec $(MAKE) $(MFLAGS) $(@:-ext=)) && \ + (cd "ext/$$dir" && exec $(MAKE) $(MFLAGS) $(@:-ext=)) && \ case "$@" in \ *distclean-ext*|*realclean-ext*) \ $(RMDIRS) "$$dir";; \ Index: mvm/ext/bigdecimal/bigdecimal.c =================================================================== --- mvm/ext/bigdecimal/bigdecimal.c (revision 27020) +++ mvm/ext/bigdecimal/bigdecimal.c (revision 27021) @@ -483,10 +483,7 @@ BigDecimal_to_i(VALUE self) { ENTER(5); - int e,n,i,nf; - U_LONG v,b,j; - volatile VALUE str; - char *psz,*pch; + int e,nf; Real *p; GUARD_OBJ(p,GetVpValue(self,1)); @@ -1013,7 +1010,6 @@ BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ { ENTER(3); - VALUE obj; Real *div=NULL, *mod=NULL; if(BigDecimal_DoDivmod(self,r,&div,&mod)) { @@ -1097,7 +1093,6 @@ BigDecimal_divmod(VALUE self, VALUE r) { ENTER(5); - VALUE obj; Real *div=NULL, *mod=NULL; if(BigDecimal_DoDivmod(self,r,&div,&mod)) { @@ -1114,7 +1109,6 @@ VALUE b,n; int na = rb_scan_args(argc,argv,"11",&b,&n); if(na==1) { /* div in Float sense */ - VALUE obj; Real *div=NULL; Real *mod; if(BigDecimal_DoDivmod(self,b,&div,&mod)) { Index: mvm/ext/.document =================================================================== --- mvm/ext/.document (revision 27020) +++ mvm/ext/.document (revision 27021) @@ -52,22 +52,7 @@ readline/readline.c ripper/ripper.c ripper/lib -socket/init.c -socket/raddrinfo.c -socket/basicsocket.c -socket/ipsocket.c -socket/tcpsocket.c -socket/tcpserver.c -socket/sockssocket.c -socket/udpsocket.c -socket/unixsocket.c -socket/unixserver.c -socket/socket.c -socket/option.c -socket/ancdata.c -socket/constants.c -socket/constdefs.c -socket/lib/socket.rb +socket stringio/stringio.c strscan/strscan.c win32ole Index: mvm/ext/dl/lib/dl/pack.rb =================================================================== --- mvm/ext/dl/lib/dl/pack.rb (revision 27020) +++ mvm/ext/dl/lib/dl/pack.rb (revision 27021) @@ -79,7 +79,7 @@ case SIZEOF_VOIDP when SIZEOF_LONG ary.pack(@template) - when SIZEOF_LONG + when SIZEOF_LONG_LONG ary.pack(@template) else raise(RuntimeError, "sizeof(void*)?") Index: mvm/ext/socket/tcpsocket.c =================================================================== --- mvm/ext/socket/tcpsocket.c (revision 27020) +++ mvm/ext/socket/tcpsocket.c (revision 27021) @@ -56,10 +56,12 @@ } /* - * TCPSocket class + * Document-class: ::TCPSocket < IPSocket + * + * TCPSocket represents a TCP/IP client socket. */ void -Init_tcpsocket(void) +rsock_init_tcpsocket(void) { rb_cTCPSocket = rb_define_class("TCPSocket", rb_cIPSocket); rb_define_singleton_method(rb_cTCPSocket, "gethostbyname", tcp_s_gethostbyname, 1); Index: mvm/ext/socket/rubysocket.h =================================================================== --- mvm/ext/socket/rubysocket.h (revision 27020) +++ mvm/ext/socket/rubysocket.h (revision 27021) @@ -218,6 +218,8 @@ VALUE rsock_ipaddr(struct sockaddr *sockaddr, int norevlookup); VALUE rsock_make_hostent(VALUE host, struct addrinfo *addr, VALUE (*ipaddr)(struct sockaddr *, size_t)); +int rsock_revlookup_flag(VALUE revlookup, int *norevlookup); + #ifdef HAVE_SYS_UN_H const char* rsock_unixpath(struct sockaddr_un *sockaddr, socklen_t len); VALUE rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len); @@ -254,25 +256,35 @@ VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len); VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len); +VALUE rsock_sock_listen(VALUE sock, VALUE log); VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data); +#if defined(HAVE_SENDMSG) +VALUE rsock_bsock_sendmsg(int argc, VALUE *argv, VALUE sock); +VALUE rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock); +#endif +#if defined(HAVE_RECVMSG) +VALUE rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock); +VALUE rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock); +#endif + #ifdef HAVE_ST_MSG_CONTROL void rsock_discard_cmsg_resource(struct msghdr *mh); #endif -void Init_basicsocket(void); -void Init_ipsocket(void); -void Init_tcpsocket(void); -void Init_tcpserver(void); -void Init_sockssocket(void); -void Init_udpsocket(void); -void Init_unixsocket(void); -void Init_unixserver(void); -void Init_socket_constants(void); -void Init_ancdata(void); -void Init_addrinfo(void); -void Init_sockopt(void); -void Init_socket_init(void); +void rsock_init_basicsocket(void); +void rsock_init_ipsocket(void); +void rsock_init_tcpsocket(void); +void rsock_init_tcpserver(void); +void rsock_init_sockssocket(void); +void rsock_init_udpsocket(void); +void rsock_init_unixsocket(void); +void rsock_init_unixserver(void); +void rsock_init_socket_constants(void); +void rsock_init_ancdata(void); +void rsock_init_addrinfo(void); +void rsock_init_sockopt(void); +void rsock_init_socket_init(void); #endif Index: mvm/ext/socket/udpsocket.c =================================================================== --- mvm/ext/socket/udpsocket.c (revision 27020) +++ mvm/ext/socket/udpsocket.c (revision 27021) @@ -247,10 +247,12 @@ } /* - * UDPSocket class + * Document-class: ::UDPSocket < IPSocket + * + * UDPSocket represents a UDP/IP socket. */ void -Init_udpsocket(void) +rsock_init_udpsocket(void) { rb_cUDPSocket = rb_define_class("UDPSocket", rb_cIPSocket); rb_define_method(rb_cUDPSocket, "initialize", udp_init, -1); Index: mvm/ext/socket/init.c =================================================================== --- mvm/ext/socket/init.c (revision 27020) +++ mvm/ext/socket/init.c (revision 27021) @@ -552,18 +552,18 @@ * SocketError is the error class for socket. */ void -Init_socket_init() +rsock_init_socket_init() { rb_eSocket = rb_define_class("SocketError", rb_eStandardError); - Init_ipsocket(); - Init_tcpsocket(); - Init_tcpserver(); - Init_sockssocket(); - Init_udpsocket(); - Init_unixsocket(); - Init_unixserver(); - Init_sockopt(); - Init_ancdata(); - Init_addrinfo(); - Init_socket_constants(); + rsock_init_ipsocket(); + rsock_init_tcpsocket(); + rsock_init_tcpserver(); + rsock_init_sockssocket(); + rsock_init_udpsocket(); + rsock_init_unixsocket(); + rsock_init_unixserver(); + rsock_init_sockopt(); + rsock_init_ancdata(); + rsock_init_addrinfo(); + rsock_init_socket_constants(); } Index: mvm/ext/socket/option.c =================================================================== --- mvm/ext/socket/option.c (revision 27020) +++ mvm/ext/socket/option.c (revision 27021) @@ -148,7 +148,7 @@ * * Creates a new Socket::Option object which contains an int as data. * - * The size and endian is dependent on the host. + * The size and endian is dependent on the platform. * * p Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1) * #=> #<Socket::Option: INET SOCKET KEEPALIVE 1> @@ -169,7 +169,7 @@ * * Returns the data in _sockopt_ as an int. * - * The size and endian is dependent on the host. + * The size and endian is dependent on the platform. * * sockopt = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1) * p sockopt.int => 1 @@ -658,12 +658,16 @@ return rb_funcall(sockopt_data(self), rb_intern("unpack"), 1, template); } +/* + * Document-class: ::Socket::Option + * + * Socket::Option represents a socket option used by getsockopt and setsockopt + * system call. + * It contains socket family, protocol level, option name and option value. + */ void -Init_sockopt(void) +rsock_init_sockopt(void) { - /* for rdoc */ - /* rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); */ - rb_cSockOpt = rb_define_class_under(rb_cSocket, "Option", rb_cObject); rb_define_method(rb_cSockOpt, "initialize", sockopt_initialize, 4); rb_define_method(rb_cSockOpt, "family", sockopt_family_m, 0); Index: mvm/ext/socket/raddrinfo.c =================================================================== --- mvm/ext/socket/raddrinfo.c (revision 27020) +++ mvm/ext/socket/raddrinfo.c (revision 27021) @@ -2116,7 +2116,7 @@ * Addrinfo class */ void -Init_addrinfo(void) +rsock_init_addrinfo(void) { rb_cAddrinfo = rb_define_class("Addrinfo", rb_cData); rb_define_alloc_func(rb_cAddrinfo, addrinfo_s_allocate); Index: mvm/ext/socket/unixserver.c =================================================================== --- mvm/ext/socket/unixserver.c (revision 27020) +++ mvm/ext/socket/unixserver.c (revision 27021) @@ -136,10 +136,12 @@ #endif /* - * UNIXServer class + * Document-class: ::UNIXServer < UNIXSocket + * + * UNIXServer represents a UNIX domain stream server socket. */ void -Init_unixserver(void) +rsock_init_unixserver(void) { #ifdef HAVE_SYS_UN_H rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket); @@ -147,5 +149,6 @@ rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0); rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0); + rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */ #endif } Index: mvm/ext/socket/.document =================================================================== --- mvm/ext/socket/.document (revision 0) +++ mvm/ext/socket/.document (revision 27021) @@ -0,0 +1,16 @@ +init.c +raddrinfo.c +basicsocket.c +ipsocket.c +tcpsocket.c +tcpserver.c +sockssocket.c +udpsocket.c +unixsocket.c +unixserver.c +socket.c +option.c +ancdata.c +constants.c +constdefs.c +lib/socket.rb Index: mvm/ext/socket/constants.c =================================================================== --- mvm/ext/socket/constants.c (revision 27020) +++ mvm/ext/socket/constants.c (revision 27021) @@ -138,9 +138,8 @@ * Socket::Constants module */ void -Init_socket_constants(void) +rsock_init_socket_constants(void) { /* constants */ - rb_mSockConst = rb_define_module_under(rb_cSocket, "Constants"); init_constants(); } Index: mvm/ext/socket/tcpserver.c =================================================================== --- mvm/ext/socket/tcpserver.c (revision 27020) +++ mvm/ext/socket/tcpserver.c (revision 27021) @@ -129,14 +129,17 @@ } /* - * TCPServer class + * Document-class: ::TCPServer < TCPSocket + * + * TCPServer represents a TCP/IP server socket. */ void -Init_tcpserver(void) +rsock_init_tcpserver(void) { rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket); rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0); rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, 0); rb_define_method(rb_cTCPServer, "sysaccept", tcp_sysaccept, 0); rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1); + rb_define_method(rb_cTCPServer, "listen", rsock_sock_listen, 1); /* in socket.c */ } Index: mvm/ext/socket/ipsocket.c =================================================================== --- mvm/ext/socket/ipsocket.c (revision 27020) +++ mvm/ext/socket/ipsocket.c (revision 27021) @@ -264,7 +264,7 @@ * call-seq: * IPSocket.getaddress(host) => ipaddress * - * Lookups IP address of _host_. + * Lookups the IP address of _host_. * * IPSocket.getaddress("localhost") #=> "127.0.0.1" * IPSocket.getaddress("ip6-localhost") #=> "::1" @@ -284,10 +284,12 @@ } /* - * IPSocket class + * Document-class: ::IPSocket < BasicSocket + * + * IPSocket is the super class of TCPSocket and UDPSocket. */ void -Init_ipsocket(void) +rsock_init_ipsocket(void) { rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket); rb_define_method(rb_cIPSocket, "addr", ip_addr, -1); Index: mvm/ext/socket/lib/socket.rb =================================================================== --- mvm/ext/socket/lib/socket.rb (revision 27020) +++ mvm/ext/socket/lib/socket.rb (revision 27021) @@ -58,14 +58,14 @@ # The socket is returned otherwise. # # Addrinfo.tcp("www.ruby-lang.org", 80).connect_from("0.0.0.0", 4649) {|s| - # s.print "GET / HTTP/1.0\r\n\r\n" - # p s.read + # s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" + # puts s.read # } # # # Addrinfo object can be taken for the argument. # Addrinfo.tcp("www.ruby-lang.org", 80).connect_from(Addrinfo.tcp("0.0.0.0", 4649)) {|s| - # s.print "GET / HTTP/1.0\r\n\r\n" - # p s.read + # s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" + # puts s.read # } # def connect_from(*local_addr_args, &block) @@ -78,8 +78,8 @@ # The socket is returned otherwise. # # Addrinfo.tcp("www.ruby-lang.org", 80).connect {|s| - # s.print "GET / HTTP/1.0\r\n\r\n" - # p s.read + # s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" + # puts s.read # } # def connect(&block) @@ -92,8 +92,8 @@ # The socket is returned otherwise. # # Addrinfo.tcp("0.0.0.0", 4649).connect_to("www.ruby-lang.org", 80) {|s| - # s.print "GET / HTTP/1.0\r\n\r\n" - # p s.read + # s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" + # puts s.read # } # def connect_to(*remote_addr_args, &block) @@ -158,7 +158,7 @@ end end -class BasicSocket +class BasicSocket < IO # Returns an address of the socket suitable for connect in the local machine. # # This method returns _self_.local_address, except following condition. @@ -200,7 +200,7 @@ end end -class Socket +class Socket < BasicSocket # enable the socket option IPV6_V6ONLY if IPV6_V6ONLY is available. def ipv6only! if defined? Socket::IPV6_V6ONLY @@ -220,9 +220,9 @@ # If no block is given, the socket is returned. # # Socket.tcp("www.ruby-lang.org", 80) {|sock| - # sock.print "GET / HTTP/1.0\r\n\r\n" + # sock.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" # sock.close_write - # print sock.read + # puts sock.read # } # def self.tcp(host, port, local_host=nil, local_port=nil) # :yield: socket @@ -268,6 +268,7 @@ end end + # :stopdoc: def self.ip_sockets_port0(ai_list, reuseaddr) begin sockets = [] @@ -317,6 +318,7 @@ class << self private :tcp_server_sockets_port0 end + # :startdoc: # creates TCP/IP server sockets for _host_ and _port_. # _host_ is optional. @@ -681,7 +683,7 @@ end end - # creates UNIX server sockets on _path_ + # creates a UNIX server socket on _path_ # # If no block given, it returns a listening socket. # Index: mvm/ext/socket/mkconstants.rb =================================================================== --- mvm/ext/socket/mkconstants.rb (revision 27020) +++ mvm/ext/socket/mkconstants.rb (revision 27021) @@ -83,7 +83,9 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(make_value, name, default_value)") #if defined(<%=name%>) + /* <%=name%>: */ rb_define_const(rb_cSocket, <%=c_str name%>, <%=make_value%>(<%=name%>)); + /* <%=name%>: */ rb_define_const(rb_mSockConst, <%=c_str name%>, <%=make_value%>(<%=name%>)); #endif EOS @@ -272,12 +274,19 @@ <%= INTERN_DEFS.map {|vardef, gen_hash, decl, func| vardef }.join("\n") %> +/* + * Document-module: ::Socket::Constants + * + * Socket::Constants provides socket related constants. + * Following lists possible constants. + * If underlying platform doesn't define a constant, + * the corresponding Ruby constant is not defined. + * + */ static void init_constants(void) { - /* for rdoc */ - /* rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); */ - /* rb_mSockConst = rb_define_module_under(rb_cSocket, "Constants"); */ + rb_mSockConst = rb_define_module_under(rb_cSocket, "Constants"); <%= gen_const_defs %> <%= INTERN_DEFS.map {|vardef, gen_hash, decl, func| gen_hash }.join("\n") %> Index: mvm/ext/socket/socket.c =================================================================== --- mvm/ext/socket/socket.c (revision 27020) +++ mvm/ext/socket/socket.c (revision 27021) @@ -134,13 +134,13 @@ /* * call-seq: - * socket.connect(server_sockaddr) => 0 + * socket.connect(remote_sockaddr) => 0 * - * Requests a connection to be made on the given +server_sockaddr+. Returns 0 if + * Requests a connection to be made on the given +remote_sockaddr+. Returns 0 if * successful, otherwise an exception is raised. * * === Parameter - * * +server_sockaddr+ - the +struct+ sockaddr contained in a string + * * +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object * * === Example: * # Pull down Google's web page @@ -263,14 +263,14 @@ /* * call-seq: - * socket.connect_nonblock(server_sockaddr) => 0 + * socket.connect_nonblock(remote_sockaddr) => 0 * - * Requests a connection to be made on the given +server_sockaddr+ after + * Requests a connection to be made on the given +remote_sockaddr+ after * O_NONBLOCK is set for the underlying file descriptor. * Returns 0 if successful, otherwise an exception is raised. * * === Parameter - * * +server_sockaddr+ - the +struct+ sockaddr contained in a string + * * +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object * * === Example: * # Pull down Google's web page @@ -325,15 +325,22 @@ /* * call-seq: - * socket.bind(server_sockaddr) => 0 + * socket.bind(local_sockaddr) => 0 * - * Binds to the given +struct+ sockaddr. + * Binds to the given local address. * * === Parameter - * * +server_sockaddr+ - the +struct+ sockaddr contained in a string + * * +local_sockaddr+ - the +struct+ sockaddr contained in a string or an Addrinfo object * * === Example * require 'socket' + * + * # use Addrinfo + * socket = Socket.new(:INET, :STREAM, 0) + * socket.bind(Addrinfo.tcp("127.0.0.1", 2222)) + * p socket.local_address #=> #<Addrinfo: 127.0.0.1:2222 TCP> + * + * # use struct sockaddr * include Socket::Constants * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) @@ -485,8 +492,8 @@ * * listen manual pages on unix-based systems * * listen function in Microsoft's Winsock functions reference */ -static VALUE -sock_listen(VALUE sock, VALUE log) +VALUE +rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog; @@ -507,11 +514,11 @@ * * Receives up to _maxlen_ bytes from +socket+. _flags_ is zero or more * of the +MSG_+ options. The first element of the results, _mesg_, is the data - * received. The second element, _sender_addrinfo_, contains protocol-specific information - * on the sender. + * received. The second element, _sender_addrinfo_, contains protocol-specific + * address information of the sender. * * === Parameters - * * +maxlen+ - the number of bytes to receive from the socket + * * +maxlen+ - the maximum number of bytes to receive from the socket * * +flags+ - zero or more of the +MSG_+ options * * === Example @@ -620,15 +627,15 @@ * O_NONBLOCK is set for the underlying file descriptor. * _flags_ is zero or more of the +MSG_+ options. * The first element of the results, _mesg_, is the data received. - * The second element, _sender_addrinfo_, contains protocol-specific information - * on the sender. + * The second element, _sender_addrinfo_, contains protocol-specific address + * information of the sender. * * When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns * an empty string as data. * The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc. * * === Parameters - * * +maxlen+ - the number of bytes to receive from the socket + * * +maxlen+ - the maximum number of bytes to receive from the socket * * +flags+ - zero or more of the +MSG_+ options * * === Example @@ -689,7 +696,7 @@ * serv = Socket.new(:INET, :STREAM, 0) * serv.listen(5) * c = Socket.new(:INET, :STREAM, 0) - * c.connect(serv.local_address) + * c.connect(serv.connect_address) * p serv.accept #=> [#<Socket:fd 6>, #<Addrinfo: 127.0.0.1:48555 TCP>] * */ @@ -830,10 +837,10 @@ * * Returns the hostname. * - * Note that it is not guaranteed to be able to convert to IP address using gethostbyname, getaddrinfo, etc. - * * p Socket.gethostname #=> "hal" * + * Note that it is not guaranteed to be able to convert to IP address using gethostbyname, getaddrinfo, etc. + * If you need local IP address, use Socket.ip_address_list. */ static VALUE sock_gethostname(VALUE obj) @@ -1097,6 +1104,8 @@ * +true+, +:hostname+: hostname is obtained from numeric address using reverse lookup, which may take a time. * +false+, +:numeric+: hostname is same as numeric address. * +nil+: obey to the current +do_not_reverse_lookup+ flag. + * + * If Addrinfo object is preferred, use Addrinfo.getaddrinfo. */ static VALUE sock_s_getaddrinfo(int argc, VALUE *argv) @@ -1147,6 +1156,8 @@ * Socket.getnameinfo(Socket.sockaddr_in(80, "127.0.0.1")) #=> ["localhost", "www"] * Socket.getnameinfo(["AF_INET", 80, "127.0.0.1"]) #=> ["localhost", "www"] * Socket.getnameinfo(["AF_INET", 80, "localhost", "127.0.0.1"]) #=> ["localhost", "www"] + * + * If Addrinfo object is preferred, use Addrinfo#getnameinfo. */ static VALUE sock_s_getnameinfo(int argc, VALUE *argv) @@ -1780,12 +1791,15 @@ #endif /* + * Document-class: ::Socket < BasicSocket + * * Class +Socket+ provides access to the underlying operating system * socket implementations. It can be used to provide more operating system - * specific functionality than the protocol-specific socket classes but at the - * expense of greater complexity. In particular, the class handles addresses - * using +struct+ sockaddr structures packed into Ruby strings, which can be - * a joy to manipulate. + * specific functionality than the protocol-specific socket classes. + * + * The constants defined under Socket::Constants are also defined under Socket. + * For example, Socket::AF_INET is usable as well as Socket::Constants::AF_INET. + * See Socket::Constants for the list of constants. * * === Exception Handling * Ruby's implementation of +Socket+ causes an exception to be raised @@ -1795,6 +1809,15 @@ * information on particular exception is needed please refer to the * Unix manual pages or the Windows WinSock reference. * + * === Convenient methods + * + * Although the general way to create socket is Socket.new, + * there are several methods for socket creation for most cases. + * + * * TCP client socket: Socket.tcp, TCPSocket.open + * * TCP server socket: Socket.tcp_server_loop, TCPServer.open + * * UNIX client socket: Socket.unix, UNIXSocket.open + * * UNIX server socket: Socket.unix_server_loop, UNIXServer.open * * === Documentation by * * Zach Dennis @@ -1807,17 +1830,17 @@ void Init_socket() { - Init_basicsocket(); + rsock_init_basicsocket(); rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); - Init_socket_init(); + rsock_init_socket_init(); rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); rb_define_method(rb_cSocket, "connect", sock_connect, 1); rb_define_method(rb_cSocket, "connect_nonblock", sock_connect_nonblock, 1); rb_define_method(rb_cSocket, "bind", sock_bind, 1); - rb_define_method(rb_cSocket, "listen", sock_listen, 1); + rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1); rb_define_method(rb_cSocket, "accept", sock_accept, 0); rb_define_method(rb_cSocket, "accept_nonblock", sock_accept_nonblock, 0); rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0); @@ -1844,10 +1867,4 @@ #endif rb_define_singleton_method(rb_cSocket, "ip_address_list", socket_s_ip_address_list, 0); - - /* defined here for rdoc */ - rb_define_method(rb_cTCPServer, "listen", sock_listen, 1); -#ifdef HAVE_SYS_UN_H - rb_define_method(rb_cUNIXServer, "listen", sock_listen, 1); -#endif } Index: mvm/ext/socket/basicsocket.c =================================================================== --- mvm/ext/socket/basicsocket.c (revision 27020) +++ mvm/ext/socket/basicsocket.c (revision 27021) @@ -89,7 +89,7 @@ * call-seq: * basicsocket.close_read => nil * - * Disallows further read. + * Disallows further read using shutdown system call. * * s1, s2 = UNIXSocket.pair * s1.close_read @@ -117,7 +117,7 @@ * call-seq: * basicsocket.close_write => nil * - * Disallows further write. + * Disallows further write using shutdown system call. * * UNIXSocket.pair {|s1, s2| * s1.print "ping" @@ -198,7 +198,8 @@ * }; * * In this case #setsockopt could be called like this: - * optval = IPAddr.new("224.0.0.251").hton + IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton + * optval = IPAddr.new("224.0.0.251").hton + + * IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton * sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval) * */ @@ -263,7 +264,7 @@ * * Gets a socket option. These are protocol and system specific, see your * local system documentation for details. The option is returned as - * a Socket::Option. + * a Socket::Option object. * * === Parameters * * +level+ is an integer, usually one of the SOL_ constants such as @@ -348,6 +349,9 @@ * TCPServer.open("127.0.0.1", 15120) {|serv| * p serv.getsockname #=> "\x02\x00;\x10\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" * } + * + * If Addrinfo object is preferred over the binary string, + * use BasicSocket#local_address. */ static VALUE bsock_getsockname(VALUE sock) @@ -374,6 +378,9 @@ * p s.getpeername #=> "\x02\x00\x82u\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" * } * + * If Addrinfo object is preferred over the binary string, + * use BasicSocket#remote_address. + * */ static VALUE bsock_getpeername(VALUE sock) @@ -454,6 +461,10 @@ * * Note that addrinfo.protocol is filled by 0. * + * TCPSocket.open("www.ruby-lang.org", 80) {|s| + * p s.local_address #=> #<Addrinfo: 192.168.0.129:36873 TCP> + * } + * * TCPServer.open("127.0.0.1", 1512) {|serv| * p serv.local_address #=> #<Addrinfo: 127.0.0.1:1512 TCP> * } @@ -480,6 +491,10 @@ * * Note that addrinfo.protocol is filled by 0. * + * TCPSocket.open("www.ruby-lang.org", 80) {|s| + * p s.remote_address #=> #<Addrinfo: 221.186.184.68:80 TCP> + * } + * * TCPServer.open("127.0.0.1", 1728) {|serv| * c = TCPSocket.new("127.0.0.1", 1728) * s = serv.accept @@ -502,7 +517,7 @@ /* * call-seq: - * basicsocket.send(mesg, flags [, sockaddr_to]) => numbytes_sent + * basicsocket.send(mesg, flags [, dest_sockaddr]) => numbytes_sent * * send _mesg_ via _basicsocket_. * @@ -510,7 +525,7 @@ * * _flags_ should be a bitwise OR of Socket::MSG_* constants. * - * _sockaddr_to_ should be a packed sockaddr string or an addrinfo. + * _dest_sockaddr_ should be a packed sockaddr string or an addrinfo. * * TCPSocket.open("localhost", 80) {|s| * s.send "GET / HTTP/1.0\r\n\r\n", 0 @@ -718,10 +733,10 @@ } /* - * BasicSocket class + * BasicSocket is the super class for the all socket classes. */ void -Init_basicsocket(void) +rsock_init_basicsocket(void) { rb_cBasicSocket = rb_define_class("BasicSocket", rb_cIO); rb_undef_method(rb_cBasicSocket, "initialize"); @@ -747,4 +762,10 @@ rb_define_method(rb_cBasicSocket, "recv_nonblock", bsock_recv_nonblock, -1); rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup", bsock_do_not_reverse_lookup, 0); rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup=", bsock_do_not_reverse_lookup_set, 1); + + rb_define_method(rb_cBasicSocket, "sendmsg", rsock_bsock_sendmsg, -1); /* in ancdata.c */ + rb_define_method(rb_cBasicSocket, "sendmsg_nonblock", rsock_bsock_sendmsg_nonblock, -1); /* in ancdata.c */ + rb_define_method(rb_cBasicSocket, "recvmsg", rsock_bsock_recvmsg, -1); /* in ancdata.c */ + rb_define_method(rb_cBasicSocket, "recvmsg_nonblock", rsock_bsock_recvmsg_nonblock, -1); /* in ancdata.c */ + } Index: mvm/ext/socket/ancdata.c =================================================================== --- mvm/ext/socket/ancdata.c (revision 27020) +++ mvm/ext/socket/ancdata.c (revision 27021) @@ -1325,13 +1325,13 @@ * sock.sendmsg("\0", 0, nil, ancdata) * */ -static VALUE -bsock_sendmsg(int argc, VALUE *argv, VALUE sock) +VALUE +rsock_bsock_sendmsg(int argc, VALUE *argv, VALUE sock) { return bsock_sendmsg_internal(argc, argv, sock, 0); } #else -#define bsock_sendmsg rb_f_notimplement +#define rsock_bsock_sendmsg rb_f_notimplement #endif #if defined(HAVE_SENDMSG) @@ -1346,8 +1346,8 @@ * and it doesn't retry the system call. * */ -static VALUE -bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock) +VALUE +rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock) { return bsock_sendmsg_internal(argc, argv, sock, 1); } @@ -1737,13 +1737,13 @@ * } * */ -static VALUE -bsock_recvmsg(int argc, VALUE *argv, VALUE sock) +VALUE +rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock) { return bsock_recvmsg_internal(argc, argv, sock, 0); } #else -#define bsock_recvmsg rb_f_notimplement +#define rsock_bsock_recvmsg rb_f_notimplement #endif #if defined(HAVE_RECVMSG) @@ -1758,27 +1758,25 @@ * and it doesn't retry the system call. * */ -static VALUE -bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock) +VALUE +rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock) { return bsock_recvmsg_internal(argc, argv, sock, 1); } #else -#define bsock_recvmsg_nonblock rb_f_notimplement +#define rsock_bsock_recvmsg_nonblock rb_f_notimplement #endif +/* + * Document-class: ::Socket::AncillaryData + * + * Socket::AncillaryData represents the ancillary data (control information) + * used by sendmsg and recvmsg system call. + * It contains socket family, cmsg level, cmsg type and cmsg data. + */ void -Init_ancdata(void) +rsock_init_ancdata(void) { - /* for rdoc */ - /* rb_cBasicSocket = rb_define_class("BasicSocket", rb_cIO); */ - /* rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); */ - - rb_define_method(rb_cBasicSocket, "sendmsg", bsock_sendmsg, -1); - rb_define_method(rb_cBasicSocket, "sendmsg_nonblock", bsock_sendmsg_nonblock, -1); - rb_define_method(rb_cBasicSocket, "recvmsg", bsock_recvmsg, -1); - rb_define_method(rb_cBasicSocket, "recvmsg_nonblock", bsock_recvmsg_nonblock, -1); - #if defined(HAVE_ST_MSG_CONTROL) rb_cAncillaryData = rb_define_class_under(rb_cSocket, "AncillaryData", rb_cObject); rb_define_method(rb_cAncillaryData, "initialize", ancillary_initialize, 4); Index: mvm/ext/socket/sockssocket.c =================================================================== --- mvm/ext/socket/sockssocket.c (revision 27020) +++ mvm/ext/socket/sockssocket.c (revision 27021) @@ -41,10 +41,12 @@ #endif /* + * Document-class: ::SOCKSSocket < TCPSocket + * * SOCKSSocket class */ void -Init_sockssocket(void) +rsock_init_sockssocket(void) { #ifdef SOCKS rb_cSOCKSSocket = rb_define_class("SOCKSSocket", rb_cTCPSocket); Index: mvm/ext/socket/unixsocket.c =================================================================== --- mvm/ext/socket/unixsocket.c (revision 27020) +++ mvm/ext/socket/unixsocket.c (revision 27021) @@ -485,10 +485,12 @@ #endif /* - * UNIXSocket class + * Document-class: ::UNIXSocket < BasicSocket + * + * UNIXSocket represents a UNIX domain stream client socket. */ void -Init_unixsocket(void) +rsock_init_unixsocket(void) { #ifdef HAVE_SYS_UN_H rb_cUNIXSocket = rb_define_class("UNIXSocket", rb_cBasicSocket); Index: mvm/NEWS =================================================================== --- mvm/NEWS (revision 27020) +++ mvm/NEWS (revision 27021) @@ -96,6 +96,11 @@ * New method: * MatchData#== + * Proc + * extended method: + * Proc#source_location returns location even if receiver is a method + defined by attr_reader / attr_writer / attr_accessor. + * Process * extended methods: * Process.spawn accepts [:child, FD] for a redirect target. @@ -288,6 +293,11 @@ * SecureRandom.urlsafe_base64 * URI + * new methods: + * URI.encode_www_form + * URI.decode_www_form + * URI.encode_www_form_component + * URI.decode_www_form_component * Obsoleted methods: * URI#escape * URI#unescape Index: mvm/.merged-trunk-revision =================================================================== --- mvm/.merged-trunk-revision (revision 27020) +++ mvm/.merged-trunk-revision (revision 27021) @@ -1 +1 @@ -26967 +27020 Index: mvm/version.c =================================================================== --- mvm/version.c (revision 27020) +++ mvm/version.c (revision 27021) @@ -26,8 +26,11 @@ #define RUBY_THINARCH RUBY_PLATFORM_CPU"-"RUBY_PLATFORM_OS #endif #ifndef RUBY_LIB_PREFIX -#error RUBY_LIB_PREFIX must be defined +#ifndef RUBY_EXEC_PREFIX +#error RUBY_EXEC_PREFIX must be defined #endif +#define RUBY_LIB_PREFIX RUBY_EXEC_PREFIX"/lib/ruby" +#endif #ifndef RUBY_SITE_LIB #define RUBY_SITE_LIB RUBY_LIB_PREFIX"/site_ruby" #endif Index: mvm/version.h =================================================================== --- mvm/version.h (revision 27020) +++ mvm/version.h (revision 27021) @@ -1,5 +1,5 @@ #define RUBY_VERSION "1.9.2" -#define RUBY_RELEASE_DATE "2010-03-18" +#define RUBY_RELEASE_DATE "2010-03-23" #define RUBY_PATCHLEVEL -1 #define RUBY_BRANCH_NAME "mvm" @@ -8,7 +8,7 @@ #define RUBY_VERSION_TEENY 1 #define RUBY_RELEASE_YEAR 2010 #define RUBY_RELEASE_MONTH 3 -#define RUBY_RELEASE_DAY 18 +#define RUBY_RELEASE_DAY 23 #include "ruby/version.h" Index: mvm/vm_insnhelper.c =================================================================== --- mvm/vm_insnhelper.c (revision 27020) +++ mvm/vm_insnhelper.c (revision 27021) @@ -504,7 +504,7 @@ if (num != 1) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", num); } - val = rb_ivar_set(recv, me->def->body.attr_id, *(cfp->sp - 1)); + val = rb_ivar_set(recv, me->def->body.attr.id, *(cfp->sp - 1)); cfp->sp -= 2; break; } @@ -512,7 +512,7 @@ if (num != 0) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", num); } - val = rb_attr_get(recv, me->def->body.attr_id); + val = rb_attr_get(recv, me->def->body.attr.id); cfp->sp -= 1; break; } Index: mvm/ruby.c =================================================================== --- mvm/ruby.c (revision 27020) +++ mvm/ruby.c (revision 27021) @@ -428,8 +428,9 @@ #define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), path, len) #else + static const char exec_prefix[] = RUBY_EXEC_PREFIX; #define RUBY_RELATIVE(path, len) rubylib_mangled_path(path, len) -#define PREFIX_PATH() rubylib_mangled_path(RUBY_LIB_PREFIX, sizeof(RUBY_LIB_PREFIX)-1) +#define PREFIX_PATH() rubylib_mangled_path(exec_prefix, sizeof(exec_prefix)-1) #endif load_path = GET_VM()->load_path; Index: mvm/tool/transcode-tblgen.rb =================================================================== --- mvm/tool/transcode-tblgen.rb (revision 27020) +++ mvm/tool/transcode-tblgen.rb (revision 27021) @@ -19,6 +19,17 @@ end end +class String + unless "".respond_to? :start_with? + def start_with?(*prefixes) + prefixes.each {|prefix| + return true if prefix.length <= self.length && prefix == self[0, prefix.length] + } + false + end + end +end + NUM_ELEM_BYTELOOKUP = 2 C_ESC = { @@ -168,7 +179,7 @@ if actions.length == 1 actions[0] else - actions = actions.find_all {|action| action != :nomap0 } + actions.delete(:nomap0) if actions.length == 1 actions[0] else @@ -178,7 +189,7 @@ end def self.build_tree(rects) - expand("", rects) {|prefix, actions| + expand(rects) {|prefix, actions| unambiguous_action(actions) } end @@ -199,7 +210,7 @@ all_rects.concat rects.map {|min, max, action| [min, max, [i, action]] } } - tree = expand("", all_rects) {|prefix, actions| + tree = expand(all_rects) {|prefix, actions| args = Array.new(rects_list.length) { [] } actions.each {|i, action| args[i] << action @@ -214,7 +225,46 @@ merge_rects(*mappings.map {|m| parse_to_rects(m) }, &block) end - def self.expand(prefix, rects, &block) + def self.merge2(map1, map2, &block) + rects1 = parse_to_rects(map1) + rects2 = parse_to_rects(map2) + + actions = [] + all_rects = [] + + rects1.each {|rect| + min, max, action = rect + rect[2] = actions.length + actions << action + all_rects << rect + } + + boundary = actions.length + + rects2.each {|rect| + min, max, action = rect + rect[2] = actions.length + actions << action + all_rects << rect + } + + tree = expand(all_rects) {|prefix, as0| + as1 = [] + as2 = [] + as0.each {|i| + if i < boundary + as1 << actions[i] + else + as2 << actions[i] + end + } + yield(prefix, as1, as2) + } + + self.new(tree) + end + + def self.expand(rects, &block) #numsing = numreg = 0 #rects.each {|min, max, action| if min == max then numsing += 1 else numreg += 1 end } #puts "#{numsing} singleton mappings and #{numreg} region mappings." @@ -228,49 +278,47 @@ region_rects << rect end } - expand_rec(prefix, singleton_rects, region_rects, &block) + @singleton_rects = singleton_rects.sort_by {|min, max, action| min } + @singleton_rects.reverse! + ret = expand_rec("", region_rects, &block) + @singleton_rects = nil + ret end - def self.expand_rec(prefix, singleton_rects, region_rects, &block) - some_mapping = singleton_rects[0] || region_rects[0] - return [] if !some_mapping - if some_mapping[0].empty? - h = {} - (singleton_rects + region_rects).each {|min, max, action| + TMPHASH = {} + def self.expand_rec(prefix, region_rects, &block) + return region_rects if region_rects.empty? && !((s_rect = @singleton_rects.last) && s_rect[0].start_with?(prefix)) + if region_rects.empty? ? s_rect[0].length == prefix.length : region_rects[0][0].empty? + h = TMPHASH + while (s_rect = @singleton_rects.last) && s_rect[0].start_with?(prefix) + min, max, action = @singleton_rects.pop + raise ArgumentError, "ambiguous pattern: #{prefix}" if min.length != prefix.length + h[action] = true + end + region_rects.each {|min, max, action| raise ArgumentError, "ambiguous pattern: #{prefix}" if !min.empty? h[action] = true } - actions = h.keys - act = block.call(prefix, actions) - tree = Action.new(act) + tree = Action.new(block.call(prefix, h.keys)) + h.clear else tree = [] - each_firstbyte_range(prefix, singleton_rects, region_rects) {|byte_min, byte_max, s_rects2, r_rects2| + each_firstbyte_range(prefix, region_rects) {|byte_min, byte_max, r_rects2| if byte_min == byte_max prefix2 = prefix + "%02X" % byte_min else prefix2 = prefix + "{%02X-%02X}" % [byte_min, byte_max] end - child_tree = expand_rec(prefix2, s_rects2, r_rects2, &block) + child_tree = expand_rec(prefix2, r_rects2, &block) tree << Branch.new(byte_min, byte_max, child_tree) } end return tree end - def self.each_firstbyte_range(prefix, singleton_rects, region_rects) - index_from = {} + def self.each_firstbyte_range(prefix, region_rects) + index_from = TMPHASH - singleton_ary = [] - singleton_rects.each {|seq, _, action| - raise ArgumentError, "ambiguous pattern: #{prefix}" if seq.empty? - seq_firstbyte = seq[0,2].to_i(16) - seq_rest = seq[2..-1] - singleton_ary << [seq_firstbyte, [seq_rest, seq_rest, action]] - index_from[seq_firstbyte] = true - index_from[seq_firstbyte+1] = true - } - region_ary = [] region_rects.each {|min, max, action| raise ArgumentError, "ambiguous pattern: #{prefix}" if min.empty? @@ -284,31 +332,64 @@ } byte_from = Array.new(index_from.size) - index_from.keys.sort.each_with_index {|byte, i| + bytes = index_from.keys + bytes.sort! + bytes.reverse! + bytes.each_with_index {|byte, i| index_from[byte] = i byte_from[i] = byte } - singleton_rects_hash = {} - singleton_ary.each {|seq_firstbyte, rest_elt| - i = index_from[seq_firstbyte] - (singleton_rects_hash[i] ||= []) << rest_elt - } - - region_rects_hash = {} + region_rects_ary = Array.new(index_from.size) { [] } region_ary.each {|min_firstbyte, max_firstbyte, rest_elt| - index_from[min_firstbyte].upto(index_from[max_firstbyte+1]-1) {|i| - (region_rects_hash[i] ||= []) << rest_elt + index_from[min_firstbyte].downto(index_from[max_firstbyte+1]+1) {|i| + region_rects_ary[i] << rest_elt } } - 0.upto(index_from.size-1) {|i| - s_rects = singleton_rects_hash[i] - r_rects = region_rects_hash[i] - if s_rects || r_rects - yield byte_from[i], byte_from[i+1]-1, (s_rects || []), (r_rects || []) + index_from.clear + + r_rects = region_rects_ary.pop + region_byte = byte_from.pop + prev_r_start = region_byte + prev_r_rects = [] + while r_rects && (s_rect = @singleton_rects.last) && (seq = s_rect[0]).start_with?(prefix) + singleton_byte = seq[prefix.length, 2].to_i(16) + min_byte = singleton_byte < region_byte ? singleton_byte : region_byte + if prev_r_start < min_byte && !prev_r_rects.empty? + yield prev_r_start, min_byte-1, prev_r_rects end - } + if region_byte < singleton_byte + prev_r_start = region_byte + prev_r_rects = r_rects + r_rects = region_rects_ary.pop + region_byte = byte_from.pop + elsif region_byte > singleton_byte + yield singleton_byte, singleton_byte, prev_r_rects + prev_r_start = singleton_byte+1 + else # region_byte == singleton_byte + prev_r_start = region_byte+1 + prev_r_rects = r_rects + r_rects = region_rects_ary.pop + region_byte = byte_from.pop + yield singleton_byte, singleton_byte, prev_r_rects + end + end + + while r_rects + if prev_r_start < region_byte && !prev_r_rects.empty? + yield prev_r_start, region_byte-1, prev_r_rects + end + prev_r_start = region_byte + prev_r_rects = r_rects + r_rects = region_rects_ary.pop + region_byte = byte_from.pop + end + + while (s_rect = @singleton_rects.last) && (seq = s_rect[0]).start_with?(prefix) + singleton_byte = seq[prefix.length, 2].to_i(16) + yield singleton_byte, singleton_byte, [] + end end def initialize(tree) @@ -467,6 +548,7 @@ end offsets[byte] = o } + infomap.clear if !min min = max = 0 end @@ -505,7 +587,6 @@ end PreMemo = {} - PostMemo = {} NextName = "a" def generate_node(name_hint=nil) @@ -529,16 +610,12 @@ end } - if n = PostMemo[table] - return PreMemo[@tree] = n - end - if !name_hint name_hint = "fun_" + NextName NextName.succ! end - PreMemo[@tree] = PostMemo[table] = name_hint + PreMemo[@tree] = name_hint generate_lookup_node(name_hint, table) name_hint @@ -682,15 +759,19 @@ r end -def transcode_compile_tree(name, from, map, valid_encoding=nil) +UnspecifiedValidEncoding = Object.new + +def transcode_compile_tree(name, from, map, valid_encoding) map = encode_utf8(map) h = {} map.each {|k, v| h[k] = v unless h[k] # use first mapping } - valid_encoding = ValidEncoding[from] if valid_encoding == nil + if valid_encoding.equal? UnspecifiedValidEncoding + valid_encoding = ValidEncoding.fetch(from) + end if valid_encoding - am = ActionMap.merge(h, {valid_encoding => :undef}) {|prefix, as1, as2| + am = ActionMap.merge2(h, {valid_encoding => :undef}) {|prefix, as1, as2| a1 = as1.empty? ? nil : ActionMap.unambiguous_action(as1) a2 = as2.empty? ? nil : ActionMap.unambiguous_action(as2) if !a2 @@ -701,6 +782,7 @@ else am = ActionMap.parse(h) end + h.clear max_input = am.max_input_length defined_name = am.gennode(TRANSCODE_GENERATED_BYTES_CODE, TRANSCODE_GENERATED_WORDS_CODE, name) @@ -710,7 +792,7 @@ TRANSCODERS = [] TRANSCODE_GENERATED_TRANSCODER_CODE = '' -def transcode_tbl_only(from, to, map, valid_encoding=nil) +def transcode_tbl_only(from, to, map, valid_encoding=UnspecifiedValidEncoding) if VERBOSE_MODE if from.empty? || to.empty? STDERR.puts "converter for #{from.empty? ? to : from}" @@ -731,7 +813,7 @@ return map, tree_name, real_tree_name, max_input end -def transcode_tblgen(from, to, map, valid_encoding=nil) +def transcode_tblgen(from, to, map, valid_encoding=UnspecifiedValidEncoding) map, tree_name, real_tree_name, max_input = transcode_tbl_only(from, to, map, valid_encoding) transcoder_name = "rb_#{tree_name}" TRANSCODERS << transcoder_name @@ -835,6 +917,10 @@ {81-fe}{30-39}{81-fe}{30-39}', } +def ValidEncoding(enc) + ValidEncoding.fetch(enc) +end + def set_valid_byte_pattern(encoding, pattern_or_label) pattern = if ValidEncoding[pattern_or_label] Index: mvm/test/ruby/test_array.rb =================================================================== --- mvm/test/ruby/test_array.rb (revision 27020) +++ mvm/test/ruby/test_array.rb (revision 27021) @@ -1308,6 +1308,30 @@ end def test_uniq + a = [] + b = a.uniq + assert_equal([], a) + assert_equal([], b) + assert_not_same(a, b) + + a = [1] + b = a.uniq + assert_equal([1], a) + assert_equal([1], b) + assert_not_same(a, b) + + a = [1,1] + b = a.uniq + assert_equal([1,1], a) + assert_equal([1], b) + assert_not_same(a, b) + + a = [1,2] + b = a.uniq + assert_equal([1,2], a) + assert_equal([1,2], b) + assert_not_same(a, b) + a = @cls[ 1, 2, 3, 2, 1, 2, 3, 4, nil ] b = a.dup assert_equal(@cls[1, 2, 3, 4, nil], a.uniq) @@ -1321,7 +1345,46 @@ assert_equal(@cls[1, 2, 3], @cls[1, 2, 3].uniq) end + def test_uniq_with_block + a = [] + b = a.uniq {|v| v.even? } + assert_equal([], a) + assert_equal([], b) + assert_not_same(a, b) + + a = [1] + b = a.uniq {|v| v.even? } + assert_equal([1], a) + assert_equal([1], b) + assert_not_same(a, b) + + a = [1,3] + b = a.uniq {|v| v.even? } + assert_equal([1,3], a) + assert_equal([1], b) + assert_not_same(a, b) + end + def test_uniq! + a = [] + b = a.uniq! + assert_equal(nil, b) + + a = [1] + b = a.uniq! + assert_equal(nil, b) + + a = [1,1] + b = a.uniq! + assert_equal([1], a) + assert_equal([1], b) + assert_same(a, b) + + a = [1,2] + b = a.uniq! + assert_equal([1,2], a) + assert_equal(nil, b) + a = @cls[ 1, 2, 3, 2, 1, 2, 3, 4, nil ] assert_equal(@cls[1, 2, 3, 4, nil], a.uniq!) assert_equal(@cls[1, 2, 3, 4, nil], a) @@ -1342,6 +1405,27 @@ assert_raise(RuntimeError) { f.uniq! } end + def test_uniq_bang_with_block + a = [] + b = a.uniq! {|v| v.even? } + assert_equal(nil, b) + + a = [1] + b = a.uniq! {|v| v.even? } + assert_equal(nil, b) + + a = [1,3] + b = a.uniq! {|v| v.even? } + assert_equal([1], a) + assert_equal([1], b) + assert_same(a, b) + + a = [1,2] + b = a.uniq! {|v| v.even? } + assert_equal([1,2], a) + assert_equal(nil, b) + end + def test_unshift a = @cls[] assert_equal(@cls['cat'], a.unshift('cat')) Index: mvm/test/ruby/test_proc.rb =================================================================== --- mvm/test/ruby/test_proc.rb (revision 27020) +++ mvm/test/ruby/test_proc.rb (revision 27021) @@ -761,6 +761,31 @@ assert_equal(@@line_of_source_location_test, lineno, 'Bug #2427') end + @@line_of_attr_reader_source_location_test = __LINE__ + 3 + @@line_of_attr_writer_source_location_test = __LINE__ + 3 + @@line_of_attr_accessor_source_location_test = __LINE__ + 3 + attr_reader :attr_reader_source_location_test + attr_writer :attr_writer_source_location_test + attr_accessor :attr_accessor_source_location_test + + def test_attr_source_location + file, lineno = method(:attr_reader_source_location_test).source_location + assert_match(/^#{ Regexp.quote(__FILE__) }$/, file) + assert_equal(@@line_of_attr_reader_source_location_test, lineno) + + file, lineno = method(:attr_writer_source_location_test=).source_location + assert_match(/^#{ Regexp.quote(__FILE__) }$/, file) + assert_equal(@@line_of_attr_writer_source_location_test, lineno) + + file, lineno = method(:attr_accessor_source_location_test).source_location + assert_match(/^#{ Regexp.quote(__FILE__) }$/, file) + assert_equal(@@line_of_attr_accessor_source_location_test, lineno) + + file, lineno = method(:attr_accessor_source_location_test=).source_location + assert_match(/^#{ Regexp.quote(__FILE__) }$/, file) + assert_equal(@@line_of_attr_accessor_source_location_test, lineno) + end + def test_splat_without_respond_to def (obj = Object.new).respond_to?(m); false end [obj].each do |a, b| Index: mvm/test/ruby/test_string.rb =================================================================== --- mvm/test/ruby/test_string.rb (revision 27020) +++ mvm/test/ruby/test_string.rb (revision 27021) @@ -1364,6 +1364,15 @@ } end + def test_sum_long + s8421505 = "\xff" * 8421505 + assert_equal(127, s8421505.sum(31)) + assert_equal(2147483775, s8421505.sum(0)) + s16843010 = ("\xff" * 16843010) + assert_equal(254, s16843010.sum(32)) + assert_equal(4294967550, s16843010.sum(0)) + end + def test_swapcase assert_equal(S("hi&LOW"), S("HI&low").swapcase) end Index: mvm/test/ruby/test_io.rb =================================================================== --- mvm/test/ruby/test_io.rb (revision 27020) +++ mvm/test/ruby/test_io.rb (revision 27021) @@ -1266,6 +1266,49 @@ f.close end + def try_fdopen(fd, autoclose = true, level = 100) + if level > 0 + try_fdopen(fd, autoclose, level - 1) + GC.start + level + else + IO.for_fd(fd, autoclose: autoclose) + nil + end + end + + def test_autoclose + feature2250 = '[ruby-core:26222]' + pre = 'ft2250' + + Tempfile.new(pre) do |t| + f = IO.for_fd(t.fileno) + assert_equal(true, f.autoclose?) + f.autoclose = false + assert_equal(false, f.autoclose?) + f.close + assert_nothing_raised(Errno::EBADF) {t.close} + + t.open + f = IO.for_fd(t.fileno, autoclose: false) + assert_equal(false, f.autoclose?) + f.autoclose = true + assert_equal(true, f.autoclose?) + f.close + assert_raise(Errno::EBADF) {t.close} + end + + Tempfile.new(pre) do |t| + try_fdopen(t.fileno) + assert_raise(Errno::EBADF) {t.close} + end + + Tempfile.new(pre) do |t| + try_fdopen(f.fileno, false) + assert_nothing_raised(Errno::EBADF) {t.close} + end + end + def test_open_redirect o = Object.new def o.to_open; self; end Index: mvm/test/dl/test_cfunc.rb =================================================================== --- mvm/test/dl/test_cfunc.rb (revision 27020) +++ mvm/test/dl/test_cfunc.rb (revision 27021) @@ -50,7 +50,7 @@ def test_to_s s = @cf.to_s assert s.tainted?, 'to_s should be tainted' - assert_match(/ptr=#{sprintf("0x%x", @cf.ptr)}/, s) + assert_match(/ptr=#{sprintf("0x0*%x", @cf.ptr)}/, s) assert_match(/name='#{@cf.name}'/, s) assert_match(/type=#{@cf.ctype}/, s) end Index: mvm/test/dl/test_dl2.rb =================================================================== --- mvm/test/dl/test_dl2.rb (revision 27020) +++ mvm/test/dl/test_dl2.rb (revision 27021) @@ -1,8 +1,14 @@ require_relative 'test_base.rb' require 'dl/callback' +require 'dl/func' +require 'dl/pack' module DL class TestDL < TestBase + def ptr2num(*list) + list.pack("p*").unpack(PackInfo::PACK_MAP[TYPE_VOIDP] + "*") + end + # TODO: refactor test repetition def test_free_secure @@ -111,21 +117,21 @@ buff = "xxxx" str = "abc" cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy') - x = cfunc.call([buff,str].pack("pp").unpack("l!*")) + x = cfunc.call(ptr2num(buff,str)) assert_equal("abc\0", buff) assert_equal("abc\0", CPtr.new(x).to_s(4)) buff = "xxxx" str = "abc" cfunc = CFunc.new(@libc['strncpy'], TYPE_VOIDP, 'strncpy') - x = cfunc.call([buff,str,3].pack("ppL!").unpack("l!*")) + x = cfunc.call(ptr2num(buff,str) + [3]) assert_equal("abcx", buff) assert_equal("abcx", CPtr.new(x).to_s(4)) ptr = CPtr.malloc(4) str = "abc" cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy') - x = cfunc.call([ptr.to_i,str].pack("l!p").unpack("l!*")) + x = cfunc.call([ptr.to_i, *ptr2num(str)]) assert_equal("abc\0", ptr[0,4]) assert_equal("abc\0", CPtr.new(x).to_s(4)) end @@ -134,7 +140,7 @@ buff = "foobarbaz" cb = set_callback(TYPE_INT,2){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]} cfunc = CFunc.new(@libc['qsort'], TYPE_VOID, 'qsort') - cfunc.call([buff, buff.size, 1, cb].pack("pL!L!L!").unpack("l!*")) + cfunc.call(ptr2num(buff) + [buff.size, 1, cb]) assert_equal('aabbfoorz', buff) end Index: mvm/test/dl/test_handle.rb =================================================================== --- mvm/test/dl/test_handle.rb (revision 27020) +++ mvm/test/dl/test_handle.rb (revision 27021) @@ -22,6 +22,7 @@ end def test_static_sym + skip "DL::Handle.sym is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM assert_not_nil DL::Handle.sym('dlopen') assert_equal DL::Handle.sym('dlopen'), DL::Handle['dlopen'] end @@ -124,6 +125,7 @@ end def test_NEXT + skip "DL::Handle::NEXT is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM begin # Linux / Darwin # @@ -156,6 +158,7 @@ end def test_DEFAULT + skip "DL::Handle::DEFAULT is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM handle = DL::Handle::DEFAULT assert_not_nil handle['malloc'] end Index: mvm/test/uri/test_common.rb =================================================================== --- mvm/test/uri/test_common.rb (revision 27020) +++ mvm/test/uri/test_common.rb (revision 27021) @@ -54,12 +54,12 @@ assert_equal("%00+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \ "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E", URI.encode_www_form_component("\x00 !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~")) - assert_equal("%95%41", URI.encode_www_form_component( + assert_equal("%95A", URI.encode_www_form_component( "\x95\x41".force_encoding(Encoding::Shift_JIS))) - assert_equal("%30%42", URI.encode_www_form_component( + assert_equal("%E3%81%82", URI.encode_www_form_component( "\x30\x42".force_encoding(Encoding::UTF_16BE))) - assert_equal("%30%42", URI.encode_www_form_component( - "\x30\x42".force_encoding(Encoding::ISO_2022_JP))) + assert_equal("%1B%24B%24%22%1B%28B", URI.encode_www_form_component( + "\e$B$\"\e(B".force_encoding(Encoding::ISO_2022_JP))) end def test_decode_www_form_component @@ -67,6 +67,8 @@ URI.decode_www_form_component( "%20+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \ "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E")) + assert_equal("\xA1\xA2".force_encoding(Encoding::EUC_JP), + URI.decode_www_form_component("%A1%A2", "EUC-JP")) end def test_encode_www_form Index: mvm/test/yaml/test_hash.rb =================================================================== --- mvm/test/yaml/test_hash.rb (revision 27020) +++ mvm/test/yaml/test_hash.rb (revision 27021) @@ -14,5 +14,16 @@ def test_dump assert_equal @hash, YAML.load(YAML.dump(@hash)) end + + def test_ref_append + hash = YAML.load(<<-eoyml) +--- +foo: &foo + hello: world +bar: + <<: *foo +eoyml + assert_equal({"foo"=>{"hello"=>"world"}, "bar"=>{"hello"=>"world"}}, hash) + end end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/