ruby-changes:15064
From: nobu <ko1@a...>
Date: Mon, 15 Mar 2010 18:53:49 +0900 (JST)
Subject: [ruby-changes:15064] Ruby:r26940 (mvm): * merged from trunk r26885:26939.
nobu 2010-03-15 18:53:15 +0900 (Mon, 15 Mar 2010) New Revision: 26940 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26940 Log: * merged from trunk r26885:26939. Modified files: branches/mvm/.merged-trunk-revision branches/mvm/ChangeLog branches/mvm/NEWS branches/mvm/array.c branches/mvm/compile.c branches/mvm/enc/trans/emoji.trans branches/mvm/enc/trans/single_byte.trans branches/mvm/enum.c branches/mvm/ext/nkf/nkf-utf8/nkf.c branches/mvm/ext/tk/extconf.rb branches/mvm/ext/tk/lib/tk.rb branches/mvm/ext/tk/tkutil/tkutil.c branches/mvm/file.c branches/mvm/gem_prelude.rb branches/mvm/include/ruby/intern.h branches/mvm/include/ruby/io.h branches/mvm/io.c branches/mvm/iseq.c branches/mvm/lib/rubygems.rb branches/mvm/lib/uri/common.rb branches/mvm/lib/webrick/httpservlet/cgihandler.rb branches/mvm/load.c branches/mvm/random.c branches/mvm/ruby.c branches/mvm/symbian/README.SYMBIAN branches/mvm/symbian/configure.bat branches/mvm/symbian/setup branches/mvm/test/ruby/enc/test_emoji.rb branches/mvm/test/ruby/test_array.rb branches/mvm/test/ruby/test_enum.rb branches/mvm/test/ruby/test_file.rb branches/mvm/test/ruby/test_file_exhaustive.rb branches/mvm/test/ruby/test_io.rb branches/mvm/test/ruby/test_rand.rb branches/mvm/test/uri/test_common.rb branches/mvm/tool/compile_prelude.rb branches/mvm/tool/file2lastrev.rb branches/mvm/tool/transcode-tblgen.rb branches/mvm/version.h Index: mvm/array.c =================================================================== --- mvm/array.c (revision 26939) +++ mvm/array.c (revision 26940) @@ -1600,7 +1600,7 @@ val = tmp; goto str_join; } - tmp = rb_check_convert_type(val, T_ARRAY, "Array", "to_a"); + tmp = rb_check_convert_type(val, T_ARRAY, "Array", "to_ary"); if (!NIL_P(tmp)) { obj = val; val = tmp; Index: mvm/include/ruby/intern.h =================================================================== --- mvm/include/ruby/intern.h (revision 26939) +++ mvm/include/ruby/intern.h (revision 26940) @@ -365,6 +365,7 @@ char *rb_path_last_separator(const char *); char *rb_path_end(const char *); VALUE rb_file_directory_p(VALUE,VALUE); +int rb_is_absolute_path(const char *); /* gc.c */ void ruby_set_stack_size(size_t); NORETURN(void rb_memerror(void)); Index: mvm/include/ruby/io.h =================================================================== --- mvm/include/ruby/io.h (revision 26939) +++ mvm/include/ruby/io.h (revision 26940) @@ -101,7 +101,7 @@ #define MakeOpenFile(obj, fp) do {\ if (RFILE(obj)->fptr) {\ rb_io_close(obj);\ - free(RFILE(obj)->fptr);\ + rb_io_fptr_finalize(RFILE(obj)->fptr);\ RFILE(obj)->fptr = 0;\ }\ fp = 0;\ @@ -166,8 +166,6 @@ int rb_io_read_pending(rb_io_t*); DEPRECATED(void rb_read_check(FILE*)); -int ruby_absolute_path_p(const char*); - #if defined(__cplusplus) #if 0 { /* satisfy cc-mode */ Index: mvm/ChangeLog =================================================================== --- mvm/ChangeLog (revision 26939) +++ mvm/ChangeLog (revision 26940) @@ -1,3 +1,198 @@ +Mon Mar 15 18:33:36 2010 Nobuyoshi Nakada <nobu@r...> + + * random.c (default_rand): removed initial buffer. + + * random.c (Init_RandomSeed): initialize seed of default random. + + * random.c (Init_RandomSeed2): turn the seed to Bignum object. + +Mon Mar 15 17:28:30 2010 Yukihiro Matsumoto <matz@r...> + + * io.c (rb_io_print): RDoc update. a patch from Daniel Kelley + in [ruby-core:28643]. + +Mon Mar 15 14:06:07 2010 Nobuyoshi Nakada <nobu@r...> + + * random.c (next_state): no initialization here. + + * random.c (default_mt): always return initialized MT. + +Mon Mar 15 11:49:48 2010 NARUSE, Yui <naruse@r...> + + * random.c (rb_reset_random_seed): set seed in this. + [ruby-core:28655] + +Mon Mar 15 10:26:02 2010 NARUSE, Yui <naruse@r...> + + * ext/nkf/nkf-utf8/nkf.c: import latest nkf. [master 9306cb0] + this also fixes [ruby-dev:40607] + +Mon Mar 15 09:34:17 2010 NARUSE, Yui <naruse@r...> + + * lib/uri/common.rb (URI.encode_www_component): + call str.to_s at first. + +Mon Mar 15 09:36:22 2010 Nobuyoshi Nakada <nobu@r...> + + * symbian/README.SYMBIAN: fixed broken patch and converted to + unified diff. + +Mon Mar 15 07:51:05 2010 Nobuyoshi Nakada <nobu@r...> + + * file.c (Init_File): do not define File::ALT_SEPARATOR on cygwin. + +Mon Mar 15 07:41:00 2010 Nobuyoshi Nakada <nobu@r...> + + * file.c (realpath_rec): use same cache. + + * file.c (realpath_internal): regulate separators in prefix. + [ruby-core:28653] + + * file.c (FILE_ALT_SEPARATOR): separated condition. + +Mon Mar 15 04:41:25 2010 Nobuyoshi Nakada <nobu@r...> + + * io.c (rb_io_each_codepoint): read directly when readconv is + needed but internal encoding is not set. [ruby-core:28650] + +Mon Mar 15 04:18:31 2010 Nobuyoshi Nakada <nobu@r...> + + * tool/file2lastrev.rb (VCS::{SVN,GIT}#get_revisions): + use block argument 'path' to get the path given by super. + +Mon Mar 15 02:43:59 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (Action#hash): defined. + (Action#eql?): ditto. + (Action#==): ditto. + +Mon Mar 15 01:52:46 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: refactored. + +Mon Mar 15 01:18:31 2010 Alexander Zavorine <alexandre.zavorine@n...> + + * symbian/setup (*.pkg): Ruby Core installation separated from standard extensions. + + * symbian/configure.bat: ditto. + + * symbian/README.SYMBIAN: ditto. + + * symbian/setup (config.h): support for 2nd internal drive added. + +Mon Mar 15 00:11:23 2010 NARUSE, Yui <naruse@r...> + + * tool/file2lastrev.rb (VCS::GIT_SVN#get_revisions) : + use block argument 'path' to get the path given by super. + + * tool/file2lastrev.rb (VCS::GIT#get_revisions): + use double quotes for Windows. + patched by Vladimir Sizikov [ruby-core:28651] + +Sun Mar 14 22:38:31 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: consider valid_encoding for max_input. + +Sun Mar 14 15:46:09 2010 Tanaka Akira <akr@f...> + + * enc/trans/emoji.trans: fix nomap_table. + +Sun Mar 14 09:50:03 2010 Nobuyoshi Nakada <nobu@r...> + + * compile.c (insn_data_to_s_detail), iseq.c (insn_operand_intern): + fixed format specifiers. + +Sun Mar 14 07:20:17 2010 Yukihiro Matsumoto <matz@r...> + + * file.c (EXPAND_PATH_BUFFER): make it back to usascii, to prevent + infinite loop on some platform. [ruby-dev:40629] + +Sun Mar 14 02:40:38 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: reject ambiguous mapping. + + * enc/trans/single_byte.trans: remove ambiguous maping such as + \xD6 -> U+05F2 and \xD6\xC7 -> U+FB1F in Windows-1255 + +Sat Mar 13 23:48:27 2010 Yukihiro Matsumoto <matz@r...> + + * file.c (file_expand_path): should not just copy the encoding + from fname. [ruby-core:28635] + + * file.c (EXPAND_PATH_BUFFER): set filesystem_encoding, not + usascii for path buffer. + +Sat Mar 13 17:48:43 2010 Nobuyoshi Nakada <nobu@r...> + + * tool/file2lastrev.rb: refactord. fixed changed revision of git. + +Sat Mar 13 15:44:20 2010 Yukihiro Matsumoto <matz@r...> + + * io.c (rb_io_print): should not print field separator at the end + of arguments. [ruby-talk:358633] + +Sat Mar 13 14:49:55 2010 Yukihiro Matsumoto <matz@r...> + + * enum.c (enum_join): remove Enumerable#join. [ruby-core:24786] + + * array.c (ary_join_1): use #to_ary to detect recursive array. + +Sat Mar 13 12:26:13 2010 Nobuyoshi Nakada <nobu@r...> + + * include/ruby/io.h (MakeOpenFile): finalize fptr to get rid of + memory leak. + +Sat Mar 13 11:14:26 2010 Shugo Maeda <shugo@r...> + + * load.c (rb_get_expanded_load_path): expand paths if any item in $: + is not a string. + +Sat Mar 13 10:16:32 2010 Shugo Maeda <shugo@r...> + + * load.c (rb_get_expanded_load_path): does not expand paths if all + the items in $: are absolute paths. [ruby-core:28113] + +Sat Mar 13 10:03:52 2010 Hidetoshi NAGAI <nagai@a...> + + * ext/tk/extconf.rb: fix [Bug #2840] Tk doesn't built in mingw. + +Sat Mar 13 03:24:15 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: show consumed time at last. + +Sat Mar 13 00:44:20 2010 Nobuyoshi Nakada <nobu@r...> + + * file.c (rb_file_s_basename): check encoding of suffix. + +Sat Mar 13 00:11:05 2010 Nobuyoshi Nakada <nobu@r...> + + * ruby.c (ruby_init_loadpath_safe): mark initial load paths. + + * gem_prelude.rb (push_all_highest_version_gems_on_load_path): + search insertion position by initial load path mark. + + * lib/rubygems.rb (Gem.load_path_insert_index): ditto. + +Fri Mar 12 21:34:00 2010 Kenta Murata <mrkn@m...> + + * NEWS: emoji encodings. + +Fri Mar 12 17:14:12 2010 NARUSE, Yui <naruse@r...> + + * lib/uri/common.rb (URI.encode_www_form): new method to + generate URL-encoded form data. [ruby-dev:39246] + + * lib/uri/common.rb (URI.encode_www_component, + URI.decode_www_component): new method for encode/decode + a name/value of HTML form. + +Fri Mar 12 17:36:35 2010 NARUSE, Yui <naruse@r...> + + * lib/webrick/httpservlet/cgihandler.rb + (WEBrick::HTTPServlet::CGIHandler#do_GET): + set binary mode for tempfile. + http://pc12.2ch.net/test/read.cgi/tech/1265467681/286 + Fri Mar 12 13:52:00 2010 Kenta Murata <mrkn@m...> * tool/compile_prelude.rb: TMP_RUBY_PREFIX should replace Index: mvm/gem_prelude.rb =================================================================== --- mvm/gem_prelude.rb (revision 26939) +++ mvm/gem_prelude.rb (revision 26940) @@ -267,7 +267,7 @@ require_paths.first.instance_variable_set(:@gem_prelude_index, true) end # gem directories must come after -I and ENV['RUBYLIB'] - $:[$:.index(ConfigMap[:sitelibdir]),0] = require_paths + $:[$:.index{|e|e.instance_variable_defined?(:@gem_prelude_index)}||-1,0] = require_paths end def const_missing(constant) Index: mvm/enc/trans/emoji.trans =================================================================== --- mvm/enc/trans/emoji.trans (revision 26939) +++ mvm/enc/trans/emoji.trans (revision 26940) @@ -6,7 +6,7 @@ nomap_table = [ ["{00-7f}", :nomap], ["{c2-df}{80-bf}", :nomap0], - ["e0{a0-df}{80-bf}", :nomap0], + ["e0{a0-bf}{80-bf}", :nomap0], ["{e1-ec}{80-bf}{80-bf}", :nomap0], ["ed{80-9f}{80-bf}", :nomap0], ["{ee-ef}{80-bf}{80-bf}", :nomap0], Index: mvm/enc/trans/single_byte.trans =================================================================== --- mvm/enc/trans/single_byte.trans (revision 26939) +++ mvm/enc/trans/single_byte.trans (revision 26940) @@ -24,7 +24,7 @@ tbl_to_ucs = control1_if_needed + eval(name.gsub(/-/, '_') + "_TO_UCS_TBL") set_valid_byte_pattern(name, '1byte') code = '' - code << transcode_tblgen(name, "UTF-8", [["{00-7f}", :nomap], *tbl_to_ucs]) + code << transcode_tblgen(name, "UTF-8", [["{00-7f}", :nomap], *tbl_to_ucs.reject {|a, b| a.length != 2 }]) code << "\n" code << transcode_tblgen("UTF-8", name, [["{00-7f}", :nomap], *tbl_to_ucs.map {|a,b| [b,a] }]) code Index: mvm/iseq.c =================================================================== --- mvm/iseq.c (revision 26939) +++ mvm/iseq.c (revision 26940) @@ -795,7 +795,7 @@ break; case TS_IC: - ret = rb_sprintf("<ic:%d>", (struct iseq_inline_cache_entry *)op - iseq->ic_entries); + ret = rb_sprintf("<ic:%"PRIdPTRDIFF">", (struct iseq_inline_cache_entry *)op - iseq->ic_entries); break; case TS_CDHASH: Index: mvm/enum.c =================================================================== --- mvm/enum.c (revision 26939) +++ mvm/enum.c (revision 26940) @@ -1333,7 +1333,7 @@ /* * call-seq: - * enum.min_by {| obj| block } => obj + * enum.min_by {|obj| block } => obj * * Returns the object in <i>enum</i> that gives the minimum * value from the given block. @@ -1376,7 +1376,7 @@ /* * call-seq: - * enum.max_by {| obj| block } => obj + * enum.max_by {|obj| block } => obj * * Returns the object in <i>enum</i> that gives the maximum * value from the given block. @@ -1470,7 +1470,7 @@ /* * call-seq: - * enum.minmax_by {| obj| block } => [min, max] + * enum.minmax_by {|obj| block } => [min, max] * * Returns two elements array array containing the objects in * <i>enum</i> that gives the minimum and maximum values respectively @@ -2417,15 +2417,18 @@ * * If the block needs to maintain state over multiple elements, * local variables can be used. - * For example, monotonically increasing elements can be chunked as follows. + * For example, three or more consecutive increasing numbers can be squashed + * as follows: * - * a = [3,1,4,1,5,9,2,6,5,3,5] - * n = 0 - * p a.slice_before {|elt| - * prev, n = n, elt - * prev > elt - * }.to_a - * #=> [[3], [1, 4], [1, 5, 9], [2, 6], [5], [3, 5]] + * a = [0,2,3,4,6,7,9] + * prev = a[0] + * p a.slice_before {|e| + * prev, prev2 = e, prev + * prev2 + 1 != e + * }.map {|es| + * es.length <= 2 ? es.join(",") : "#{es.first}-#{es.last}" + * }.join(",") + * #=> "0,2-4,6,7,9" * * However local variables are not appropriate to maintain state * if the result enumerator is used twice or more. @@ -2519,25 +2522,6 @@ } /* - * call-seq: - * enum.join(sep=$,) -> str - * - * Returns a string created by converting each element of the - * <i>enum</i> to a string, separated by <i>sep</i>. - */ - -static VALUE -enum_join(int argc, VALUE *argv, VALUE obj) -{ - VALUE sep; - - rb_scan_args(argc, argv, "01", &sep); - if (NIL_P(sep)) sep = rb_output_fs; - - return rb_ary_join(enum_to_a(0, 0, obj), sep); -} - -/* * The <code>Enumerable</code> mixin provides collection classes with * several traversal and searching methods, and with the ability to * sort. The class must provide a method <code>each</code>, which @@ -2612,7 +2596,6 @@ rb_define_method(rb_mEnumerable, "drop", enum_drop, 1); rb_define_method(rb_mEnumerable, "drop_while", enum_drop_while, 0); rb_define_method(rb_mEnumerable, "cycle", enum_cycle, -1); - rb_define_method(rb_mEnumerable, "join", enum_join, -1); rb_define_method(rb_mEnumerable, "chunk", enum_chunk, -1); rb_define_method(rb_mEnumerable, "slice_before", enum_slice_before, -1); } Index: mvm/io.c =================================================================== --- mvm/io.c (revision 26939) +++ mvm/io.c (revision 26940) @@ -2894,9 +2894,14 @@ rb_enc_name(fptr->encs.enc)); } n = MBCLEN_CHARFOUND_LEN(r); - c = rb_enc_codepoint(fptr->cbuf+fptr->cbuf_off, - fptr->cbuf+fptr->cbuf_off+fptr->cbuf_len, - fptr->encs.enc); + if (fptr->encs.enc) { + c = rb_enc_codepoint(fptr->cbuf+fptr->cbuf_off, + fptr->cbuf+fptr->cbuf_off+fptr->cbuf_len, + fptr->encs.enc); + } + else { + c = (unsigned char)fptr->cbuf[fptr->cbuf_off]; + } fptr->cbuf_off += n; fptr->cbuf_len -= n; rb_yield(UINT2NUM(c)); @@ -4495,7 +4500,7 @@ #if USE_OPENAT data.base = (base && base->fd != -1) ? base->fd : DEFAULT_BASE_FD; #else - if (base && !ruby_absolute_path_p(RSTRING_PTR(fname))) { + if (base && !rb_is_absolute_path(RSTRING_PTR(fname))) { VALUE fullpath = Qnil; if (base->fd != -1) { char *basecwd; @@ -5964,7 +5969,9 @@ * ios.print(obj, ...) => nil * * Writes the given object(s) to <em>ios</em>. The stream must be - * opened for writing. If the output record separator (<code>$\\</code>) + * opened for writing. If the output field separator (<code>$,</code>) + * is not <code>nil</code>, it will be inserted between each object. + * If the output record separator (<code>$\\</code>) * is not <code>nil</code>, it will be appended to the output. If no * arguments are given, prints <code>$_</code>. Objects that aren't * strings will be converted by calling their <code>to_s</code> method. @@ -5991,10 +5998,10 @@ argv = &line; } for (i=0; i<argc; i++) { - rb_io_write(out, argv[i]); - if (!NIL_P(rb_output_fs)) { + if (!NIL_P(rb_output_fs) && i>0) { rb_io_write(out, rb_output_fs); } + rb_io_write(out, argv[i]); } if (argc > 0 && !NIL_P(rb_output_rs)) { rb_io_write(out, rb_output_rs); Index: mvm/load.c =================================================================== --- mvm/load.c (revision 26939) +++ mvm/load.c (revision 26940) @@ -37,10 +37,19 @@ rb_get_expanded_load_path(void) { VALUE load_path = rb_get_load_path(); - VALUE ary = rb_ary_new2(RARRAY_LEN(load_path)); + VALUE ary; long i; for (i = 0; i < RARRAY_LEN(load_path); ++i) { + VALUE str = rb_check_string_type(RARRAY_PTR(load_path)[i]); + if (NIL_P(str) || !rb_is_absolute_path(RSTRING_PTR(str))) + goto relative_path_found; + } + return load_path; + + relative_path_found: + ary = rb_ary_new2(RARRAY_LEN(load_path)); + for (i = 0; i < RARRAY_LEN(load_path); ++i) { VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil); rb_str_freeze(path); rb_ary_push(ary, path); Index: mvm/lib/webrick/httpservlet/cgihandler.rb =================================================================== --- mvm/lib/webrick/httpservlet/cgihandler.rb (revision 26939) +++ mvm/lib/webrick/httpservlet/cgihandler.rb (revision 26940) @@ -32,9 +32,9 @@ status = -1 cgi_in = IO::popen(@cgicmd, "wb") - cgi_out = Tempfile.new("webrick.cgiout.", @tempdir) + cgi_out = Tempfile.new("webrick.cgiout.", @tempdir, mode: IO::BINARY) cgi_out.set_encoding("ASCII-8BIT") - cgi_err = Tempfile.new("webrick.cgierr.", @tempdir) + cgi_err = Tempfile.new("webrick.cgierr.", @tempdir, mode: IO::BINARY) cgi_err.set_encoding("ASCII-8BIT") begin cgi_in.sync = true Index: mvm/lib/rubygems.rb =================================================================== --- mvm/lib/rubygems.rb (revision 26939) +++ mvm/lib/rubygems.rb (revision 26940) @@ -254,8 +254,6 @@ File.join spec.full_gem_path, path end - sitelibdir = ConfigMap[:sitelibdir] - # gem directories must come after -I and ENV['RUBYLIB'] insert_index = load_path_insert_index @@ -570,23 +568,9 @@ ## # The index to insert activated gem paths into the $LOAD_PATH. - # - # Defaults to the site lib directory unless gem_prelude.rb has loaded paths, - # then it inserts the activated gem's paths before the gem_prelude.rb paths - # so you can override the gem_prelude.rb default $LOAD_PATH paths. def self.load_path_insert_index - index = $LOAD_PATH.index ConfigMap[:sitelibdir] - - $LOAD_PATH.each_with_index do |path, i| - if path.instance_variables.include?(:@gem_prelude_index) or - path.instance_variables.include?('@gem_prelude_index') then - index = i - break - end - end - - index + $LOAD_PATH.index {|path| path.instance_variable_defined?(:@gem_prelude_index)} end ## Index: mvm/lib/uri/common.rb =================================================================== --- mvm/lib/uri/common.rb (revision 26939) +++ mvm/lib/uri/common.rb (revision 26940) @@ -716,6 +716,94 @@ DEFAULT_PARSER.make_regexp(schemes) end + # :nodoc: + TBLENCWWWCOMP_ = {} + + # :nodoc: + TBLDECWWWCOMP_ = {} + + # Encode given +str+ to URL-encoded form data. + # + # This doesn't convert *, -, ., 0-9, A-Z, _, a-z, + # does convert SP to +, and convert others to %XX. + # + # This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data + # + # See URI.decode_www_component(str), URI.encode_www_form(enum) + def self.encode_www_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] = '%%%X' % i + end + end + TBLENCWWWCOMP_.freeze + end + str = str.to_s.dup + enc = str.encoding + str.force_encoding(Encoding::ASCII_8BIT) + str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_) + str.force_encoding(enc) + end + + # Decode given +str+ of URL-encoded form data. + # + # This decods + to SP. + # + # See URI.encode_www_component(str) + def self.decode_www_component(str) + if TBLDECWWWCOMP_.empty? + 256.times do |i| + case i + when 0x20 + TBLDECWWWCOMP_['+'] = ' ' + else + h, l = i>>4, i&15 + TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr + TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr + TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr + TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr + end + end + TBLDECWWWCOMP_.freeze + end + str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_) + end + + # Generate URL-encoded form data from given +enum+. + # + # This generates application/x-www-form-urlencoded data defined in HTML5 + # from given an Enumerable object. + # + # This internally uses URI.encode_www_component(str). + # + # 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. + # + # This doesn't treat files. When you send a file, use multipart/form-data. + # + # This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data + # + # See URI.encode_www_component(str) + def self.encode_www_form(enum) + str = nil + enum.each do |k,v| + if str + str << '&' + else + str = ''.force_encoding(Encoding::US_ASCII) + end + str << encode_www_component(k) + str << '=' + str << encode_www_component(v) + end + str + end end module Kernel Index: mvm/compile.c =================================================================== --- mvm/compile.c (revision 26939) +++ mvm/compile.c (revision 26940) @@ -4973,7 +4973,7 @@ for (j = 0; types[j]; j++) { char type = types[j]; - printf("str: %p, type: %c\n", str, type); + printf("str: %"PRIxVALUE", type: %c\n", str, type); switch (type) { case TS_OFFSET: /* label(destination position) */ Index: mvm/symbian/setup =================================================================== --- mvm/symbian/setup (revision 26939) +++ mvm/symbian/setup (revision 26940) @@ -187,7 +187,7 @@ @echo>>$(1) #define RUBY_LIB_VERSION_STYLE 3 @echo>>$(1) #define RUBY_LIB_PREFIX "C:/Data/Ruby/lib" @echo>>$(1) #define RUBY_SITE_LIB "E:/Data/Ruby/lib" -@echo>>$(1) #define RUBY_VENDOR_LIB "C:/Data/Ruby/lib" +@echo>>$(1) #define RUBY_VENDOR_LIB "F:/Data/Ruby/lib" @echo>>$(1) #define RUBY_PLATFORM "$(arch)" endef @@ -340,6 +340,7 @@ define ext_mmp @echo>$(1)$(2).mmp TARGET $(2).dll @echo>>$(1)$(2).mmp TARGETTYPE DLL +@echo>>$(1)$(2).mmp EPOCALLOWDLLDATA @echo>>$(1)$(2).mmp UID 0x10004262 $(3) @echo>>$(1)$(2).mmp VENDORID 0 @echo>>$(1)$(2).mmp SECUREID $(3) @@ -391,7 +392,20 @@ @echo>>$(1) "$(EPOCROOT)epoc32\release\gcce\urel\Ruby.exe"-"!:\sys\bin\Ruby.exe" endef +define core_ext_pkg +@echo>$(1) ^&EN +@echo>>$(1) #{"Ruby Core Extensions"},($(STRINGIO_UID)),$(MAJOR),$(MINOR),$(TEENY) + +@echo>>$(1) %%{"Symbian Research"} + +@echo>>$(1) :"Symbian Research" + +@echo>>$(1) ($(RUBY_UID)), $(MAJOR),$(MINOR),$(TEENY), {"Symbian Ruby"} + +@echo>>$(1) [0x101F7961], 0, 0, 0, {"S60ProductID"} +endef + define ext_pkg @echo>>$(1) "$(EPOCROOT)epoc32\release\gcce\urel\$(2).dll"-"!:\sys\bin\$(2).dll" @echo>>$(1) "$(EPOCROOT)epoc32\release\gcce\urel\$(2).dll"-"!:\Data\Ruby\lib\$(MAJOR).$(MINOR).$(TEENY)\$(arch)\$(2).dll" Index: mvm/symbian/configure.bat =================================================================== --- mvm/symbian/configure.bat (revision 26939) +++ mvm/symbian/configure.bat (revision 26940) @@ -104,9 +104,10 @@ echo>> ~tmp~.mak ^ @if not exist sis\nul md sis echo>> ~tmp~.mak ^ $(call ruby_pkg,sis\ruby.pkg) echo>> ~tmp~.mak ifndef EXTSTATIC -echo>> ~tmp~.mak ^ $(call ext_bigdecimal,sis\ruby.pkg) -echo>> ~tmp~.mak ^ $(call ext_pkg,sis\ruby.pkg,stringio) -echo>> ~tmp~.mak ^ $(call ext_pkg,sis\ruby.pkg,zlib) +echo>> ~tmp~.mak ^ $(call core_ext_pkg,sis\ruby_core_ext.pkg) +echo>> ~tmp~.mak ^ $(call ext_bigdecimal,sis\ruby_core_ext.pkg) +echo>> ~tmp~.mak ^ $(call ext_pkg,sis\ruby_core_ext.pkg,stringio) +echo>> ~tmp~.mak ^ $(call ext_pkg,sis\ruby_core_ext.pkg,zlib) echo>> ~tmp~.mak ^ @if not exist eabi\nul md eabi echo>> ~tmp~.mak ^ $(call ext_def,eabi\,stringio) echo>> ~tmp~.mak ^ $(call ext_def,eabi\,bigdecimal) Index: mvm/symbian/README.SYMBIAN =================================================================== --- mvm/symbian/README.SYMBIAN (revision 26939) +++ mvm/symbian/README.SYMBIAN (revision 26940) @@ -8,68 +8,58 @@ Note: if you want to build dynamic extensions support you need to install the latest version of GCC compiler from http://www.codesourcery.com/gnu_toolchains/arm/portal/release643. After that you need to apply a patch below to a header file (SDK_ROOT)\epoc32\include\gcce\gcce.h -11c11 -< ---- -> @released -18a19 -> -21a23 -> -24a27,29 -> #define IMPORT_D __declspec(dllimport) -> #define EXPORT_D __declspec(dllexport) -> -81,82c86,87 -< #define __NAKED__ __asm -< #define ____ONLY_USE_NAKED_IN_CIA____ __asm ---- -> #define __NAKED__ __declspec(naked) -> #define ____ONLY_USE_NAKED_IN_CIA____ __declspec(naked) -92,96c97,98 -< namespace std { -< extern "C" { -< #endif /* __cplusplus */ -< -< typedef struct __va_list { void *__ap; } va_list; ---- -> namespace std { extern "C" { -> #endif -97a100,104 -> #if __GNUC__ < 4 -> typedef struct __va_list { void *__ap; } va_list; -> #else -> typedef __builtin_va_list va_list; -> #endif -100,102c107 -< } /* extern "C" */ -< } /* namespace std */ -< ---- -> } } -105a111 -> #if __GNUC__ < 4 -107,109c113,119 -< #define va_arg(ap, type) __builtin_va_arg(ap.__ap, type) -< #define va_end(ap) __builtin_va_end(ap.__ap) -< ---- -> #define va_arg(ap, type) __builtin_va_arg(ap.__ap, type) -> #define va_end(ap) __builtin_va_end(ap.__ap) -> #else -> #define va_start(ap, parmN) __builtin_va_start(ap, parmN) -> #define va_arg(ap, type) __builtin_va_arg(ap, type) -> #define va_end(ap) __builtin_va_end(ap) -> #endif -140,141c150,152 -< // Deal with operator new issues here -< #include "../symcpp.h" ---- -> #ifndef __SYMBIAN_STDCPP_SUPPORT__ -> #include "../symcpp.h" -> #endif -151a163 -> +=================================================================== +--- Epoc32/include/gcce/gcce.h ++++ Epoc32/include/gcce/gcce.h +@@ -22,4 +22,6 @@ + #define IMPORT_C __declspec(dllimport) + #define EXPORT_C __declspec(dllexport) ++#define IMPORT_D __declspec(dllimport) ++#define EXPORT_D __declspec(dllexport) + + +@@ -79,6 +81,6 @@ + + // __NAKED__ from cpudefs.h +-#define __NAKED__ __asm +-#define ____ONLY_USE_NAKED_IN_CIA____ __asm ++#define __NAKED__ __declspec(naked) ++#define ____ONLY_USE_NAKED_IN_CIA____ __declspec(naked) + + // Int64 and Uint64 from nkern\nklib.h +@@ -94,5 +96,9 @@ + #endif /* __cplusplus */ + ++#if __GNUC__ < 4 + typedef struct __va_list { void *__ap; } va_list; ++#else ++typedef __builtin_va_list va_list; ++#endif + + +@@ -104,7 +110,13 @@ + #endif + ++#if __GNUC__ < 4 + #define va_start(ap, parmN) __builtin_va_start(ap.__ap, parmN) + #define va_arg(ap, type) __builtin_va_arg(ap.__ap, type) + #define va_end(ap) __builtin_va_end(ap.__ap) ++#else ++#define va_start(ap, parmN) __builtin_va_start(ap, parmN) ++#define va_arg(ap, type) __builtin_va_arg(ap, type) ++#define va_end(ap) __builtin_va_end(ap) ++#endif + + +@@ -139,5 +151,7 @@ + + // Deal with operator new issues here ++#ifndef __SYMBIAN_STDCPP_SUPPORT__ + #include "..\symcpp.h" ++#endif + + #ifdef __cplusplus +=================================================================== (2) If you want to build from SVN source, following command line binaries are required that are not a part of Symbain SDK. @@ -88,13 +78,16 @@ 'abld freeze gcce ruby' 'abld build gcce urel' -(3) Run `makesis ruby.pkg' from symbian\sis directory +(3) Run 'makesis ruby.pkg' from symbian\sis directory This command will create unsigned installation file ruby.sis. To sign it follow the guidlines from www.symbiansigned.com +(4) In case dynamic extensions support was enabled repeat (3) for ruby_core_ext.pkg + == Known problems Currently gems are not supported. Currently signals are supported with reduced functionality (see OpenC release notes.) +Dynamic extensions could be installed only on internal drive "C". =end Index: mvm/ext/tk/lib/tk.rb =================================================================== --- mvm/ext/tk/lib/tk.rb (revision 26939) +++ mvm/ext/tk/lib/tk.rb (revision 26940) @@ -5663,7 +5663,7 @@ #Tk.freeze module Tk - RELEASE_DATE = '2009-08-04'.freeze + RELEASE_DATE = '2010-02-01'.freeze autoload :AUTO_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable' Index: mvm/ext/tk/extconf.rb =================================================================== --- mvm/ext/tk/extconf.rb (revision 26939) +++ mvm/ext/tk/extconf.rb (revision 26940) @@ -634,7 +634,8 @@ TkLib_Config["tclConfig-dir"] = tclConfig_dir TkLib_Config["tkConfig-dir"] = tkConfig_dir - print("Search tclConfig.sh and tkConfig.sh in #{tclConfig_dir}.") + print("Search tclConfig.sh", (tclConfig_dir)? " (in #{tclConfig_dir})": "", + " and tkConfig.sh", (tkConfig_dir)? " (in #{tkConfig_dir})": "", ".") if tclConfig_dir tclConfig, tkConfig = search_tclConfig([ ((tclConfig_file)? tclConfig_file: tclConfig_dir), @@ -727,7 +728,14 @@ end def search_vers_on_path(vers, path, *heads) - files = Dir.glob(File.join(path, "*{#{heads.join(',')}}*.{#{CONFIG['LIBEXT']},#{CONFIG['DLEXT']}}")) + if enable_config("shared") == false + exts = CONFIG['LIBEXT'] + ',' + CONFIG['DLEXT'] + else + exts = CONFIG['DLEXT'] + ',' + CONFIG['LIBEXT'] + end + exts << ",dll,lib" if is_win32? + exts << ",bundle,dylib" if is_macosx? || /nextstep|openstep|rhapsody/ =~ RUBY_PLATFORM + files = Dir.glob(File.join(path, "*{#{heads.join(',')}}*.{#{exts}}")) vers.find_all{|ver| files.find{|f| f =~ /(#{ver}|#{ver.delete('.')})/} } end @@ -1256,6 +1264,8 @@ have_func("rb_obj_taint", "ruby.h") print(".") # progress have_func("rb_set_safe_level_force", "ruby.h") +print(".") # progress +have_func("rb_sourcefile", "ruby.h") print("\n") # progress print("check struct members.") Index: mvm/ext/tk/tkutil/tkutil.c =================================================================== --- mvm/ext/tk/tkutil/tkutil.c (revision 26939) +++ mvm/ext/tk/tkutil/tkutil.c (revision 26940) @@ -7,7 +7,7 @@ ************************************************/ -#define TKUTIL_RELEASE_DATE "2009-10-27" +#define TKUTIL_RELEASE_DATE "2010-02-01" #include "ruby.h" Index: mvm/ext/nkf/nkf-utf8/nkf.c =================================================================== --- mvm/ext/nkf/nkf-utf8/nkf.c (revision 26939) +++ mvm/ext/nkf/nkf-utf8/nkf.c (revision 26940) @@ -20,11 +20,11 @@ * * 3. This notice may not be removed or altered from any source distribution. */ -#define NKF_VERSION "2.0.9" -#define NKF_RELEASE_DATE "2009-01-20" +#define NKF_VERSION "2.1.1" +#define NKF_RELEASE_DATE "2010-03-15" #define COPY_RIGHT \ "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).\n" \ - "Copyright (C) 1996-2009, The nkf Project." + "Copyright (C) 1996-2010, The nkf Project." #include "config.h" #include "nkf.h" @@ -210,6 +210,8 @@ } encoding_name_to_id_table[] = { {"US-ASCII", ASCII}, {"ASCII", ASCII}, + {"646", ASCII}, + {"ROMAN8", ASCII}, {"ISO-2022-JP", ISO_2022_JP}, {"ISO2022JP-CP932", CP50220}, {"CP50220", CP50220}, @@ -221,6 +223,7 @@ {"ISO-2022-JP-2004", ISO_2022_JP_2004}, {"SHIFT_JIS", SHIFT_JIS}, {"SJIS", SHIFT_JIS}, + {"PCK", SHIFT_JIS}, {"WINDOWS-31J", WINDOWS_31J}, {"CSWINDOWS31J", WINDOWS_31J}, {"CP932", WINDOWS_31J}, @@ -295,7 +298,7 @@ && (c != '(') && (c != ')') && (c != '.') && (c != 0x22))) #define is_ibmext_in_sjis(c2) (CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END) -#define nkf_byte_jisx0201_katakana_p(c) (SP <= c && c < (0xE0&0x7F)) +#define nkf_byte_jisx0201_katakana_p(c) (SP <= c && c <= 0x5F) #define HOLD_SIZE 1024 #if defined(INT_IS_SHORT) @@ -468,6 +471,8 @@ {"Shift_JIS", 0, 0, 0, {0, 0, 0}, s_status, s_iconv, 0}, #ifdef UTF8_INPUT_ENABLE {"UTF-8", 0, 0, 0, {0, 0, 0}, w_status, w_iconv, 0}, + {"UTF-16", 0, 0, 0, {0, 0, 0}, NULL, w_iconv16, 0}, + {"UTF-32", 0, 0, 0, {0, 0, 0}, NULL, w_iconv32, 0}, #endif {0} }; @@ -809,7 +814,7 @@ nkf_buf_new(int length) { nkf_buf_t *buf = nkf_xmalloc(sizeof(nkf_buf_t)); - buf->ptr = nkf_xmalloc(length); + buf->ptr = nkf_xmalloc(sizeof(nkf_char) * length); buf->capa = length; buf->len = 0; return buf; @@ -827,7 +832,7 @@ #define nkf_buf_length(buf) ((buf)->len) #define nkf_buf_empty_p(buf) ((buf)->len == 0) -static unsigned char +static nkf_char nkf_buf_at(nkf_buf_t *buf, int index) { assert(index <= buf->len); @@ -849,7 +854,7 @@ buf->ptr[buf->len++] = c; } -static unsigned char +static nkf_char nkf_buf_pop(nkf_buf_t *buf) { assert(!nkf_buf_empty_p(buf)); @@ -1026,7 +1031,7 @@ int shift = 20; c &= VALUE_MASK; while(shift >= 0){ - if(c >= 1<<shift){ + if(c >= NKF_INT32_C(1)<<shift){ while(shift >= 0){ (*f)(0, bin2hex(c>>shift)); shift -= 4; @@ -1204,6 +1209,7 @@ case CP50220: case CP50221: case CP50222: + x0201_f = TRUE; #ifdef SHIFTJIS_CP932 cp51932_f = TRUE; #endif @@ -1225,6 +1231,7 @@ case SHIFT_JIS: break; case WINDOWS_31J: + x0201_f = TRUE; #ifdef SHIFTJIS_CP932 cp51932_f = TRUE; #endif @@ -1246,6 +1253,7 @@ case EUCJP_NKF: break; case CP51932: + x0201_f = TRUE; #ifdef SHIFTJIS_CP932 cp51932_f = TRUE; #endif @@ -1325,6 +1333,7 @@ #endif break; case CP50221: + x0201_f = TRUE; #ifdef SHIFTJIS_CP932 if (cp932inv_f == TRUE) cp932inv_f = FALSE; #endif @@ -1332,6 +1341,11 @@ ms_ucs_map_f = UCS_MAP_CP932; #endif break; + case ISO_2022_JP: +#ifdef SHIFTJIS_CP932 + if (cp932inv_f == TRUE) cp932inv_f = FALSE; +#endif + break; case ISO_2022_JP_1: x0212_f = TRUE; #ifdef SHIFTJIS_CP932 @@ -1348,6 +1362,7 @@ case SHIFT_JIS: break; case WINDOWS_31J: + x0201_f = TRUE; #ifdef UTF8_OUTPUT_ENABLE ms_ucs_map_f = UCS_MAP_CP932; #endif @@ -1376,6 +1391,7 @@ #endif break; case CP51932: + x0201_f = TRUE; #ifdef SHIFTJIS_CP932 if (cp932inv_f == TRUE) cp932inv_f = FALSE; #endif @@ -1426,6 +1442,7 @@ output_endian = ENDIAN_LITTLE; output_bom_f = TRUE; break; + case UTF_32: case UTF_32BE_BOM: output_bom_f = TRUE; break; @@ -1652,7 +1669,7 @@ *p3 = 0x80 | ( val & 0x3f); *p4 = 0; } else if (nkf_char_unicode_value_p(val)) { - *p1 = 0xe0 | (val >> 16); + *p1 = 0xf0 | (val >> 18); *p2 = 0x80 | ((val >> 12) & 0x3f); *p3 = 0x80 | ((val >> 6) & 0x3f); *p4 = 0x80 | ( val & 0x3f); @@ -2216,13 +2233,15 @@ static nkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0) { - return 0; + (*oconv)(c2, c1); + return 16; /* different from w_iconv32 */ } static nkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0) { - return 0; + (*oconv)(c2, c1); + return 32; /* different from w_iconv16 */ } static size_t @@ -3036,24 +3055,24 @@ } #endif /*WIN32DLL*/ -static unsigned char hold_buf[HOLD_SIZE*2]; +static nkf_char hold_buf[HOLD_SIZE*2]; static int hold_count = 0; static nkf_char push_hold_buf(nkf_char c2) { if (hold_count >= HOLD_SIZE*2) return (EOF); - hold_buf[hold_count++] = (unsigned char)c2; + hold_buf[hold_count++] = c2; return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count); } static int -h_conv(FILE *f, int c1, int c2) +h_conv(FILE *f, nkf_char c1, nkf_char c2) { - int ret, c4, c3; + int ret; int hold_index; + nkf_char c3, c4; - /** it must NOT be in the kanji shifte sequence */ /** it must NOT be written in JIS7 */ /** and it must be after 2 byte 8bit code */ @@ -3102,7 +3121,11 @@ hold_index = 0; while (hold_index < hold_count){ c1 = hold_buf[hold_index++]; - if (c1 <= DEL){ + if (nkf_char_unicode_p(c1)) { + (*oconv)(0, c1); + continue; + } + else if (c1 <= DEL){ (*iconv)(0, c1, 0); continue; }else if (iconv == s_iconv && 0xa1 <= c1 && c1 <= 0xdf){ @@ -3128,18 +3151,16 @@ } else if ((c3 = (*i_getc)(f)) == EOF) { ret = EOF; break; - } else { - code_status(c3); - if (hold_index < hold_count){ - c4 = hold_buf[hold_index++]; - } else if ((c4 = (*i_getc)(f)) == EOF) { - c3 = ret = EOF; - break; - } else { - code_status(c4); - (*iconv)(c1, c2, (c3<<8)|c4); - } } + code_status(c3); + if (hold_index < hold_count){ + c4 = hold_buf[hold_index++]; + } else if ((c4 = (*i_getc)(f)) == EOF) { + c3 = ret = EOF; + break; + } + code_status(c4); + (*iconv)(c1, c2, (c3<<8)|c4); break; case -1: /* 3 bytes EUC or UTF-8 */ @@ -3339,6 +3360,40 @@ else if (c2 != 0 || c1 != LF) (*o_eol_conv)(c2, c1); } +static void +put_newline(void (*func)(nkf_char)) +{ + switch (eolmode_f ? eolmode_f : DEFAULT_NEWLINE) { + case CRLF: + (*func)(0x0D); + (*func)(0x0A); + break; + case CR: + (*func)(0x0D); + break; + case LF: + (*func)(0x0A); + break; + } +} + +static void +oconv_newline(void (*func)(nkf_char, nkf_char)) +{ + switch (eolmode_f ? eolmode_f : DEFAULT_NEWLINE) { + case CRLF: + (*func)(0, 0x0D); + (*func)(0, 0x0A); + break; + case CR: + (*func)(0, 0x0D); + break; + case LF: + (*func)(0, 0x0A); + break; + } +} + /* Return value of fold_conv() @@ -3511,13 +3566,13 @@ /* terminator process */ switch(fold_state) { case LF: - OCONV_NEWLINE((*o_fconv)); + oconv_newline(o_fconv); (*o_fconv)(c2,c1); break; case 0: return; case CR: - OCONV_NEWLINE((*o_fconv)); + oconv_newline(o_fconv); break; case TAB: case SP: @@ -3804,6 +3859,7 @@ (const unsigned char *)"\075?ISO-8859-1?Q?", (const unsigned char *)"\075?ISO-8859-1?B?", (const unsigned char *)"\075?ISO-2022-JP?B?", + (const unsigned char *)"\075?ISO-2022-JP?B?", (const unsigned char *)"\075?ISO-2022-JP?Q?", #if defined(UTF8_INPUT_ENABLE) (const unsigned char *)"\075?UTF-8?B?", @@ -3824,7 +3880,7 @@ }; static const nkf_char mime_encode[] = { - EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201_1976_K, + EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201_1976_K, JIS_X_0201_1976_K, #if defined(UTF8_INPUT_ENABLE) UTF_8, UTF_8, #endif @@ -3833,7 +3889,7 @@ }; static const nkf_char mime_encode_method[] = { - 'B', 'B','Q', 'B', 'B', 'Q', + 'B', 'B','Q', 'B', 'B', 'B', 'Q', #if defined(UTF8_INPUT_ENABLE) 'B', 'Q', #endif @@ -4427,7 +4483,7 @@ } if (c1=='='&&c2<SP) { /* this is soft wrap */ while((c1 = (*i_mgetc)(f)) <=SP) { - if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF); + if (c1 == EOF) return (EOF); } mime_decode_mode = 'Q'; /* still in MIME */ goto restart_mime_q; @@ -4599,7 +4655,7 @@ (*o_mputc)(mimeout_state.buf[i]); i++; } - PUT_NEWLINE((*o_mputc)); + put_newline(o_mputc); (*o_mputc)(SP); base64_count = 1; if (mimeout_state.count>0 && nkf_isspace(mimeout_state.buf[i])) { @@ -4632,14 +4688,14 @@ if (c2 == EOF){ if (base64_count + mimeout_state.count/3*4> 73){ (*o_base64conv)(EOF,0); - OCONV_NEWLINE((*o_base64conv)); + oconv_newline(o_base64conv); (*o_base64conv)(0,SP); base64_count = 1; } } else { - if (base64_count + mimeout_state.count/3*4> 66) { + if ((c2 != 0 || c1 > DEL) && base64_count + mimeout_state.count/3*4> 66) { (*o_base64conv)(EOF,0); - OCONV_NEWLINE((*o_base64conv)); + oconv_newline(o_base64conv); (*o_base64conv)(0,SP); base64_count = 1; mimeout_mode = -1; @@ -4650,7 +4706,7 @@ mimeout_mode = (output_mode==ASCII ||output_mode == ISO_8859_1) ? 'Q' : 'B'; open_mime(output_mode); (*o_base64conv)(EOF,0); - OCONV_NEWLINE((*o_base64conv)); + oconv_newline(o_base64conv); (*o_base64conv)(0,SP); base64_count = 1; mimeout_mode = -1; @@ -4748,14 +4804,14 @@ if (base64_count > 71){ if (c!=CR && c!=LF) { (*o_mputc)('='); - PUT_NEWLINE((*o_mputc)); + put_newline(o_mputc); } base64_count = 0; } }else{ if (base64_count > 71){ eof_mime(); - PUT_NEWLINE((*o_mputc)); + put_newline(o_mputc); base64_count = 0; } if (c == EOF) { /* c==EOF */ @@ -4817,7 +4873,7 @@ } else if (c <= SP) { close_mime(); if (base64_count > 70) { - PUT_NEWLINE((*o_mputc)); + put_newline(o_mputc); base64_count = 0; } if (!nkf_isblank(c)) { @@ -4827,7 +4883,7 @@ } else { if (base64_count > 70) { close_mime(); - PUT_NEWLINE((*o_mputc)); + put_newline(o_mputc); (*o_mputc)(SP); base64_count = 1; open_mime(output_mode); @@ -4837,14 +4893,17 @@ return; } } - (*o_mputc)(c); - base64_count++; + if (c != 0x1B) { + (*o_mputc)(c); + base64_count++; + return; + } } - return; } if (mimeout_mode <= 0) { - if (c <= DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) { + if (c <= DEL && (output_mode==ASCII || output_mode == ISO_8859_1 || + output_mode == UTF_8)) { if (nkf_isspace(c)) { int flag = 0; if (mimeout_mode == -1) { @@ -4889,7 +4948,7 @@ } if (i == 0 || i == mimeout_state.count - len) { - PUT_NEWLINE((*o_mputc)); + put_newline(o_mputc); base64_count = 0; if (!nkf_isspace(mimeout_state.buf[0])){ (*o_mputc)(SP); @@ -4901,7 +4960,7 @@ for (j = 0; j <= i; ++j) { (*o_mputc)(mimeout_state.buf[j]); } - PUT_NEWLINE((*o_mputc)); + put_newline(o_mputc); base64_count = 1; for (; j <= mimeout_state.count; ++j) { mimeout_state.buf[j - i] = mimeout_state.buf[j]; @@ -4935,14 +4994,15 @@ } }else{ /* mimeout_mode == 'B', 1, 2 */ - if ( c<=DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) { + if (c <= DEL && (output_mode==ASCII || output_mode == ISO_8859_1 || + output_mode == UTF_8)) { if (lastchar == CR || lastchar == LF){ if (nkf_isblank(c)) { for (i=0;i<mimeout_state.count;i++) { mimeout_addchar(mimeout_state.buf[i]); } mimeout_state.count = 0; - } else if (SP<c && c<DEL) { + } else { eof_mime(); for (i=0;i<mimeout_state.count;i++) { (*o_mputc)(mimeout_state.buf[i]); @@ -5238,6 +5298,8 @@ set_output_encoding(output_encoding); oconv = nkf_enc_to_oconv(output_encoding); o_putc = std_putc; + if (nkf_enc_unicode_p(output_encoding)) + output_mode = UTF_8; /* replace continucation module, from output side */ @@ -5386,7 +5448,7 @@ (c4 = (*i_getc)(f)) != EOF) { nkf_iconv_utf_32(c1, c2, c3, c4); } - (*i_ungetc)(EOF, f); + goto finished; } else if (iconv == w_iconv16) { while ((c1 = (*i_getc)(f)) != EOF && @@ -5397,7 +5459,7 @@ nkf_iconv_utf_16(c1, c2, c3, c4); } } - (*i_ungetc)(EOF, f); + goto finished; } #endif @@ -5444,6 +5506,12 @@ if (input_mode == JIS_X_0208 && DEL <= c1 && c1 < 0x92) { /* CP5022x */ MORE; + }else if (input_codename && input_codename[0] == 'I' && + 0xA1 <= c1 && c1 <= 0xDF) { + /* JIS X 0201 Katakana in 8bit JIS */ + c2 = JIS_X_0201_1976_K; + c1 &= 0x7f; + SEND; } else if (c1 > DEL) { /* 8 bit code */ if (!estab_f && !iso8859_f) { @@ -5518,7 +5586,7 @@ SKIP; } else if (c1 == ESC && (!is_8bit || mime_decode_mode)) { if ((c1 = (*i_getc)(f)) == EOF) { - /* (*oconv)(0, ESC); don't send bogus code */ + (*oconv)(0, ESC); LAST; } else if (c1 == '&') { @@ -5648,7 +5716,7 @@ } else if (c1 == ESC && iconv == s_iconv) { /* ESC in Shift_JIS */ if ((c1 = (*i_getc)(f)) == EOF) { - /* (*oconv)(0, ESC); don't send bogus code */ + (*oconv)(0, ESC); LAST; } else if (c1 == '$') { /* J-PHONE emoji */ @@ -5773,6 +5841,7 @@ /* goto next_word */ } +finished: /* epilogue */ (*iconv)(EOF, 0, 0); if (!input_codename) @@ -6132,7 +6201,7 @@ break; #endif #ifdef UTF8_OUTPUT_ENABLE - case 'w': /* UTF-8 output */ + case 'w': /* UTF-{8,16,32} output */ if (cp[0] == '8') { cp++; if (cp[0] == '0'){ @@ -6157,19 +6226,18 @@ if (cp[0]=='L') { cp++; output_endian = ENDIAN_LITTLE; + output_bom_f = TRUE; } else if (cp[0] == 'B') { cp++; - } else { - output_encoding = nkf_enc_from_index(enc_idx); - continue; + output_bom_f = TRUE; } if (cp[0] == '0'){ + output_bom_f = FALSE; cp++; enc_idx = enc_idx == UTF_16 ? (output_endian == ENDIAN_LITTLE ? UTF_16LE : UTF_16BE) : (output_endian == ENDIAN_LITTLE ? UTF_32LE : UTF_32BE); } else { - output_bom_f = TRUE; enc_idx = enc_idx == UTF_16 ? (output_endian == ENDIAN_LITTLE ? UTF_16LE_BOM : UTF_16BE_BOM) : (output_endian == ENDIAN_LITTLE ? UTF_32LE_BOM : UTF_32BE_BOM); @@ -6229,10 +6297,10 @@ bit:3 Convert HTML Entity bit:4 Convert JIS X 0208 Katakana to JIS X 0201 Katakana */ - while ('0'<= *cp && *cp <='9') { + while ('0'<= *cp && *cp <='4') { alpha_f |= 1 << (*cp++ - '0'); } - if (!alpha_f) alpha_f = 1; + alpha_f |= 1; continue; case 'x': /* Convert X0201 kana to X0208 or X0201 Conversion */ x0201_f = FALSE; /* No X0201->X0208 conversion */ Index: mvm/NEWS =================================================================== --- mvm/NEWS (revision 26939) +++ mvm/NEWS (revision 26940) @@ -27,6 +27,13 @@ * new encodings: * Big5 * Big5-UAO + * ISO-2022-JP-KDDI + * SJIS-DoCoMo + * SJIS-KDDI + * SJIS-SoftBank + * UTF8-DoCoMo + * UTF8-KDDI + * UTF8-SoftBank * new method: * ascii_compatible? Index: mvm/.merged-trunk-revision =================================================================== --- mvm/.merged-trunk-revision (revision 26939) +++ mvm/.merged-trunk-revision (revision 26940) @@ -1 +1 @@ -26885 +26939 Index: mvm/version.h =================================================================== --- mvm/version.h (revision 26939) +++ mvm/version.h (revision 26940) @@ -1,5 +1,5 @@ #define RUBY_VERSION "1.9.2" -#define RUBY_RELEASE_DATE "2010-03-12" +#define RUBY_RELEASE_DATE "2010-03-15" #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 12 +#define RUBY_RELEASE_DAY 15 #include "ruby/version.h" Index: mvm/ruby.c =================================================================== --- mvm/ruby.c (revision 26939) +++ mvm/ruby.c (revision 26940) @@ -337,6 +337,7 @@ ruby_init_loadpath_safe(int safe_level) { VALUE load_path; + ID id_initial_load_path_mark; extern const char ruby_initial_load_paths[]; const char *paths = ruby_initial_load_paths; #if defined LOAD_RELATIVE @@ -430,16 +431,18 @@ #define RUBY_RELATIVE(path, len) rubylib_mangled_path(path, len) #define PREFIX_PATH() rubylib_mangled_path(RUBY_LIB_PREFIX, sizeof(RUBY_LIB_PREFIX)-1) #endif -#define incpush(path) rb_ary_push(load_path, (path)) load_path = GET_VM()->load_path; if (safe_level == 0) { ruby_push_include(getenv("RUBYLIB"), identical_path); } + id_initial_load_path_mark = rb_intern_const("@gem_prelude_index"); while (*paths) { size_t len = strlen(paths); - incpush(RUBY_RELATIVE(paths, len)); + VALUE path = RUBY_RELATIVE(paths, len); + rb_ivar_set(path, id_initial_load_path_mark, path); + rb_ary_push(load_path, path); paths += len + 1; } Index: mvm/tool/transcode-tblgen.rb =================================================================== --- mvm/tool/transcode-tblgen.rb (revision 26939) +++ mvm/tool/transcode-tblgen.rb (revision 26940) @@ -1,7 +1,24 @@ require 'optparse' require 'erb' require 'fileutils' +require 'pp' +class Array + unless [].respond_to? :product + def product(*args) + if args.empty? + self.map {|e| [e] } + else + result = [] + self.each {|e0| + result.concat args.first.product(*args[1..-1]).map {|es| [e0, *es] } + } + result + end + end + end +end + NUM_ELEM_BYTELOOKUP = 2 C_ESC = { @@ -18,257 +35,287 @@ '"' + str.gsub(C_ESC_PAT) { C_ESC[$&] } + '"' end -HEX2 = /[0-9A-Fa-f]{2}/ +HEX2 = /(?:[0-9A-Fa-f]{2})/ -class StrSet - attr_reader :pat +class ArrayCode + def initialize(type, name) + @type = type + @name = name + @len = 0; + @content = '' + end - SINGLE_BYTE_RANGES = (0..255).map {|i| [i..i] } + def length + @len + end - def self.parse(pattern) - if /\A\s*((#{HEX2}|\{(#{HEX2}|#{HEX2}-#{HEX2})(,(#{HEX2}|#{HEX2}-#{HEX2}))*\})+(\s+|\z))*\z/o !~ pattern - raise ArgumentError, "invalid pattern: #{pattern.inspect}" - end - result = [] - pattern.scan(/\S+/) {|seq| - seq_result = [] - while !seq.empty? - if /\A(#{HEX2})/o =~ seq - byte = $1.to_i(16) - seq_result << SINGLE_BYTE_RANGES[byte] - seq = $' - elsif /\A\{([^\}]+)\}/ =~ seq - set = $1 - seq = $' - set_result = [] - set.scan(/[^,]+/) {|range| - if /\A(#{HEX2})-(#{HEX2})\z/o =~ range - b = $1.to_i(16) - e = $2.to_i(16) - set_result << (b..e) - elsif /\A(#{HEX2})\z/o =~ range - byte = $1.to_i(16) - set_result << (byte..byte) - else - raise "invalid range: #{range.inspect}" - end - } - seq_result << set_result - else - raise "invalid sequence: #{seq.inspect}" - end - end - result << seq_result - } - self.new(result) + def insert_at_last(num, str) + newnum = self.length + num + @content << str + @len += num end - def initialize(pat) - @pat = pat + def to_s + <<"End" +static const #{@type} +#{@name}[#{@len}] = { +#{@content}}; +End end +end +class Action + def initialize(value) + @value = value + end + attr_reader :value + def hash - return @hash if defined? @hash - @hash = @pat.hash + @value.hash end def eql?(other) self.class == other.class && - @pat == other.pat + @value == other.value end - alias == eql? +end - def to_s - if @pat.empty? - "(empset)" - else - @pat.map {|seq| - if seq.empty? - "(empstr)" - else - seq.map {|byteset| - if byteset.length == 1 && byteset[0].begin == byteset[0].end - "%02x" % byteset[0].begin +class ActionMap + def self.parse_to_rects(hash) + h = {} + hash.each {|pat, action| + pat = pat.to_s + h[pat] = action + } + hash = h + + rects = [] + n = 0 + hash.each {|pat, action| + if /\A\s*\(empset\)\s*\z/ =~ pat + next + elsif /\A\s*\(empstr\)\s*\z/ =~ pat + rects << ['', '', action] + n += 1 + elsif /\A\s*(#{HEX2}+)\s*\z/o =~ pat + hex = $1.upcase + rects << [hex, hex, action] + elsif /\A\s*((#{HEX2}|\{#{HEX2}(?:-#{HEX2})?(,#{HEX2}(?:-#{HEX2})?)*\})+(\s+|\z))*\z/o =~ pat + pat = pat.upcase + pat.scan(/\S+/) { + pat1 = $& + ranges_list = [] + pat1.scan(/#{HEX2}|\{([^\}]*)\}/o) { + ranges_list << [] + if !$1 + ranges_list.last << [$&,$&] else - "{" + - byteset.map {|range| - if range.begin == range.end - "%02x" % range.begin + set = {} + $1.scan(/(#{HEX2})(?:-(#{HEX2}))?/o) { + if !$2 + c = $1.to_i(16) + set[c] = true else - "%02x-%02x" % [range.begin, range.end] + b = $1.to_i(16) + e = $2.to_i(16) + b.upto(e) {|c| set[c] = true } end - }.join(',') + - "}" + } + i = nil + 0.upto(256) {|j| + if set[j] + if !i + i = j + end + if !set[j+1] + ranges_list.last << ["%02X" % i, "%02X" % j] + i = nil + end + end + } end - }.join('') - end - }.join(' ') - end + } + first_ranges = ranges_list.shift + first_ranges.product(*ranges_list).each {|range_list| + min = range_list.map {|x, y| x }.join + max = range_list.map {|x, y| y }.join + rects << [min, max, action] + } + } + else + raise ArgumentError, "invalid pattern: #{pat.inspect}" + end + } + rects end - def inspect - "\#<#{self.class}: #{self.to_s}>" - end - - def min_length - if @pat.empty? - nil + def self.unambiguous_action(actions0) + actions = actions0.uniq + if actions.length == 1 + actions[0] else - @pat.map {|seq| seq.length }.min + actions = actions.find_all {|action| action != :nomap0 } + if actions.length == 1 + actions[0] + else + raise ArgumentError, "ambiguous actions: #{actions0.inspect}" + end end end - def max_length - if @pat.empty? - nil - else - @pat.map {|seq| seq.length }.max - end + def self.build_tree(rects) + expand("", rects) {|actions| + unambiguous_action(actions) + } end - def emptyable? - @pat.any? {|seq| - seq.empty? - } + def self.parse(hash) + rects = parse_to_rects(hash) + tree = build_tree(rects) + self.new("", tree) end - def first_bytes - result = {} - @pat.each {|seq| - next if seq.empty? - seq.first.each {|range| - range.each {|byte| - result[byte] = true - } - } + def self.merge(*rects_list) + if rects_list.length < 2 + raise ArgumentError, "not enough arguments" + end + + all_rects = [] + rects_list.each_with_index {|rects, i| + all_rects.concat rects.map {|min, max, action| [min, max, [i, action]] } } - result.keys.sort - end - def each_firstbyte - h = {} - @pat.each {|seq| - next if seq.empty? - seq.first.each {|range| - range.each {|byte| - (h[byte] ||= []) << seq[1..-1] - } + tree = expand("", all_rects) {|actions| + args = Array.new(rects_list.length) { [] } + actions.each {|i, action| + args[i] << action } + yield(args) } - h.keys.sort.each {|byte| - yield byte, StrSet.new(h[byte]) - } - end -end -class ArrayCode - def initialize(type, name) - @type = type - @name = name - @len = 0; - @content = '' + self.new("", tree) end - def length - @len + def self.expand(prefix, rects, &block) + return [] if rects.empty? + has_empty = false + has_nonempty = false + rects.each {|min, max, action| + if min.empty? + has_empty = true + else + has_nonempty = true + end + } + if has_empty && has_nonempty + raise ArgumentError, "ambiguous pattern: #{prefix}" + end + if has_empty + actions = rects.map {|min, max, action| action }.uniq + act = block.call(actions) + tree = Action.new(act) + else + tree = [] + each_firstbyte_range(prefix, rects) {|byte_min, byte_max, rects2| + prefix2 = prefix + if byte_min == byte_max + prefix2 += "%02X" % byte_min + else + prefix2 += "{%02X-%02X}" % [byte_min, byte_max] + end + child_tree = expand(prefix2, rects2, &block) + tree << [byte_min, byte_max, child_tree] + } + end + return tree end - def insert_at_last(num, str) - newnum = self.length + num - @content << str - @len += num - end - - def to_s - <<"End" -static const #{@type} -#{@name}[#{@len}] = { -#{@content}}; -End - end -end - -class ActionMap - def self.parse(hash) - h = {} - hash.each {|pat, action| - h[StrSet.parse(pat)] = action + def self.each_firstbyte_range(prefix, rects) + a = [] + index_from = {} + rects.each {|min, max, action| + raise ArgumentError, "emptyable pattern" if min.empty? + min_firstbyte = min[0,2].to_i(16) + min_rest = min[2..-1] + max_firstbyte = max[0,2].to_i(16) + max_rest = max[2..-1] + a << [min_firstbyte, max_firstbyte, [min_rest, max_rest, action]] + index_from[min_firstbyte] = true + index_from[max_firstbyte+1] = true } - self.new(h) + byte_from = {} + index_from.keys.sort.each_with_index {|byte, i| + index_from[byte] = i + byte_from[i] = byte + } + rects_hash = {} + a.each {|min_firstbyte, max_firstbyte, rest_elt| + index_from[min_firstbyte].upto(index_from[max_firstbyte+1]-1) {|i| + rects_hash[i] ||= [] + rects_hash[i] << rest_elt + } + } + 0.upto(index_from.size-1) {|i| + rects2 = rects_hash[i] + yield byte_from[i], byte_from[i+1]-1, rects2 if rects2 + } end - def initialize(h) - @map = h + def initialize(prefix, tree) + @prefix = prefix # just for debug + @tree = tree end def hash return @hash if defined? @hash - hash = 0 - @map.each {|k,v| - hash ^= k.hash ^ v.hash - } - @hash = hash + @hash = @tree.hash end def eql?(other) self.class == other.class && - @map == other.instance_eval { @map } + @tree == other.instance_eval { @tree } end alias == eql? def inspect "\#<#{self.class}:" + - @map.map {|k, v| " [" + k.to_s + "]=>" + v.inspect }.join('') + + @tree.inspect + ">" end + def max_input_length_rec(tree) + case tree + when Action + 0 + else + tree.map {|byte_min, byte_max, child_tree| + max_input_length_rec(child_tree) + }.max + 1 + end + end + def max_input_length - @map.keys.map {|k| k.max_length }.max + max_input_length_rec(@tree) end def empty_action - @map.each {|ss, action| - return action if ss.emptyable? - } - nil + if @tree.kind_of? Action + @tree.value + else + nil + end end - def each_firstbyte(valid_encoding=nil) - h = {} - @map.each {|ss, action| - if ss.emptyable? - raise "emptyable pattern" - else - ss.each_firstbyte {|byte, rest| - h[byte] ||= {} - if h[byte][rest].nil? - elsif action == :nomap0 - next - elsif h[byte][rest] != :nomap0 - raise "ambiguous %s or %s (%02X/%s)" % [h[byte][rest], action, byte, rest] - end - h[byte][rest] = action - } - end + def each_firstbyte + @tree.each {|byte_min, byte_max, child_tree| + byte_min.upto(byte_max) {|byte| + prefix = @prefix + ("%02X" % byte) + am = ActionMap.new(prefix, child_tree) + yield byte, am + } } - if valid_encoding - valid_encoding.each_firstbyte {|byte, rest| - if h[byte] - am = ActionMap.new(h[byte]) - yield byte, am, rest - else - am = ActionMap.new(rest => :undef) - yield byte, am, nil - end - } - else - h.keys.sort.each {|byte| - am = ActionMap.new(h[byte]) - yield byte, am, nil - } - end end OffsetsMemo = {} @@ -433,24 +480,24 @@ PostMemo = {} NextName = "a" - def generate_node(bytes_code, words_code, name_hint=nil, valid_encoding=nil) - if n = PreMemo[[self,valid_encoding]] + def generate_node(bytes_code, words_code, name_hint=nil) + if n = PreMemo[self] return n end table = Array.new(0x100, :invalid) - each_firstbyte(valid_encoding) {|byte, rest, rest_valid_encoding| + each_firstbyte {|byte, rest| if a = rest.empty_action table[byte] = a else name_hint2 = nil name_hint2 = "#{name_hint}_#{'%02X' % byte}" if name_hint - table[byte] = "/*BYTE_LOOKUP*/" + rest.gennode(bytes_code, words_code, name_hint2, rest_valid_encoding) + table[byte] = "/*BYTE_LOOKUP*/" + rest.gennode(bytes_code, words_code, name_hint2) end } if n = PostMemo[table] - return PreMemo[[self,valid_encoding]] = n + return PreMemo[self] = n end if !name_hint @@ -458,16 +505,16 @@ NextName.succ! end - PreMemo[[self,valid_encoding]] = PostMemo[table] = name_hint + PreMemo[self] = PostMemo[table] = name_hint generate_lookup_node(bytes_code, words_code, name_hint, table) name_hint end - def gennode(bytes_code, words_code, name_hint=nil, valid_encoding=nil) + def gennode(bytes_code, words_code, name_hint=nil) @bytes_code = bytes_code @words_code = words_code - name = generate_node(bytes_code, words_code, name_hint, valid_encoding) + name = generate_node(bytes_code, words_code, name_hint) @bytes_code = nil @words_code = nil return name @@ -608,17 +655,20 @@ map.each {|k, v| h[k] = v unless h[k] # use first mapping } - am = ActionMap.parse(h) - - max_input = am.max_input_length - - if ValidEncoding[from] - valid_encoding = StrSet.parse(ValidEncoding[from]) + if valid_encoding = ValidEncoding[from] + rects = ActionMap.parse_to_rects(h) + undef_rects = ActionMap.parse_to_rects(valid_encoding => :undef) + am = ActionMap.merge(rects, undef_rects) {|a1, a2| + a1 = a1.empty? ? nil : ActionMap.unambiguous_action(a1) + a2 = a2.empty? ? nil : ActionMap.unambiguous_action(a2) + a1 || a2 + } else - valid_encoding = nil + am = ActionMap.parse(h) end - defined_name = am.gennode(TRANSCODE_GENERATED_BYTES_CODE, TRANSCODE_GENERATED_WORDS_CODE, name, valid_encoding) + max_input = am.max_input_length + defined_name = am.gennode(TRANSCODE_GENERATED_BYTES_CODE, TRANSCODE_GENERATED_WORDS_CODE, name) return defined_name, max_input end @@ -773,6 +823,8 @@ end if __FILE__ == $0 + start_time = Time.now + output_filename = nil verbose_mode = false force_mode = false @@ -861,7 +913,9 @@ FileUtils.mkdir_p(File.dirname(output_filename)) File.open(new_filename, "wb") {|f| f << result } File.rename(new_filename, output_filename) - STDERR.puts "done." if VERBOSE_MODE + tms = Process.times + elapsed = Time.now - start_time + STDERR.puts "done. (#{'%.2f' % tms.utime}user #{'%.2f' % tms.stime}system #{'%.2f' % elapsed}elapsed)" if VERBOSE_MODE else print result end Index: mvm/tool/compile_prelude.rb =================================================================== --- mvm/tool/compile_prelude.rb (revision 26939) +++ mvm/tool/compile_prelude.rb (revision 26940) @@ -48,7 +48,7 @@ key = $1 unless @mkconf require './rbconfig' - @mkconf = RbConfig::MAKEFILE_CONFIG.merge('rubylibprefix'=>'#{TMP_RUBY_PREFIX}') + @mkconf = RbConfig::MAKEFILE_CONFIG.merge('prefix'=>'#{TMP_RUBY_PREFIX}') end if RbConfig::MAKEFILE_CONFIG.has_key? key val = RbConfig.expand("$(#{key})", @mkconf) Index: mvm/tool/file2lastrev.rb =================================================================== --- mvm/tool/file2lastrev.rb (revision 26939) +++ mvm/tool/file2lastrev.rb (revision 26940) @@ -5,47 +5,77 @@ require 'optparse' require 'pathname' -SRCDIR = Pathname(File.dirname($0)).parent.freeze -class VCSNotFoundError < RuntimeError; end +Program = Pathname($0) -def detect_vcs(path) - path = SRCDIR - return :svn, path.relative_path_from(SRCDIR) if File.directory?("#{path}/.svn") - return :git_svn, path.relative_path_from(SRCDIR) if File.directory?("#{path}/.git/svn") - return :git, path.relative_path_from(SRCDIR) if File.directory?("#{path}/.git") - raise VCSNotFoundError, "does not seem to be under a vcs" -end +class VCS + class NotFoundError < RuntimeError; end -# return a pair of strings, the last revision and the last revision in which -# +path+ was modified. -def get_revisions(path) - vcs, path = detect_vcs(path) + @@dirs = [] + def self.register(dir) + @@dirs << [dir, self] + end - info = case vcs - when :svn - info_xml = `cd "#{SRCDIR}" && svn info --xml "#{path}"` - _, last, _, changed, _ = info_xml.split(/revision="(\d+)"/) + def self.detect(path) + @@dirs.sort.reverse_each do |dir, klass| + return klass.new(path) if File.directory?("#{path}/#{dir}") + end + raise VCS::NotFoundError, "does not seem to be under a vcs: #{path}" + end + + def initialize(path) + @srcdir = path + end + + # return a pair of strings, the last revision and the last revision in which + # +path+ was modified. + def get_revisions(path) + path = relative_to(path) + last, changed = Dir.chdir(@srcdir) {yield path} + last or raise "last revision not found" + changed or raise "changed revision not found" return last, changed - when :git_svn - `cd "#{SRCDIR}" && git svn info "#{path}"` - when :git - git_log = `cd "#{SRCDIR}" && git log HEAD~1..HEAD "#{path}"` - git_log =~ /git-svn-id: .*?@(\d+)/ - return $1, $1 end - if /^Revision: (\d+)/ =~ info - last = $1 - else - raise "last revision not found" + def relative_to(path) + path ? Pathname(path).relative_path_from(@srcdir) : '.' end - if /^Last Changed Rev: (\d+)/ =~ info - changed = $1 - else - raise "changed revision not found" + + class SVN < self + register(".svn") + + def get_revisions(*) + super do |path| + info_xml = `svn info --xml "#{path}"` + _, last, _, changed, _ = info_xml.split(/revision="(\d+)"/) + [last, changed] + end + end end - return last, changed + class GIT_SVN < self + register(".git/svn") + + def get_revisions(*) + super do |path| + info = `git svn info "#{path}"` + [info[/^Revision: (\d+)/, 1], info[/^Last Changed Rev: (\d+)/, 1]] + end + end + end + + class GIT < self + register(".git") + + def get_revisions(*) + logcmd = %Q[git log -n1 --grep="^ *git-svn-id: .*@[0-9][0-9]* "] + idpat = /git-svn-id: .*?@(\d+) \S+\Z/ + super do |path| + last = `#{logcmd}`[idpat, 1] + changed = path ? `#{logcmd} "#{path}"`[idpat, 1] : last + [last, changed] + end + end + end end @output = nil @@ -57,27 +87,33 @@ end @suppress_not_found = false +srcdir = nil parser = OptionParser.new {|opts| + opts.on("--srcdir=PATH", "use PATH as source directory") do |path| + srcdir = path + end opts.on("--changed", "changed rev") do self.output = :changed end - opts.on("--revision.h") do + opts.on("--revision.h", "RUBY_REVISION macro") do self.output = :revision_h end - opts.on("--doxygen") do + opts.on("--doxygen", "Doxygen format") do self.output = :doxygen end opts.on("-q", "--suppress_not_found") do @suppress_not_found = true end } -parser.parse! +parser.parse! rescue abort "#{Program.basename}: #{$!}\n#{parser}" - +srcdir = (srcdir ? Pathname(srcdir) : Program.parent.parent).freeze begin - last, changed = get_revisions(ARGV.shift) -rescue VCSNotFoundError - raise unless @suppress_not_found + vcs = VCS.detect(srcdir) +rescue VCS::NotFoundError => e + abort "#{Program.basename}: #{e.message}" unless @suppress_not_found +else + last, changed = vcs.get_revisions(ARGV.shift) end case @output Index: mvm/test/ruby/test_array.rb =================================================================== --- mvm/test/ruby/test_array.rb (revision 26939) +++ mvm/test/ruby/test_array.rb (revision 26940) @@ -1565,7 +1565,7 @@ a << a assert_raise(ArgumentError){a.join} - def (a = Object.new).to_a + def (a = Object.new).to_ary [self] end assert_raise(ArgumentError, '[ruby-core:24150]'){[a].join} Index: mvm/test/ruby/test_file_exhaustive.rb =================================================================== --- mvm/test/ruby/test_file_exhaustive.rb (revision 26939) +++ mvm/test/ruby/test_file_exhaustive.rb (revision 26940) @@ -423,6 +423,8 @@ end assert_incompatible_encoding {|d| File.basename(d)} + assert_incompatible_encoding {|d| File.basename(d, ".*")} + assert_raise(Encoding::CompatibilityError) {File.basename("foo.ext", ".*".encode("utf-16le"))} end def test_dirname Index: mvm/test/ruby/enc/test_emoji.rb =================================================================== --- mvm/test/ruby/enc/test_emoji.rb (revision 26939) +++ mvm/test/ruby/enc/test_emoji.rb (revision 26940) @@ -1,430 +1,442 @@ require 'test/unit' -class TestRenameSJIS < Test::Unit::TestCase - def test_shift_jis - assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-DoCoMo") } - assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-KDDI") } - assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-SoftBank") } - end -end +module Emoji -class TestUTF8_BLACK_SUN_WITH_RAYS < Test::Unit::TestCase - def setup - @codes = { - "UTF8-DoCoMo" => utf8_docomo("\u{E63E}"), - "UTF8-KDDI" => utf8_kddi("\u{E488}"), - "UTF8-SoftBank" => utf8_softbank("\u{E04A}"), - "UTF-8" => "\u{2600}", - } + class TestRenameSJIS < Test::Unit::TestCase + def test_shift_jis + assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-DoCoMo") } + assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-KDDI") } + assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-SoftBank") } + end end - def test_convert - @codes.each do |from_enc, from_str| - @codes.each do |to_enc, to_str| - next if from_enc == to_enc - assert_equal to_str, from_str.encode(to_enc), "convert from #{from_enc} to #{to_enc}" + class TestUTF8_BLACK_SUN_WITH_RAYS < Test::Unit::TestCase + include Emoji + + def setup + @codes = { + "UTF8-DoCoMo" => utf8_docomo("\u{E63E}"), + "UTF8-KDDI" => utf8_kddi("\u{E488}"), + "UTF8-SoftBank" => utf8_softbank("\u{E04A}"), + "UTF-8" => "\u{2600}", + } + end + + def test_convert + @codes.each do |from_enc, from_str| + @codes.each do |to_enc, to_str| + next if from_enc == to_enc + assert_equal to_str, from_str.encode(to_enc), "convert from #{from_enc} to #{to_enc}" + end end end end -end -class TestDoCoMo < Test::Unit::TestCase - def setup - setup_instance_variable(self) - end + class TestDoCoMo < Test::Unit::TestCase + include Emoji - def test_encoding_name - %w(UTF8-DoCoMo - SJIS-DoCoMo).each do |n| - assert Encoding.name_list.include?(n), "encoding not found: #{n}" + def setup + setup_instance_variable(self) end - end - def test_comparison - assert_not_equal Encoding::UTF_8, Encoding::UTF8_DoCoMo - assert_not_equal Encoding::Windows_31J, Encoding::SJIS_DoCoMo - end + def test_encoding_name + %w(UTF8-DoCoMo + SJIS-DoCoMo).each do |n| + assert Encoding.name_list.include?(n), "encoding not found: #{n}" + end + end - def test_from_utf8 - assert_nothing_raised { assert_equal utf8_docomo(@aiueo_utf8), to_utf8_docomo(@aiueo_utf8) } - assert_nothing_raised { assert_equal sjis_docomo(@aiueo_sjis), to_sjis_docomo(@aiueo_utf8) } - end + def test_comparison + assert_not_equal Encoding::UTF_8, Encoding::UTF8_DoCoMo + assert_not_equal Encoding::Windows_31J, Encoding::SJIS_DoCoMo + end - def test_from_sjis - assert_nothing_raised { assert_equal utf8_docomo(@aiueo_utf8), to_utf8_docomo(@aiueo_sjis) } - assert_nothing_raised { assert_equal sjis_docomo(@aiueo_sjis), to_sjis_docomo(@aiueo_sjis) } - end + def test_from_utf8 + assert_nothing_raised { assert_equal utf8_docomo(@aiueo_utf8), to_utf8_docomo(@aiueo_utf8) } + assert_nothing_raised { assert_equal sjis_docomo(@aiueo_sjis), to_sjis_docomo(@aiueo_utf8) } + end - def test_to_utf8 - assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_docomo) } - assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_docomo) } - end + def test_from_sjis + assert_nothing_raised { assert_equal utf8_docomo(@aiueo_utf8), to_utf8_docomo(@aiueo_sjis) } + assert_nothing_raised { assert_equal sjis_docomo(@aiueo_sjis), to_sjis_docomo(@aiueo_sjis) } + end - def test_to_sjis - assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_docomo) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_docomo) } - end + def test_to_utf8 + assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_docomo) } + assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_docomo) } + end - def test_to_eucjp - assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_docomo) } - assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_docomo) } - end + def test_to_sjis + assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_docomo) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_docomo) } + end - def test_docomo - assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_docomo) } - assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_docomo) } - end + def test_to_eucjp + assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_docomo) } + assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_docomo) } + end - def test_to_kddi - assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@utf8_docomo) } - assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_docomo) } - assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_docomo) } + def test_docomo + assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_docomo) } + assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_docomo) } + end - assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_docomo) } - assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_docomo) } - assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_docomo) } + def test_to_kddi + assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@utf8_docomo) } + assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_docomo) } + assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_docomo) } - assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@utf8_docomo_only) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@utf8_docomo_only) } - assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@utf8_docomo_only) } + assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_docomo) } + assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_docomo) } + assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_docomo) } - assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@sjis_docomo_only) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@sjis_docomo_only) } - assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@sjis_docomo_only) } - end + assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@utf8_docomo_only) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@utf8_docomo_only) } + assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@utf8_docomo_only) } - def test_to_softbank - assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_docomo) } - assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_docomo) } + assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@sjis_docomo_only) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@sjis_docomo_only) } + assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@sjis_docomo_only) } + end - assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_docomo) } - assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_docomo) } + def test_to_softbank + assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_docomo) } + assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_docomo) } - assert_raise(Encoding::UndefinedConversionError) { to_utf8_softbank(@utf8_docomo_only) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis_softbank(@utf8_docomo_only) } + assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_docomo) } + assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_docomo) } - assert_raise(Encoding::UndefinedConversionError) { to_utf8_softbank(@sjis_docomo_only) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis_softbank(@sjis_docomo_only) } - end -end + assert_raise(Encoding::UndefinedConversionError) { to_utf8_softbank(@utf8_docomo_only) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis_softbank(@utf8_docomo_only) } -class TestKDDI < Test::Unit::TestCase - def setup - setup_instance_variable(self) + assert_raise(Encoding::UndefinedConversionError) { to_utf8_softbank(@sjis_docomo_only) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis_softbank(@sjis_docomo_only) } + end end - def test_encoding_name - %w(UTF8-KDDI - SJIS-KDDI - ISO-2022-JP-KDDI - stateless-ISO-2022-JP-KDDI).each do |n| - assert Encoding.name_list.include?(n), "encoding not found: #{n}" + class TestKDDI < Test::Unit::TestCase + include Emoji + + def setup + setup_instance_variable(self) end - end - def test_comparison - assert_not_equal Encoding::UTF_8, Encoding::UTF8_KDDI - assert_not_equal Encoding::Windows_31J, Encoding::SJIS_KDDI - assert_not_equal Encoding::ISO_2022_JP, Encoding::ISO_2022_JP_KDDI - assert_not_equal Encoding::Stateless_ISO_2022_JP, Encoding::Stateless_ISO_2022_JP_KDDI - end + def test_encoding_name + %w(UTF8-KDDI + SJIS-KDDI + ISO-2022-JP-KDDI + stateless-ISO-2022-JP-KDDI).each do |n| + assert Encoding.name_list.include?(n), "encoding not found: #{n}" + end + end - def test_from_utf8 - assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_utf8) } - assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_utf8) } - assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_utf8) } - end + def test_comparison + assert_not_equal Encoding::UTF_8, Encoding::UTF8_KDDI + assert_not_equal Encoding::Windows_31J, Encoding::SJIS_KDDI + assert_not_equal Encoding::ISO_2022_JP, Encoding::ISO_2022_JP_KDDI + assert_not_equal Encoding::Stateless_ISO_2022_JP, Encoding::Stateless_ISO_2022_JP_KDDI + end - def test_from_sjis - assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_sjis) } - assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_sjis) } - assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_sjis) } - end + def test_from_utf8 + assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_utf8) } + assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_utf8) } + assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_utf8) } + end - def test_from_iso2022jp - assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_iso2022jp) } - assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_iso2022jp) } - assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_iso2022jp) } - end + def test_from_sjis + assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_sjis) } + assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_sjis) } + assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_sjis) } + end - def test_to_utf8 - assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_kddi) } - assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_undoc_kddi) } - assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_kddi) } - assert_nothing_raised { assert_equal @utf8, to_utf8(@iso2022jp_kddi) } - end + def test_from_iso2022jp + assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_iso2022jp) } + assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_iso2022jp) } + assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_iso2022jp) } + end - def test_to_sjis - assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_kddi) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_undoc_kddi) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_kddi) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis(@iso2022jp_kddi) } - end + def test_to_utf8 + assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_kddi) } + assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_undoc_kddi) } + assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_kddi) } + assert_nothing_raised { assert_equal @utf8, to_utf8(@iso2022jp_kddi) } + end - def test_to_eucjp - assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_kddi) } - assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_undoc_kddi) } - assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_kddi) } - assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@iso2022jp_kddi) } - end + def test_to_sjis + assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_kddi) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_undoc_kddi) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_kddi) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis(@iso2022jp_kddi) } + end - def test_kddi - assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_kddi) } - assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@iso2022jp_kddi) } - assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_kddi) } - assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_undoc_kddi) } - assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@iso2022jp_kddi) } - assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_kddi) } - assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_undoc_kddi) } - assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@iso2022jp_kddi) } - end + def test_to_eucjp + assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_kddi) } + assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_undoc_kddi) } + assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_kddi) } + assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@iso2022jp_kddi) } + end - def test_to_docomo - assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_kddi) } - assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_kddi) } + def test_kddi + assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_kddi) } + assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@iso2022jp_kddi) } + assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_kddi) } + assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_undoc_kddi) } + assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@iso2022jp_kddi) } + assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_kddi) } + assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_undoc_kddi) } + assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@iso2022jp_kddi) } + end - assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_undoc_kddi) } - assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_undoc_kddi) } + def test_to_docomo + assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_kddi) } + assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_kddi) } - assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_kddi) } - assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_kddi) } + assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_undoc_kddi) } + assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_undoc_kddi) } - assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@iso2022jp_kddi) } - assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@iso2022jp_kddi) } + assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_kddi) } + assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_kddi) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_kddi_only) } + assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@iso2022jp_kddi) } + assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@iso2022jp_kddi) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_undoc_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_undoc_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_undoc_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_undoc_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@iso2022jp_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@iso2022jp_kddi_only) } - end + assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_kddi_only) } - def test_to_softbank - assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_kddi) } - assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_kddi) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@iso2022jp_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@iso2022jp_kddi_only) } + end - assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_undoc_kddi) } - assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_undoc_kddi) } + def test_to_softbank + assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_kddi) } + assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_kddi) } - assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_kddi) } - assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_kddi) } + assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_undoc_kddi) } + assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_undoc_kddi) } - assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@iso2022jp_kddi) } - assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@iso2022jp_kddi) } + assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_kddi) } + assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_kddi) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_kddi_only) } + assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@iso2022jp_kddi) } + assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@iso2022jp_kddi) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_undoc_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_undoc_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_undoc_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_undoc_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@iso2022jp_kddi_only) } - assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@iso2022jp_kddi_only) } - end -end + assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_kddi_only) } -class TestSoftBank < Test::Unit::TestCase - def setup - setup_instance_variable(self) + assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@iso2022jp_kddi_only) } + assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@iso2022jp_kddi_only) } + end end - def test_encoding_name - %w(UTF8-SoftBank - SJIS-SoftBank).each do |n| - assert Encoding.name_list.include?(n), "encoding not found: #{n}" + class TestSoftBank < Test::Unit::TestCase + include Emoji + + def setup + setup_instance_variable(self) end - end - def test_comparison - assert_not_equal Encoding::UTF_8, Encoding::UTF8_SoftBank - assert_not_equal Encoding::Windows_31J, Encoding::SJIS_SoftBank - end + def test_encoding_name + %w(UTF8-SoftBank + SJIS-SoftBank).each do |n| + assert Encoding.name_list.include?(n), "encoding not found: #{n}" + end + end - def test_from_utf8 - assert_nothing_raised { assert_equal utf8_softbank(@aiueo_utf8), to_utf8_softbank(@aiueo_utf8) } - assert_nothing_raised { assert_equal sjis_softbank(@aiueo_sjis), to_sjis_softbank(@aiueo_utf8) } - end + def test_comparison + assert_not_equal Encoding::UTF_8, Encoding::UTF8_SoftBank + assert_not_equal Encoding::Windows_31J, Encoding::SJIS_SoftBank + end - def test_from_sjis - assert_nothing_raised { assert_equal utf8_softbank(@aiueo_utf8), to_utf8_softbank(@aiueo_sjis) } - assert_nothing_raised { assert_equal sjis_softbank(@aiueo_sjis), to_sjis_softbank(@aiueo_sjis) } - end + def test_from_utf8 + assert_nothing_raised { assert_equal utf8_softbank(@aiueo_utf8), to_utf8_softbank(@aiueo_utf8) } + assert_nothing_raised { assert_equal sjis_softbank(@aiueo_sjis), to_sjis_softbank(@aiueo_utf8) } + end - def test_to_utf8 - assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_softbank) } - assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_softbank) } - end + def test_from_sjis + assert_nothing_raised { assert_equal utf8_softbank(@aiueo_utf8), to_utf8_softbank(@aiueo_sjis) } + assert_nothing_raised { assert_equal sjis_softbank(@aiueo_sjis), to_sjis_softbank(@aiueo_sjis) } + end - def test_to_sjis - assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_softbank) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_softbank) } - end + def test_to_utf8 + assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_softbank) } + assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_softbank) } + end - def test_to_eucjp - assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_softbank) } - assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_softbank) } - end + def test_to_sjis + assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_softbank) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_softbank) } + end - def test_softbank - assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_softbank) } - assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_softbank) } - end + def test_to_eucjp + assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_softbank) } + assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_softbank) } + end - def test_to_docomo - assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_softbank) } - assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_softbank) } + def test_softbank + assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_softbank) } + assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_softbank) } + end - assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_softbank) } - assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_softbank) } + def test_to_docomo + assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_softbank) } + assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_softbank) } - assert_raise(Encoding::UndefinedConversionError) { to_utf8_docomo(@utf8_softbank_only) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis_docomo(@utf8_softbank_only) } + assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_softbank) } + assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_softbank) } - assert_raise(Encoding::UndefinedConversionError) { to_utf8_docomo(@sjis_softbank_only) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis_docomo(@sjis_softbank_only) } - end + assert_raise(Encoding::UndefinedConversionError) { to_utf8_docomo(@utf8_softbank_only) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis_docomo(@utf8_softbank_only) } - def test_to_kddi - assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@utf8_softbank) } - assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_softbank) } - assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_softbank) } + assert_raise(Encoding::UndefinedConversionError) { to_utf8_docomo(@sjis_softbank_only) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis_docomo(@sjis_softbank_only) } + end - assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_softbank) } - assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_softbank) } - assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_softbank) } + def test_to_kddi + assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@utf8_softbank) } + assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_softbank) } + assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_softbank) } - assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@utf8_softbank_only) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@utf8_softbank_only) } - assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@utf8_softbank_only) } + assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_softbank) } + assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_softbank) } + assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_softbank) } - assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@sjis_softbank_only) } - assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@sjis_softbank_only) } - assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@sjis_softbank_only) } + assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@utf8_softbank_only) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@utf8_softbank_only) } + assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@utf8_softbank_only) } + + assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@sjis_softbank_only) } + assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@sjis_softbank_only) } + assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@sjis_softbank_only) } + end end -end -private + private -def setup_instance_variable(obj) - obj.instance_eval do - @aiueo_utf8 = "\u{3042}\u{3044}\u{3046}\u{3048}\u{304A}" - @aiueo_sjis = to_sjis(@aiueo_utf8) - @aiueo_iso2022jp = to_iso2022jp(@aiueo_utf8) + def setup_instance_variable(obj) + obj.instance_eval do + @aiueo_utf8 = "\u{3042}\u{3044}\u{3046}\u{3048}\u{304A}" + @aiueo_sjis = to_sjis(@aiueo_utf8) + @aiueo_iso2022jp = to_iso2022jp(@aiueo_utf8) - @utf8 = "\u{2600}" + @utf8 = "\u{2600}" - @utf8_docomo = utf8_docomo("\u{E63E}") - @sjis_docomo = sjis_docomo("\xF8\x9F") - @utf8_docomo_only = utf8_docomo("\u{E6B1}") - @sjis_docomo_only = sjis_docomo("\xF9\x55") + @utf8_docomo = utf8_docomo("\u{E63E}") + @sjis_docomo = sjis_docomo("\xF8\x9F") + @utf8_docomo_only = utf8_docomo("\u{E6B1}") + @sjis_docomo_only = sjis_docomo("\xF9\x55") - @utf8_kddi = utf8_kddi("\u{E488}") - @utf8_undoc_kddi = utf8_kddi("\u{EF60}") - @sjis_kddi = sjis_kddi("\xF6\x60") - @iso2022jp_kddi = iso2022jp_kddi("\x1B$B\x75\x41\x1B(B") - @stateless_iso2022jp_kddi = stateless_iso2022jp_kddi("\x92\xF5\xC1") - @utf8_kddi_only = utf8_kddi("\u{E5B3}") - @utf8_undoc_kddi_only = utf8_kddi("\u{F0D0}") - @sjis_kddi_only = sjis_kddi("\xF7\xD0") - @iso2022jp_kddi_only = iso2022jp_kddi("\x1B$B\x78\x52\x1B(B") - @stateless_iso2022jp_kddi_only = stateless_iso2022jp_kddi("\x92\xF8\xD2") + @utf8_kddi = utf8_kddi("\u{E488}") + @utf8_undoc_kddi = utf8_kddi("\u{EF60}") + @sjis_kddi = sjis_kddi("\xF6\x60") + @iso2022jp_kddi = iso2022jp_kddi("\x1B$B\x75\x41\x1B(B") + @stateless_iso2022jp_kddi = stateless_iso2022jp_kddi("\x92\xF5\xC1") + @utf8_kddi_only = utf8_kddi("\u{E5B3}") + @utf8_undoc_kddi_only = utf8_kddi("\u{F0D0}") + @sjis_kddi_only = sjis_kddi("\xF7\xD0") + @iso2022jp_kddi_only = iso2022jp_kddi("\x1B$B\x78\x52\x1B(B") + @stateless_iso2022jp_kddi_only = stateless_iso2022jp_kddi("\x92\xF8\xD2") - @utf8_softbank = utf8_softbank("\u{E04A}") - @sjis_softbank = sjis_softbank("\xF9\x8B") - @utf8_softbank_only = utf8_softbank("\u{E524}") - @sjis_softbank_only = sjis_softbank("\xFB\xC4") + @utf8_softbank = utf8_softbank("\u{E04A}") + @sjis_softbank = sjis_softbank("\xF9\x8B") + @utf8_softbank_only = utf8_softbank("\u{E524}") + @sjis_softbank_only = sjis_softbank("\xFB\xC4") + end end -end -def utf8(str) - str.force_encoding("UTF-8") -end + def utf8(str) + str.force_encoding("UTF-8") + end -def to_utf8(str) - str.encode("UTF-8") -end + def to_utf8(str) + str.encode("UTF-8") + end -def to_sjis(str) - str.encode("Windows-31J") -end + def to_sjis(str) + str.encode("Windows-31J") + end -def to_eucjp(str) - str.encode("eucJP-ms") -end + def to_eucjp(str) + str.encode("eucJP-ms") + end -def to_iso2022jp(str) - str.encode("ISO-2022-JP") -end + def to_iso2022jp(str) + str.encode("ISO-2022-JP") + end -def utf8_docomo(str) - str.force_encoding("UTF8-DoCoMo") -end + def utf8_docomo(str) + str.force_encoding("UTF8-DoCoMo") + end -def to_utf8_docomo(str) - str.encode("UTF8-DoCoMo") -end + def to_utf8_docomo(str) + str.encode("UTF8-DoCoMo") + end -def utf8_kddi(str) - str.force_encoding("UTF8-KDDI") -end + def utf8_kddi(str) + str.force_encoding("UTF8-KDDI") + end -def to_utf8_kddi(str) - str.encode("UTF8-KDDI") -end + def to_utf8_kddi(str) + str.encode("UTF8-KDDI") + end -def utf8_softbank(str) - str.force_encoding("UTF8-SoftBank") -end + def utf8_softbank(str) + str.force_encoding("UTF8-SoftBank") + end -def to_utf8_softbank(str) - str.encode("UTF8-SoftBank") -end + def to_utf8_softbank(str) + str.encode("UTF8-SoftBank") + end -def sjis_docomo(str) - str.force_encoding("SJIS-DoCoMo") -end + def sjis_docomo(str) + str.force_encoding("SJIS-DoCoMo") + end -def to_sjis_docomo(str) - str.encode("SJIS-DoCoMo") -end + def to_sjis_docomo(str) + str.encode("SJIS-DoCoMo") + end -def sjis_kddi(str) - str.force_encoding("SJIS-KDDI") -end + def sjis_kddi(str) + str.force_encoding("SJIS-KDDI") + end -def to_sjis_kddi(str) - str.encode("SJIS-KDDI") -end + def to_sjis_kddi(str) + str.encode("SJIS-KDDI") + end -def sjis_softbank(str) - str.force_encoding("SJIS-SoftBank") -end + def sjis_softbank(str) + str.force_encoding("SJIS-SoftBank") + end -def to_sjis_softbank(str) - str.encode("SJIS-SoftBank") -end + def to_sjis_softbank(str) + str.encode("SJIS-SoftBank") + end -def iso2022jp_kddi(str) - str.force_encoding("ISO-2022-JP-KDDI") -end + def iso2022jp_kddi(str) + str.force_encoding("ISO-2022-JP-KDDI") + end -def to_iso2022jp_kddi(str) - str.encode("ISO-2022-JP-KDDI") -end + def to_iso2022jp_kddi(str) + str.encode("ISO-2022-JP-KDDI") + end -def stateless_iso2022jp_kddi(str) - str.force_encoding("stateless-ISO-2022-JP-KDDI") -end + def stateless_iso2022jp_kddi(str) + str.force_encoding("stateless-ISO-2022-JP-KDDI") + end -def to_stateless_iso2022jp_kddi(str) - str.encode("stateless-ISO-2022-JP-KDDI") + def to_stateless_iso2022jp_kddi(str) + str.encode("stateless-ISO-2022-JP-KDDI") + end + end Index: mvm/test/ruby/test_enum.rb =================================================================== --- mvm/test/ruby/test_enum.rb (revision 26939) +++ mvm/test/ruby/test_enum.rb (revision 26940) @@ -311,38 +311,6 @@ assert_equal([2,1,3,2,1], @obj.reverse_each.to_a) end - def test_join - ofs = $, - assert_equal("abc", ("a".."c").join("")) - assert_equal("a-b-c", ("a".."c").join("-")) - $, = "-" - assert_equal("a-b-c", ("a".."c").join()) - $, = nil - assert_equal("abc", ("a".."c").join()) - assert_equal("123", (1..3).join()) - assert_raise(TypeError, '[ruby-core:24172]') {("a".."c").join(1)} - class << (e = Object.new.extend(Enumerable)) - def each - yield self - end - end - assert_raise(ArgumentError){e.join("")} - assert_raise(ArgumentError){[e].join("")} - e = Class.new { - include Enumerable - def initialize(*args) - @e = args - end - def each - @e.each {|e| yield e} - end - } - e = e.new(1, e.new(2, e.new(3, e.new(4, 5)))) - assert_equal("1:2:3:4:5", e.join(':'), '[ruby-core:24196]') - ensure - $, = ofs - end - def test_chunk e = [].chunk {|elt| true } assert_equal([], e.to_a) Index: mvm/test/ruby/test_file.rb =================================================================== --- mvm/test/ruby/test_file.rb (revision 26939) +++ mvm/test/ruby/test_file.rb (revision 26940) @@ -164,6 +164,10 @@ tst = realdir.sub(/#{Regexp.escape(File::SEPARATOR)}/, '\0\0\0') assert_equal(realdir, File.realpath(tst)) assert_equal(realdir, File.realpath(".", tst)) + if File::ALT_SEPARATOR + bug2961 = '[ruby-core:28653]' + assert_equal(realdir, File.realpath(realdir.tr(File::SEPARATOR, File::ALT_SEPARATOR)), bug2961) + end } end Index: mvm/test/ruby/test_io.rb =================================================================== --- mvm/test/ruby/test_io.rb (revision 26939) +++ mvm/test/ruby/test_io.rb (revision 26940) @@ -150,6 +150,16 @@ r.close end + def test_each_codepoint + t = make_tempfile + bug2959 = '[ruby-core:28650]' + a = "" + File.open(t, 'rt') {|f| + f.each_codepoint {|c| a << c} + } + assert_equal("foo\nbar\nbaz\n", a, bug2959) + end + def test_rubydev33072 assert_raise(Errno::ENOENT, "[ruby-dev:33072]") do File.read("empty", nil, nil, {}) @@ -1386,6 +1396,23 @@ assert_in_out_err(["-", t.path], "print while $<.gets", %w(foo bar baz), []) end + def test_print_separators + $, = ':' + $\ = "\n" + r, w = IO.pipe + w.print('a') + w.print('a','b','c') + w.close + assert_equal("a\n", r.gets) + assert_equal("a:b:c\n", r.gets) + assert_nil r.gets + r.close + + ensure + $, = nil + $\ = nil + end + def test_putc pipe(proc do |w| w.putc "A" Index: mvm/test/ruby/test_rand.rb =================================================================== --- mvm/test/ruby/test_rand.rb (revision 26939) +++ mvm/test/ruby/test_rand.rb (revision 26940) @@ -387,4 +387,14 @@ r2.rand(0x100) assert(r1 == r2) end + + def test_fork_shuffle + pid = fork do + (1..10).to_a.shuffle + raise 'default seed is not set' if srand == 0 + end + p2, st = Process.waitpid2(pid) + assert(st.success?) + rescue NotImplementedError, ArgumentError + end end Index: mvm/test/uri/test_common.rb =================================================================== --- mvm/test/uri/test_common.rb (revision 26939) +++ mvm/test/uri/test_common.rb (revision 26940) @@ -49,6 +49,31 @@ assert_equal(expected, Kernel::URI("http://www.ruby-lang.org/")) assert_raise(NoMethodError) { Object.new.URI("http://www.ruby-lang.org/") } end + + def test_encode_www_component + assert_equal("+%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_component(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~")) + end + + def test_decode_www_component + assert_equal(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~", + URI.decode_www_component( + "+%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")) + end + + def test_encode_www_form + assert_equal("a=1", URI.encode_www_form("a" => "1")) + assert_equal("a=1", URI.encode_www_form(a: 1)) + assert_equal("a=1", URI.encode_www_form([["a", "1"]])) + assert_equal("a=1", URI.encode_www_form([[:a, 1]])) + expected = "a=1&%E3%81%82=%E6%BC%A2" + assert_equal(expected, URI.encode_www_form("a" => "1", "\u3042" => "\u6F22")) + assert_equal(expected, URI.encode_www_form(a: 1, :"\u3042" => "\u6F22")) + assert_equal(expected, URI.encode_www_form([["a", "1"], ["\u3042", "\u6F22"]])) + assert_equal(expected, URI.encode_www_form([[:a, 1], [:"\u3042", "\u6F22"]])) + end end Index: mvm/file.c =================================================================== --- mvm/file.c (revision 26939) +++ mvm/file.c (revision 26940) @@ -2539,7 +2539,11 @@ #if defined __CYGWIN__ || defined DOSISH #define DOSISH_UNC #define DOSISH_DRIVE_LETTER -#define isdirsep(x) ((x) == '/' || (x) == '\\') +#define FILE_ALT_SEPARATOR '\\' +#endif +#ifdef FILE_ALT_SEPARATOR +#define isdirsep(x) ((x) == '/' || (x) == FILE_ALT_SEPARATOR) +static const char file_alt_separator[] = {FILE_ALT_SEPARATOR, '\0'}; #else #define isdirsep(x) ((x) == '/') #endif @@ -2735,8 +2739,6 @@ (void)(extenc || (extenc = rb_default_external_encoding())),\ rb_enc_associate(result, extenc)) -#define is_absolute_path(path) ruby_absolute_path_p(path) - VALUE rb_home_dir(const char *user, VALUE result) { @@ -2850,7 +2852,7 @@ } } #endif - else if (!is_absolute_path(s)) { + else if (!rb_is_absolute_path(s)) { if (!NIL_P(dname)) { file_expand_path(dname, Qnil, abs_mode, result); BUFINIT(); @@ -2881,7 +2883,7 @@ p = buf + (s - b); BUFCHECK(bdiff >= buflen); memset(buf, '/', p - buf); - rb_enc_copy(result, fname); + rb_enc_associate(result, rb_enc_check(result, fname)); } if (p > buf && p[-1] == '/') --p; @@ -3133,6 +3135,8 @@ static void realpath_rec(long *prefixlenp, VALUE *resolvedp, char *unresolved, VALUE loopcheck, int strict, int last) { + ID resolving; + CONST_ID(resolving, "resolving"); while (*unresolved) { char *testname = unresolved; char *unresolved_firstsep = rb_path_next(unresolved); @@ -3158,7 +3162,7 @@ rb_str_cat(testpath, testname, testnamelen); checkval = rb_hash_aref(loopcheck, testpath); if (!NIL_P(checkval)) { - if (checkval == ID2SYM(rb_intern("resolving"))) { + if (checkval == ID2SYM(resolving)) { errno = ELOOP; rb_sys_fail(RSTRING_PTR(testpath)); } @@ -3186,7 +3190,7 @@ volatile VALUE link; char *link_prefix, *link_names; long link_prefixlen; - rb_hash_aset(loopcheck, testpath, ID2SYM(rb_intern("resolving"))); + rb_hash_aset(loopcheck, testpath, ID2SYM(resolving)); link = rb_file_s_readlink(rb_cFile, testpath); link_prefix = RSTRING_PTR(link); link_names = skiproot(link_prefix); @@ -3221,9 +3225,9 @@ volatile VALUE unresolved_path; VALUE loopcheck; volatile VALUE curdir = Qnil; - + char *path_names = NULL, *basedir_names = NULL, *curdir_names = NULL; - char *ptr; + char *ptr, *prefixptr = NULL; rb_secure(2); @@ -3257,11 +3261,21 @@ resolved = rb_str_new(ptr, curdir_names - ptr); root_found: - ptr = chompdirsep(RSTRING_PTR(resolved)); + prefixptr = RSTRING_PTR(resolved); + prefixlen = RSTRING_LEN(resolved); + ptr = chompdirsep(prefixptr); if (*ptr) { - rb_str_set_len(resolved, ptr - RSTRING_PTR(resolved) + 1); + prefixlen = ++ptr - prefixptr; + rb_str_set_len(resolved, prefixlen); } - prefixlen = RSTRING_LEN(resolved); +#ifdef FILE_ALT_SEPARATOR + while (prefixptr < ptr) { + if (*prefixptr == FILE_ALT_SEPARATOR) { + *prefixptr = '/'; + } + prefixptr = CharNext(prefixptr); + } +#endif loopcheck = rb_hash_new(); if (curdir_names) @@ -3372,9 +3386,15 @@ long f, n; if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) { + rb_encoding *enc; StringValue(fext); + if (!rb_enc_asciicompat(enc = rb_enc_get(fext))) { + rb_raise(rb_eEncCompatError, "ascii incompatible character encodings: %s", + rb_enc_name(enc)); + } } FilePathStringValue(fname); + if (!NIL_P(fext)) rb_enc_check(fname, fext); if (RSTRING_LEN(fname) == 0 || !*(name = RSTRING_PTR(fname))) return rb_str_new_shared(fname); name = skipprefix(name); @@ -4745,7 +4765,7 @@ } int -ruby_absolute_path_p(const char *path) +rb_is_absolute_path(const char *path) { #ifdef DOSISH_DRIVE_LETTER if (has_drive_letter(path) && isdirsep(path[2])) return 1; @@ -4775,7 +4795,7 @@ const char *p0 = StringValueCStr(path); char *p = 0, *s; - if (!is_absolute_path(p0)) { + if (!rb_is_absolute_path(p0)) { char *buf = my_getcwd(); VALUE newpath; @@ -4912,7 +4932,7 @@ expanded = 1; } - if (expanded || is_absolute_path(f) || is_explicit_relative(f)) { + if (expanded || rb_is_absolute_path(f) || is_explicit_relative(f)) { if (safe_level >= 1 && !fpath_check(fname)) { rb_raise(rb_eSecurityError, "loading from unsafe path %s", f); } @@ -4983,7 +5003,7 @@ expanded = 1; } - if (expanded || is_absolute_path(f) || is_explicit_relative(f)) { + if (expanded || rb_is_absolute_path(f) || is_explicit_relative(f)) { if (safe_level >= 1 && !fpath_check(path)) { rb_raise(rb_eSecurityError, "loading from unsafe path %s", f); } @@ -5150,7 +5170,7 @@ rb_define_singleton_method(rb_cFile, "join", rb_file_s_join, -2); #ifdef DOSISH - rb_define_const(rb_cFile, "ALT_SEPARATOR", rb_obj_freeze(rb_usascii_str_new2("\\"))); + rb_define_const(rb_cFile, "ALT_SEPARATOR", rb_obj_freeze(rb_usascii_str_new2(file_alt_separator))); #else rb_define_const(rb_cFile, "ALT_SEPARATOR", Qnil); #endif Index: mvm/random.c =================================================================== --- mvm/random.c (revision 26939) +++ mvm/random.c (revision 26940) @@ -137,10 +137,6 @@ unsigned int *p = mt->state; int j; - /* if init_genrand() has not been called, */ - /* a default initial seed is used */ - if (!genrand_initialized(mt)) init_genrand(mt, 5489U); - mt->left = N; mt->next = mt->state; @@ -157,6 +153,7 @@ static unsigned int genrand_int32(struct MT *mt) { + /* mt must be initialized */ unsigned int y; if (--mt->left <= 0) next_state(mt); @@ -175,6 +172,7 @@ static double genrand_real(struct MT *mt) { + /* mt must be initialized */ unsigned int a = genrand_int32(mt)>>5, b = genrand_int32(mt)>>6; return(a*67108864.0+b)*(1.0/9007199254740992.0); } @@ -184,6 +182,7 @@ static double genrand_real2(struct MT *mt) { + /* mt must be initialized */ unsigned int a = genrand_int32(mt), b = genrand_int32(mt); return int_pair_to_real_inclusive(a, b); } @@ -217,23 +216,34 @@ #define DEFAULT_SEED_CNT 4 -struct Random { - rb_random_t rnd; - unsigned int initial[DEFAULT_SEED_CNT]; -}; - #define default_rand (*(rb_random_t *)DATA_PTR(*rb_vm_specific_ptr(rb_vmkey_default_rand))) +static VALUE rand_init(struct MT *mt, VALUE vseed); +static VALUE random_seed(void); + +static struct MT * +default_mt(void) +{ + rb_random_t *r = &default_rand; + struct MT *mt = &r->mt; + if (!genrand_initialized(mt)) { + r->seed = rand_init(mt, random_seed()); + } + return mt; +} + unsigned int rb_genrand_int32(void) { - return genrand_int32(&default_rand.mt); + struct MT *mt = default_mt(); + return genrand_int32(mt); } double rb_genrand_real(void) { - return genrand_real(&default_rand.mt); + struct MT *mt = default_mt(); + return genrand_real(mt); } #define BDIGITS(x) (RBIGNUM_DIGITS(x)) @@ -304,8 +314,6 @@ #define id_minus '-' #define id_plus '+' -static VALUE random_seed(void); - /* :nodoc: */ static void random_mark(void *ptr) @@ -759,6 +767,7 @@ static unsigned long limited_rand(struct MT *mt, unsigned long limit) { + /* mt must be initialized */ int i; unsigned long val, mask; @@ -780,6 +789,7 @@ static VALUE limited_big_rand(struct MT *mt, struct RBignum *limit) { + /* mt must be initialized */ unsigned long mask, lim, rnd; struct RBignum *val; long i, len; @@ -830,10 +840,7 @@ unsigned long rb_rand_internal(unsigned long i) { - struct MT *mt = &default_rand.mt; - if (!genrand_initialized(mt)) { - rand_init(mt, random_seed()); - } + struct MT *mt = default_mt(); return limited_rand(mt, i); } @@ -904,6 +911,7 @@ static VALUE rand_int(struct MT *mt, VALUE vmax, int restrictive) { + /* mt must be initialized */ long max; unsigned long r; @@ -1109,11 +1117,8 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj) { VALUE vmax, r; - struct MT *mt = &default_rand.mt; + struct MT *mt = default_mt(); - if (!genrand_initialized(mt)) { - rand_init(mt, random_seed()); - } if (argc == 0) goto zero_arg; rb_scan_args(argc, argv, "01", &vmax); if (NIL_P(vmax)) goto zero_arg; @@ -1126,20 +1131,26 @@ } static st_index_t hashseed; -static struct Random initial_rand; -static struct Random * -init_randomseed(struct Random *r) +static VALUE +init_randomseed(struct MT *mt, unsigned int initial[DEFAULT_SEED_CNT]) { - fill_random_seed(r->initial); - init_by_array(&r->rnd.mt, r->initial, DEFAULT_SEED_CNT); - return r; + VALUE seed; + fill_random_seed(initial); + init_by_array(mt, initial, DEFAULT_SEED_CNT); + seed = make_seed_value(initial); + memset(initial, 0, DEFAULT_SEED_LEN); + return seed; } void Init_RandomSeed(void) { - struct MT *mt = &init_randomseed(&initial_rand)->rnd.mt; + VALUE rv = *rb_vm_specific_ptr(rb_vmkey_default_rand) = random_alloc(0); + rb_random_t *r = DATA_PTR(rv); + unsigned int initial[DEFAULT_SEED_CNT]; + struct MT *mt = &r->mt; + VALUE seed = init_randomseed(mt, initial); hashseed = genrand_int32(mt); #if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8 @@ -1154,11 +1165,23 @@ hashseed <<= 32; hashseed |= genrand_int32(mt); #endif + + r->seed = seed; } void InitVM_RandomSeed(void) { + VALUE *rp = rb_vm_specific_ptr(rb_vmkey_default_rand), rv = *rp; + unsigned int initial[DEFAULT_SEED_CNT]; + rb_random_t *r; + + if (rv) return; /* main VM */ + *rp = rv = random_alloc(0); + r = DATA_PTR(rv); + init_randomseed(&r->mt, initial); + r->seed = make_seed_value(initial); + memset(initial, 0, DEFAULT_SEED_LEN); } st_index_t @@ -1168,24 +1191,13 @@ } static void -InitVM_RandomSeed2(void) +Init_RandomSeed2(void) { - unsigned int *ini, initial[DEFAULT_SEED_CNT]; - VALUE rv = random_alloc(0); - rb_random_t *r = DATA_PTR(rv); + VALUE seed = default_rand.seed; - *rb_vm_specific_ptr(rb_vmkey_default_rand) = rv; - if (initial_rand.rnd.seed) { - fill_random_seed(initial); - init_by_array(&r->mt, initial, DEFAULT_SEED_CNT); - ini = initial; + if (RB_TYPE_P(seed, T_BIGNUM)) { + RBASIC(seed)->klass = rb_cBignum; } - else { - *r = initial_rand.rnd; - initial_rand.rnd.seed = Qtrue; - ini = initial_rand.initial; - } - r->seed = make_seed_value(ini); } void @@ -1204,7 +1216,7 @@ void InitVM_Random(void) { - InitVM_RandomSeed2(); + Init_RandomSeed2(); rb_define_global_function("srand", rb_f_srand, -1); rb_define_global_function("rand", rb_f_rand, -1); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/