ruby-changes:15091
From: nobu <ko1@a...>
Date: Thu, 18 Mar 2010 04:45:52 +0900 (JST)
Subject: [ruby-changes:15091] Ruby:r26968 (mvm): * merged from trunk r26939:26967.
nobu 2010-03-18 04:45:21 +0900 (Thu, 18 Mar 2010) New Revision: 26968 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26968 Log: * merged from trunk r26939:26967. Added directories: branches/mvm/ext/tmpdir/ Modified files: branches/mvm/.merged-trunk-revision branches/mvm/ChangeLog branches/mvm/NEWS branches/mvm/compile.c branches/mvm/configure.in branches/mvm/enc/trans/chinese.trans branches/mvm/enc/trans/emoji.trans branches/mvm/enc/trans/single_byte.trans branches/mvm/ext/bigdecimal/bigdecimal.c branches/mvm/file.c branches/mvm/hash.c branches/mvm/include/ruby/encoding.h branches/mvm/include/ruby/ruby.h branches/mvm/iseq.c branches/mvm/lib/tmpdir.rb branches/mvm/lib/uri/common.rb branches/mvm/load.c branches/mvm/parse.y branches/mvm/prelude.rb branches/mvm/ruby.c branches/mvm/test/ruby/test_m17n_comb.rb branches/mvm/test/ruby/test_string.rb branches/mvm/test/uri/test_common.rb branches/mvm/tool/transcode-tblgen.rb branches/mvm/util.c branches/mvm/version.h branches/mvm/vm.c branches/mvm/vm_core.h branches/mvm/vm_eval.c branches/mvm/win32/win32.c Index: mvm/prelude.rb =================================================================== --- mvm/prelude.rb (revision 26967) +++ mvm/prelude.rb (revision 26968) @@ -22,17 +22,3 @@ } end end - -module Kernel - module_function - def require_relative(relative_feature) - c = caller.first - e = c.rindex(/:\d+:in /) - file = $` - if /\A\((.*)\)/ =~ file # eval, etc. - raise LoadError, "require_relative is called in #{$1}" - end - absolute_feature = File.join(File.dirname(File.realpath(file)), relative_feature) - require absolute_feature - end -end Index: mvm/include/ruby/ruby.h =================================================================== --- mvm/include/ruby/ruby.h (revision 26967) +++ mvm/include/ruby/ruby.h (revision 26968) @@ -1104,7 +1104,7 @@ NORETURN(void rb_exit(int)); NORETURN(void rb_notimplement(void)); -/* reports if `-w' specified */ +/* reports if `-W' specified */ PRINTF_ARGS(void rb_warning(const char*, ...), 1, 2); PRINTF_ARGS(void rb_compile_warning(const char *, int, const char*, ...), 3, 4); PRINTF_ARGS(void rb_sys_warning(const char*, ...), 1, 2); Index: mvm/include/ruby/encoding.h =================================================================== --- mvm/include/ruby/encoding.h (revision 26967) +++ mvm/include/ruby/encoding.h (revision 26968) @@ -95,6 +95,7 @@ VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *); VALUE rb_str_export_to_enc(VALUE, rb_encoding *); VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to); +VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts); /* index -> rb_encoding */ rb_encoding* rb_enc_from_index(int idx); @@ -197,7 +198,7 @@ #define ENC_DUMMY_FLAG (1<<24) #define ENC_INDEX_MASK (~(~0U<<24)) -#define ENC_TO_ENCINDEX(enc) ((enc)->ruby_encoding_index & ENC_INDEX_MASK) +#define ENC_TO_ENCINDEX(enc) (int)((enc)->ruby_encoding_index & ENC_INDEX_MASK) #define ENC_DUMMY_P(enc) ((enc)->ruby_encoding_index & ENC_DUMMY_FLAG) #define ENC_SET_DUMMY(enc) ((enc)->ruby_encoding_index |= ENC_DUMMY_FLAG) Index: mvm/configure.in =================================================================== --- mvm/configure.in (revision 26967) +++ mvm/configure.in (revision 26968) @@ -1349,9 +1349,9 @@ rb_cv_rshift_sign=yes, rb_cv_rshift_sign=no)]) if test "$rb_cv_rshift_sign" = yes; then - AC_DEFINE(RSHIFT(x,y), ((x)>>((int)y))) + AC_DEFINE(RSHIFT(x,y), ((x)>>(int)(y))) else - AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>(y)) : (x)>>(y))) + AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>(int)(y)) : (x)>>(int)(y))) fi test "$rb_cv_fcnt" = "not found" && rb_cv_fcnt="not found (OK if using GNU libc)" Index: mvm/ChangeLog =================================================================== --- mvm/ChangeLog (revision 26967) +++ mvm/ChangeLog (revision 26968) @@ -1,3 +1,132 @@ +Thu Mar 18 04:40:56 2010 Nobuyoshi Nakada <nobu@r...> + + * parse.y (rb_intern3): get rid of type-punning cast. + +Thu Mar 18 02:29:42 2010 Yusuke Endoh <mame@t...> + + * compile.c (iseq_build_body): add mark to jump table hash of case. + +Thu Mar 18 00:58:27 2010 NARUSE, Yui <naruse@r...> + + * util.c (ruby_strtod): Add support for Hexadecimal + floating-point expression [ruby-dev:40650] #2969 + +Thu Mar 18 00:00:58 2010 NARUSE, Yui <naruse@r...> + + * lib/uri/common.rb (URI#{en,de}code_www_form_component): + renamed from URI#{en,de}code_www_component. [ruby-dev:40672] + + * lib/uri/common.rb (URI#encode_www_form_component): %-encoded + element should have always two hex. + + * lib/uri/common.rb (URI#encode_www_form_component): + better treatment for ASCII incompatible encodings and + encodings whose lead byte may use 7bit. + + * lib/uri/common.rb (URI#decode_www_form_component): add %20. + + * lib/uri/common.rb (URI#decode_www_form_component): add + result's encoding as 2nd argument. + + * lib/uri/common.rb (URI#decode_www_form): added. + +Wed Mar 17 16:25:53 2010 Nobuyoshi Nakada <nobu@r...> + + * hash.c (rb_hash_aset): allow recursive key. [ruby-core:24648] + +Wed Mar 17 06:39:59 2010 Nobuyoshi Nakada <nobu@r...> + + * ruby.h (rb_warning, rb_sys_warning): fixed typo in rdoc. + [ruby-core:28696] + +Wed Mar 17 02:29:46 2010 Yusuke Endoh <mame@t...> + + * compile.c, iseq.c, ruby.c, vm.c, vm_core.h, vm_eval.c: add absolute + path field into rb_iseq_t. The field contains a string representing + a path to corresponding source file. or nil when the iseq is created + from -e, stdin, eval, etc. This field is used for require_relative. + [ruby-dev:40004] + + * load.c (rb_f_require_relative): add C implementation of + require_relative. + + * prelude.rb (require_relative): get rid of Ruby implementation of + require_relative. + +Wed Mar 17 01:24:01 2010 Yusuke Endoh <mame@t...> + + * parse.y (rb_intern3): prohibit Symbol with an invalid encoding. + [ruby-core:24621] + + * test/ruby/test_m17n_comb.rb: modify a test for above. + +Tue Mar 16 22:51:11 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: specialize for singleton mappings. + +Tue Mar 16 20:13:00 2010 Kenta Murata <mrkn@m...> + + * enc/trans/emoji.trans: added codepoints leading 0xf4 into + nomap_table. + +Tue Mar 16 17:33:30 2010 NARUSE, Yui <naruse@r...> + + * ext/bigdecimal/bigdecimal.c (VpCtoV): keep e's sign. + When e doesn't over flow e * BASE_FIG but overflow e * 10, + e will overflow. + +Tue Mar 16 17:18:44 2010 Nobuyoshi Nakada <nobu@r...> + + * include/ruby/encoding.h (rb_str_conv_enc_opts): missing prototype. + +Tue Mar 16 15:20:13 2010 Nobuyoshi Nakada <nobu@r...> + + * ext/tmpdir: split from lib/tmpdir.rb. + + * win32/win32.c (rb_w32_system_tmpdir): extracted from init_env. + + * win32/win32.c (rb_w32_getcwd): removed duplicated code. + +Tue Mar 16 14:06:13 2010 Nobuyoshi Nakada <nobu@r...> + + * include/ruby/encoding.h (ENC_TO_ENCINDEX): suppress warnings. + +Tue Mar 16 14:03:24 2010 Nobuyoshi Nakada <nobu@r...> + + * configure.in (RSHIFT): parenthesize the argument of cast instead + of the result. + +Tue Mar 16 11:23:42 2010 Nobuyoshi Nakada <nobu@r...> + + * file.c (file_expand_path): ignore dname if it has different + drive letter or UNC. + +Tue Mar 16 07:16:56 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: redundant loop removed. + +Tue Mar 16 07:01:43 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: refactored to use tree as memo key. + +Tue Mar 16 04:05:13 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: more info in generating macro names. + +Mon Mar 15 21:58:03 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: ActionMap#each_firstbyte inlined. + +Mon Mar 15 21:22:49 2010 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (transcode_tblgen): add valid_encoding + optional argument. + + * enc/trans/single_byte.trans use valid_encoding argument for + transcode_tblgen. + + * enc/trans/chinese.trans: ditto. + Mon Mar 15 18:33:36 2010 Nobuyoshi Nakada <nobu@r...> * random.c (default_rand): removed initial buffer. @@ -111,7 +240,7 @@ * tool/transcode-tblgen.rb: reject ambiguous mapping. - * enc/trans/single_byte.trans: remove ambiguous maping such as + * enc/trans/single_byte.trans: remove ambiguous mapping such as \xD6 -> U+05F2 and \xD6\xC7 -> U+FB1F in Windows-1255 Sat Mar 13 23:48:27 2010 Yukihiro Matsumoto <matz@r...> @@ -124,7 +253,7 @@ Sat Mar 13 17:48:43 2010 Nobuyoshi Nakada <nobu@r...> - * tool/file2lastrev.rb: refactord. fixed changed revision of git. + * tool/file2lastrev.rb: refactored. fixed changed revision of git. Sat Mar 13 15:44:20 2010 Yukihiro Matsumoto <matz@r...> @@ -465,7 +594,7 @@ Wed Mar 3 06:19:25 2010 Nobuyoshi Nakada <nobu@r...> - * win32/win32.c (signbig): defined. + * win32/win32.c (signbit): defined. * win32/Makefile.sub, symbian/setup (config.h): pack.c requires SIZEOF_INT*_T now. Index: mvm/enc/trans/chinese.trans =================================================================== --- mvm/enc/trans/chinese.trans (revision 26967) +++ mvm/enc/trans/chinese.trans (revision 26968) @@ -1,16 +1,18 @@ #include "transcode_data.h" <% - set_valid_byte_pattern 'GB2312', 'EUC-KR' - set_valid_byte_pattern 'GB12345', 'EUC-KR' + gb2312_valid_byte_pattern = ValidEncoding['EUC-KR'] + gb12345_valid_byte_pattern = ValidEncoding['EUC-KR'] transcode_tblgen "GB2312", "UTF-8", [["{00-7f}", :nomap]] + - citrus_decode_mapsrc("euc", 0x8080, "GB2312/UCS") + citrus_decode_mapsrc("euc", 0x8080, "GB2312/UCS"), + gb2312_valid_byte_pattern transcode_tblgen "GB12345", "UTF-8", [["{00-7f}", :nomap]] + - citrus_decode_mapsrc("euc", 0x8080, "GB12345/UCS") + citrus_decode_mapsrc("euc", 0x8080, "GB12345/UCS"), + gb12345_valid_byte_pattern transcode_tblgen "UTF-8", "GB2312", [["{00-7f}", :nomap]] + Index: mvm/enc/trans/emoji.trans =================================================================== --- mvm/enc/trans/emoji.trans (revision 26967) +++ mvm/enc/trans/emoji.trans (revision 26968) @@ -12,6 +12,7 @@ ["{ee-ef}{80-bf}{80-bf}", :nomap0], ["f0{90-bf}{80-bf}{80-bf}", :nomap0], ["{f1-f3}{80-bf}{80-bf}{80-bf}", :nomap0], + ["f4{80-8f}{80-bf}{80-bf}", :nomap0], ] companies = %w(DoCoMo KDDI SoftBank Unicode) Index: mvm/enc/trans/single_byte.trans =================================================================== --- mvm/enc/trans/single_byte.trans (revision 26967) +++ mvm/enc/trans/single_byte.trans (revision 26968) @@ -22,9 +22,8 @@ require(name.downcase + "-tbl") control1_if_needed = (name =~ /^ISO-8859/) ? CONTROL1_TO_UCS_TBL : [] 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.reject {|a, b| a.length != 2 }]) + code << transcode_tblgen(name, "UTF-8", [["{00-7f}", :nomap], *tbl_to_ucs.reject {|a, b| a.length != 2 }], '{00-ff}') code << "\n" code << transcode_tblgen("UTF-8", name, [["{00-7f}", :nomap], *tbl_to_ucs.map {|a,b| [b,a] }]) code Index: mvm/vm_core.h =================================================================== --- mvm/vm_core.h (revision 26967) +++ mvm/vm_core.h (revision 26968) @@ -158,6 +158,7 @@ VALUE type; /* instruction sequence type */ VALUE name; /* String: iseq name */ VALUE filename; /* file information where this sequence from */ + VALUE filepath; /* real file path or nil */ VALUE *iseq; /* iseq (insn number and openrads) */ VALUE *iseq_encoded; /* encoded iseq */ unsigned long iseq_size; @@ -537,11 +538,11 @@ } rb_thread_t; /* iseq.c */ -VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE); -VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE parent); -VALUE rb_iseq_new_main(NODE *node, VALUE filename); -VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE); -VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, const rb_compile_option_t*); +VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE); +VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent); +VALUE rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath); +VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE); +VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, const rb_compile_option_t*); VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line); VALUE rb_iseq_disasm(VALUE self); int rb_iseq_disasm_insn(VALUE str, VALUE *iseqval, size_t pos, rb_iseq_t *iseq, VALUE child); Index: mvm/iseq.c =================================================================== --- mvm/iseq.c (revision 26967) +++ mvm/iseq.c (revision 26968) @@ -96,6 +96,7 @@ RUBY_MARK_UNLESS_NULL(iseq->mark_ary); RUBY_MARK_UNLESS_NULL(iseq->name); RUBY_MARK_UNLESS_NULL(iseq->filename); + RUBY_MARK_UNLESS_NULL(iseq->filepath); RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack); RUBY_MARK_UNLESS_NULL(iseq->klass); RUBY_MARK_UNLESS_NULL(iseq->coverage); @@ -205,9 +206,11 @@ } } +VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict); + static VALUE prepare_iseq_build(rb_iseq_t *iseq, - VALUE name, VALUE filename, VALUE line_no, + VALUE name, VALUE filename, VALUE filepath, VALUE line_no, VALUE parent, VALUE type, VALUE block_opt, const rb_compile_option_t *option) { @@ -216,6 +219,7 @@ iseq->name = name; iseq->filename = filename; + iseq->filepath = filepath == Qnil ? Qnil : rb_realpath_internal(Qnil, filepath, 1); iseq->line_no = line_no; iseq->defined_method_id = 0; iseq->mark_ary = rb_ary_tmp_new(3); @@ -359,31 +363,31 @@ } VALUE -rb_iseq_new(NODE *node, VALUE name, VALUE filename, +rb_iseq_new(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent, VALUE type) { - return rb_iseq_new_with_opt(node, name, filename, INT2FIX(0), parent, type, + return rb_iseq_new_with_opt(node, name, filename, filepath, INT2FIX(0), parent, type, &COMPILE_OPTION_DEFAULT); } VALUE -rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE parent) +rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent) { - return rb_iseq_new_with_opt(node, name, filename, INT2FIX(0), parent, ISEQ_TYPE_TOP, + return rb_iseq_new_with_opt(node, name, filename, filepath, INT2FIX(0), parent, ISEQ_TYPE_TOP, &COMPILE_OPTION_DEFAULT); } VALUE -rb_iseq_new_main(NODE *node, VALUE filename) +rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath) { rb_thread_t *th = GET_THREAD(); VALUE parent = th->base_block->iseq->self; - return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), filename, INT2FIX(0), + return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), filename, filepath, INT2FIX(0), parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT); } static VALUE -rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename, VALUE line_no, +rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no, VALUE parent, VALUE type, VALUE bopt, const rb_compile_option_t *option) { @@ -393,28 +397,28 @@ GetISeqPtr(self, iseq); iseq->self = self; - prepare_iseq_build(iseq, name, filename, line_no, parent, type, bopt, option); + prepare_iseq_build(iseq, name, filename, filepath, line_no, parent, type, bopt, option); rb_iseq_compile_node(self, node); cleanup_iseq_build(iseq); return self; } VALUE -rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE filename, VALUE line_no, +rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no, VALUE parent, VALUE type, const rb_compile_option_t *option) { /* TODO: argument check */ - return rb_iseq_new_with_bopt_and_opt(node, name, filename, line_no, parent, type, + return rb_iseq_new_with_bopt_and_opt(node, name, filename, filepath, line_no, parent, type, Qfalse, option); } VALUE -rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE filename, VALUE line_no, +rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no, VALUE parent, VALUE type, VALUE bopt) { /* TODO: argument check */ - return rb_iseq_new_with_bopt_and_opt(node, name, filename, line_no, parent, type, + return rb_iseq_new_with_bopt_and_opt(node, name, filename, filepath, line_no, parent, type, bopt, &COMPILE_OPTION_DEFAULT); } @@ -428,7 +432,7 @@ VALUE iseqval = iseq_alloc(self); VALUE magic, version1, version2, format_type, misc; - VALUE name, filename, line_no; + VALUE name, filename, filepath, line_no; VALUE type, body, locals, args, exception; VALUE iseq_type; @@ -452,6 +456,7 @@ name = CHECK_STRING(rb_ary_entry(data, i++)); filename = CHECK_STRING(rb_ary_entry(data, i++)); + filepath = CHECK_STRING(rb_ary_entry(data, i++)); line_no = CHECK_INTEGER(rb_ary_entry(data, i++)); type = CHECK_SYMBOL(rb_ary_entry(data, i++)); @@ -494,7 +499,7 @@ } make_compile_option(&option, opt); - prepare_iseq_build(iseq, name, filename, line_no, + prepare_iseq_build(iseq, name, filename, filepath, line_no, parent, iseq_type, 0, &option); rb_iseq_build_from_ary(iseq, locals, args, exception, body); @@ -531,7 +536,7 @@ } VALUE -rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE line, VALUE opt) +rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE filepath, VALUE line, VALUE opt) { rb_compile_option_t option; const char *fn = StringValueCStr(file); @@ -542,11 +547,11 @@ if (th->base_block && th->base_block->iseq) { return rb_iseq_new_with_opt(node, th->base_block->iseq->name, - file, line, th->base_block->iseq->self, + file, filepath, line, th->base_block->iseq->self, ISEQ_TYPE_EVAL, &option); } else { - return rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, line, Qfalse, + return rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, filepath, line, Qfalse, ISEQ_TYPE_TOP, &option); } } @@ -554,21 +559,21 @@ VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line) { - return rb_iseq_compile_with_option(src, file, line, Qnil); + return rb_iseq_compile_with_option(src, file, Qnil, line, Qnil); } static VALUE iseq_s_compile(int argc, VALUE *argv, VALUE self) { - VALUE src, file = Qnil, line = INT2FIX(1), opt = Qnil; + VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil; rb_secure(1); - rb_scan_args(argc, argv, "13", &src, &file, &line, &opt); + rb_scan_args(argc, argv, "13", &src, &file, &path, &line, &opt); if (NIL_P(file)) file = rb_str_new2("<compiled>"); if (NIL_P(line)) line = INT2FIX(1); - return rb_iseq_compile_with_option(src, file, line, opt); + return rb_iseq_compile_with_option(src, file, path, line, opt); } static VALUE @@ -591,7 +596,7 @@ parser = rb_parser_new(); node = rb_parser_compile_file(parser, fname, f, NUM2INT(line)); make_compile_option(&option, opt); - return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file, line, Qfalse, + return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file, file, line, Qfalse, ISEQ_TYPE_TOP, &option); } @@ -1309,7 +1314,7 @@ /* * [:magic, :major_version, :minor_version, :format_type, :misc, - * :name, :filename, :line_no, :type, :locals, :args, + * :name, :filename, :filepath, :line_no, :type, :locals, :args, * :catch_table, :bytecode] */ rb_ary_push(val, rb_str_new2("YARVInstructionSequence/SimpleDataFormat")); @@ -1319,6 +1324,7 @@ rb_ary_push(val, misc); rb_ary_push(val, iseq->name); rb_ary_push(val, iseq->filename); + rb_ary_push(val, iseq->filepath); rb_ary_push(val, iseq->line_no); rb_ary_push(val, type); rb_ary_push(val, locals); Index: mvm/load.c =================================================================== --- mvm/load.c (revision 26967) +++ mvm/load.c (revision 26968) @@ -297,7 +297,7 @@ th->mild_compile_error++; node = (NODE *)rb_load_file(RSTRING_PTR(fname)); loaded = TRUE; - iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, Qfalse); + iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, fname, Qfalse); th->mild_compile_error--; rb_iseq_eval(iseq); } @@ -448,6 +448,19 @@ return rb_require_safe(fname, rb_safe_level()); } +VALUE +rb_f_require_relative(VALUE obj, VALUE fname) +{ + VALUE rb_current_realfilepath(void); + VALUE rb_file_s_dirname(VALUE klass, VALUE fname); + VALUE base = rb_current_realfilepath(); + if (NIL_P(base)) { + rb_raise(rb_eLoadError, "cannot infer basepath"); + } + base = rb_file_s_dirname(rb_cFile, base); + return rb_require_safe(rb_file_expand_path(fname, base), rb_safe_level()); +} + static int search_required(VALUE fname, volatile VALUE *path, int safe_level) { @@ -746,6 +759,7 @@ rb_define_global_function("load", rb_f_load, -1); rb_define_global_function("require", rb_f_require, 1); + rb_define_global_function("require_relative", rb_f_require_relative, 1); rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2); rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1); rb_define_global_function("autoload", rb_f_autoload, 2); Index: mvm/lib/uri/common.rb =================================================================== --- mvm/lib/uri/common.rb (revision 26967) +++ mvm/lib/uri/common.rb (revision 26968) @@ -729,49 +729,60 @@ # # 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) + # See URI.decode_www_form_component, URI.encode_www_form + def self.encode_www_form_component(str) if TBLENCWWWCOMP_.empty? 256.times do |i| case i when 0x20 TBLENCWWWCOMP_[' '] = '+' - when 0x2A, 0x2D, 0x2E, 0x30..0x39, 0x41..0x5A, 0x5F, 0x61..0x7A + # when 0x2A, 0x2D, 0x2E, 0x30..0x39, 0x41..0x5A, 0x5F, 0x61..0x7A else - TBLENCWWWCOMP_[i.chr] = '%%%X' % i + TBLENCWWWCOMP_[i.chr] = '%%%02X' % 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) + str = str.to_s + case str.encoding + when Encoding::ASCII_8BIT, Encoding::US_ASCII, Encoding::UTF_8 + str = str.dup.force_encoding(Encoding::ASCII_8BIT) + str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_) + when Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE + reg = Regexp.new('[^*\-.0-9A-Z_a-z]+'.encode(str.encoding)) + str = str.gsub(reg){ + $&.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_). + force_encoding(str.encoding) + } + else + if str.encoding.ascii_compatible? + str = str.gsub(/[^*\-.0-9A-Z_a-z]+/){ + $&.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_)} + else + str = str.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_) + end + end + str.force_encoding(Encoding::US_ASCII) 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) + # See URI.encode_www_form_component, URI.decode_www_form + def self.decode_www_form_component(str, enc=Encoding::UTF_8) 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 + 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 + TBLDECWWWCOMP_['+'] = ' ' if i == 0x20 end TBLDECWWWCOMP_.freeze end - str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_) + str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(Encoding::UTF_8) end # Generate URL-encoded form data from given +enum+. @@ -779,7 +790,7 @@ # 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 internally uses URI.encode_www_form_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 @@ -789,7 +800,7 @@ # # This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data # - # See URI.encode_www_component(str) + # See URI.encode_www_form_component, URI.decode_www_form def self.encode_www_form(enum) str = nil enum.each do |k,v| @@ -798,12 +809,43 @@ else str = ''.force_encoding(Encoding::US_ASCII) end - str << encode_www_component(k) + str << encode_www_form_component(k) str << '=' - str << encode_www_component(v) + str << encode_www_form_component(v) end str end + + # Decode URL-encoded form data from given +str+. + # + # This decodes application/x-www-form-urlencoded data + # and returns array of key-value array. + # This internally uses URI.decode_www_form_component. + # + # _charset_ hack is not supported now because the mapping from given charset + # to Ruby's encoding is not clear yet. + # see also http://www.w3.org/TR/html5/syntax.html#character-encodings-0 + # + # This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data + # + # ary = URI.decode_www_form("a=1&a=2&b=3") + # p ary #=> [['a', '1'], ['a', '2'], ['b', '3']] + # p ary.assoc('a').last #=> '1' + # p ary.assoc('b').last #=> '3' + # p ary.rassoc('a').last #=> '2' + # p Hash[ary] # => {"a"=>"2", "b"=>"3"} + # + # See URI.decode_www_form_component, URI.encode_www_form + def self.decode_www_form(str, enc=Encoding::UTF_8) + ary = [] + unless /\A\??(?<query>[^=;&]*=[^;&]*(?:[;&][^=;&]*=[^;&]*)*)\z/ =~ str + raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})" + end + query.scan(/([^=;&]+)=([^;&]*)/) do + ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)] + end + ary + end end module Kernel Index: mvm/lib/tmpdir.rb =================================================================== --- mvm/lib/tmpdir.rb (revision 26967) +++ mvm/lib/tmpdir.rb (revision 26968) @@ -5,37 +5,15 @@ # require 'fileutils' +begin + require 'tmpdir.so' +rescue LoadError +end class Dir - @@systmpdir = '/tmp' + @@systmpdir ||= '/tmp' - if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM and - begin - require 'Win32API' - true - rescue LoadError - end - CSIDL_LOCAL_APPDATA = 0x001c - max_pathlen = 260 - windir = "\0"*(max_pathlen+1) - begin - getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L') - raise RuntimeError if getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) != 0 - windir.rstrip! - rescue RuntimeError - begin - getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L') - rescue RuntimeError - getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L') - end - windir[getdir.call(windir, windir.size)..-1] = "" - end - windir.force_encoding(Dir.pwd.encoding) - temp = File.expand_path('temp', windir.untaint) - @@systmpdir = temp if File.directory?(temp) and File.writable?(temp) - end - ## # Returns the operating system's temporary file path. Index: mvm/compile.c =================================================================== --- mvm/compile.c (revision 26967) +++ mvm/compile.c (revision 26968) @@ -169,6 +169,9 @@ #define iseq_filename(iseq) \ (((rb_iseq_t*)DATA_PTR(iseq))->filename) +#define iseq_filepath(iseq) \ + (((rb_iseq_t*)DATA_PTR(iseq))->filepath) + #define NEW_ISEQVAL(node, name, type, line_no) \ new_child_iseq(iseq, node, name, 0, type, line_no) @@ -917,7 +920,7 @@ VALUE ret; debugs("[new_child_iseq]> ---------------------------------------\n"); - ret = rb_iseq_new_with_opt(node, name, iseq_filename(iseq->self), INT2FIX(line_no), + ret = rb_iseq_new_with_opt(node, name, iseq_filename(iseq->self), iseq_filepath(iseq->self), INT2FIX(line_no), parent, type, iseq->compile_data->option); debugs("[new_child_iseq]< ---------------------------------------\n"); iseq_add_mark_object(iseq, ret); @@ -5287,6 +5290,7 @@ rb_ary_store(op, i+1, (VALUE)label | 1); } argv[j] = op; + iseq_add_mark_object_compile_time(iseq, op); } break; default: Index: mvm/vm_eval.c =================================================================== --- mvm/vm_eval.c (revision 26967) +++ mvm/vm_eval.c (revision 26968) @@ -1711,6 +1711,16 @@ } } +VALUE +rb_current_realfilepath(void) +{ + rb_thread_t *th = GET_THREAD(); + rb_control_frame_t *cfp = th->cfp; + cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)); + if (cfp != 0) return cfp->iseq->filepath; + return Qnil; +} + void Init_vm_eval(void) { Index: mvm/win32/win32.c =================================================================== --- mvm/win32/win32.c (revision 26967) +++ mvm/win32/win32.c (revision 26968) @@ -430,6 +430,22 @@ #define numberof(array) (sizeof(array) / sizeof(*array)) +UINT +rb_w32_system_tmpdir(WCHAR *path, UINT len) +{ + static const WCHAR temp[] = L"temp"; + WCHAR *p; + + if (!get_special_folder(CSIDL_LOCAL_APPDATA, path)) { + if (get_system_directory(path, len)) return 0; + } + p = translate_wchar(path, L'\\', L'/'); + if (*(p - 1) != L'/') *p++ = L'/'; + if (p - path + numberof(temp) >= len) return 0; + memcpy(p, temp, sizeof(temp)); + return p - path + numberof(temp) - 1; +} + static void init_env(void) { @@ -484,15 +500,8 @@ if (!GetEnvironmentVariableW(TMPDIR, env, numberof(env)) && !GetEnvironmentVariableW(L"TMP", env, numberof(env)) && !GetEnvironmentVariableW(L"TEMP", env, numberof(env)) && - (get_special_folder(CSIDL_LOCAL_APPDATA, env) || - get_system_directory(env, numberof(env)))) { - static const WCHAR temp[] = L"temp"; - WCHAR *p = translate_wchar(env, L'\\', L'/'); - if (*(p - 1) != L'/') *p++ = L'/'; - if (p - env + numberof(temp) < numberof(env)) { - memcpy(p, temp, sizeof(temp)); - set_env_val(TMPDIR); - } + rb_w32_system_tmpdir(env, numberof(env))) { + set_env_val(TMPDIR); } #undef env @@ -3579,7 +3588,6 @@ rb_w32_getcwd(char *buffer, int size) { char *p = buffer; - char *bp; int len; len = GetCurrentDirectory(0, NULL); @@ -3610,11 +3618,7 @@ return NULL; } - for (bp = p; *bp != '\0'; bp = CharNext(bp)) { - if (*bp == '\\') { - *bp = '/'; - } - } + translate_char(p, '\\', '/'); return p; } Index: mvm/parse.y =================================================================== --- mvm/parse.y (revision 26967) +++ mvm/parse.y (revision 26968) @@ -9616,6 +9616,10 @@ str = (VALUE)&fake_str; rb_enc_associate(str, enc); + if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) { + rb_raise(rb_eEncodingError, "invalid encoding symbol"); + } + if (st_lookup(global_symbols.sym_id, str, &data)) return (ID)data; Index: mvm/util.c =================================================================== --- mvm/util.c (revision 26967) +++ mvm/util.c (revision 26968) @@ -2106,6 +2106,44 @@ } break2: if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') { + static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; + s0 = ++s; + adj = 0; + + while (*++s && (s1 = strchr(hexdigit, *s))) { + adj *= 16; + adj += (s1 - hexdigit) & 15; + } + + if (*s == '.') { + aadj = 1.; + while (*++s && (s1 = strchr(hexdigit, *s))) { + aadj /= 16; + adj += aadj * ((s1 - hexdigit) & 15); + } + } + + if (*s != 'P' && *s != 'p') { + s = s0; + goto ret; + } + + dsign = 0x2C - *++s; /* +: 2B, -: 2D */ + if (abs(dsign) != 1) { + s = s0; + goto ret; + } + + for (nd = 0, s++; (c = *s) >= '0' && c <= '9'; s++) { + nd *= 10; + nd += c; + nd -= '0'; + } + + dval(rv) = ldexp(adj, nd * dsign); + goto ret; + } nz0 = 1; while (*++s == '0') ; if (!*s) Index: mvm/ext/bigdecimal/bigdecimal.c =================================================================== --- mvm/ext/bigdecimal/bigdecimal.c (revision 26967) +++ mvm/ext/bigdecimal/bigdecimal.c (revision 26968) @@ -4045,6 +4045,7 @@ e = e * 10 + exp_chr[i] - '0'; if(es>e*((S_INT)BASE_FIG)) { exponent_overflow = 1; + e = es; break; } ++i; Index: mvm/ext/tmpdir/tmpdir.c =================================================================== --- mvm/ext/tmpdir/tmpdir.c (revision 0) +++ mvm/ext/tmpdir/tmpdir.c (revision 26968) @@ -0,0 +1,32 @@ +#include <ruby/ruby.h> +#include <ruby/encoding.h> + +#define numberof(array) (sizeof(array) / sizeof(*array)) + +#ifdef HAVE_RB_W32_SYSTEM_TMPDIR +UINT rb_w32_system_tmpdir(WCHAR *path, UINT len); +VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc); +#endif + +static VALUE +system_tmpdir(void) +{ +#ifdef HAVE_RB_W32_SYSTEM_TMPDIR + WCHAR path[_MAX_PATH]; + UINT len = rb_w32_system_tmpdir(path, numberof(path)); + if (!len) return Qnil; + return rb_w32_conv_from_wchar(path, rb_filesystem_encoding()); +#else + return rb_filesystem_str_new_cstr("/tmp"); +#endif +} + +/* + * sets Dir.@@systmpdir. + */ +void +Init_tmpdir(void) +{ + rb_cvar_set(rb_cDir, rb_intern_const("@@systmpdir"), + rb_obj_freeze(system_tmpdir())); +} Property changes on: mvm/ext/tmpdir/tmpdir.c ___________________________________________________________________ Name: svn:keywords + Author Id Revision Name: svn:eol-style + LF Index: mvm/ext/tmpdir/extconf.rb =================================================================== --- mvm/ext/tmpdir/extconf.rb (revision 0) +++ mvm/ext/tmpdir/extconf.rb (revision 26968) @@ -0,0 +1,6 @@ +case +when have_func("rb_w32_system_tmpdir") + ok = true # win32 +else +end +create_makefile("tmpdir") if ok Property changes on: mvm/ext/tmpdir/extconf.rb ___________________________________________________________________ Name: svn:keywords + Author Id Revision Name: svn:eol-style + LF Index: mvm/hash.c =================================================================== --- mvm/hash.c (revision 26967) +++ mvm/hash.c (revision 26968) @@ -1094,9 +1094,6 @@ { rb_hash_modify(hash); hash_update(hash, key); - if (hash == key) { - rb_raise(rb_eArgError, "recursive key for hash"); - } if (RHASH(hash)->ntbl->type == &identhash || rb_obj_class(key) != rb_cString) { st_insert(RHASH(hash)->ntbl, key, val); } Index: mvm/NEWS =================================================================== --- mvm/NEWS (revision 26967) +++ mvm/NEWS (revision 26968) @@ -313,6 +313,7 @@ * \d, \s, and \w are now ASCII only; use POSIX bracket classes and \p{} for Unicode semantics * $: no longer includes the current directory, use require_relative +* Symbol with an invalid encoding is forbidden to exist. === Compilation options Index: mvm/.merged-trunk-revision =================================================================== --- mvm/.merged-trunk-revision (revision 26967) +++ mvm/.merged-trunk-revision (revision 26968) @@ -1 +1 @@ -26939 +26967 Index: mvm/vm.c =================================================================== --- mvm/vm.c (revision 26967) +++ mvm/vm.c (revision 26968) @@ -1435,7 +1435,7 @@ { rb_thread_t *th = GET_THREAD(); const rb_control_frame_t *reg_cfp = th->cfp; - volatile VALUE iseqval = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP); + volatile VALUE iseqval = rb_iseq_new(0, filename, filename, filename, 0, ISEQ_TYPE_TOP); VALUE val; vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP, @@ -2304,7 +2304,7 @@ rb_thread_t *th = GET_THREAD(); rb_vm_t *vm = th->vm; VALUE filename = rb_str_new2("<main>"); - volatile VALUE iseqval = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP); + volatile VALUE iseqval = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP); volatile VALUE th_self; rb_iseq_t *iseq; Index: mvm/version.h =================================================================== --- mvm/version.h (revision 26967) +++ mvm/version.h (revision 26968) @@ -1,5 +1,5 @@ #define RUBY_VERSION "1.9.2" -#define RUBY_RELEASE_DATE "2010-03-15" +#define RUBY_RELEASE_DATE "2010-03-18" #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 15 +#define RUBY_RELEASE_DAY 18 #include "ruby/version.h" Index: mvm/ruby.c =================================================================== --- mvm/ruby.c (revision 26967) +++ mvm/ruby.c (revision 26968) @@ -1456,7 +1456,9 @@ } PREPARE_PARSE_MAIN({ - iseq = rb_iseq_new_main(tree, opt->script_name); + VALUE path = Qnil; + if (!opt->e_script && strcmp(opt->script, "-")) path = opt->script_name; + iseq = rb_iseq_new_main(tree, opt->script_name, path); }); if (opt->dump & DUMP_BIT(insns)) { Index: mvm/tool/transcode-tblgen.rb =================================================================== --- mvm/tool/transcode-tblgen.rb (revision 26967) +++ mvm/tool/transcode-tblgen.rb (revision 26968) @@ -81,18 +81,31 @@ alias == eql? end +class Branch + def initialize(byte_min, byte_max, child_tree) + @byte_min = byte_min + @byte_max = byte_max + @child_tree = child_tree + @hash = byte_min.hash ^ byte_max.hash ^ child_tree.hash + end + attr_reader :byte_min, :byte_max, :child_tree, :hash + + def eql?(other) + self.class == other.class && + @hash == other.hash && + @byte_min == other.byte_min && + @byte_max == other.byte_max && + @child_tree == other.child_tree + end + alias == eql? +end + class ActionMap - def self.parse_to_rects(hash) - h = {} - hash.each {|pat, action| - pat = pat.to_s - h[pat] = action - } - hash = h - + def self.parse_to_rects(mapping) rects = [] n = 0 - hash.each {|pat, action| + mapping.each {|pat, action| + pat = pat.to_s if /\A\s*\(empset\)\s*\z/ =~ pat next elsif /\A\s*\(empstr\)\s*\z/ =~ pat @@ -165,18 +178,18 @@ end def self.build_tree(rects) - expand("", rects) {|actions| + expand("", rects) {|prefix, actions| unambiguous_action(actions) } end - def self.parse(hash) - rects = parse_to_rects(hash) + def self.parse(mapping) + rects = parse_to_rects(mapping) tree = build_tree(rects) - self.new("", tree) + self.new(tree) end - def self.merge(*rects_list) + def self.merge_rects(*rects_list) if rects_list.length < 2 raise ArgumentError, "not enough arguments" end @@ -186,99 +199,122 @@ all_rects.concat rects.map {|min, max, action| [min, max, [i, action]] } } - tree = expand("", all_rects) {|actions| + tree = expand("", all_rects) {|prefix, actions| args = Array.new(rects_list.length) { [] } actions.each {|i, action| args[i] << action } - yield(args) + yield(prefix, *args) } - self.new("", tree) + self.new(tree) end + def self.merge(*mappings, &block) + merge_rects(*mappings.map {|m| parse_to_rects(m) }, &block) + end + 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 + #numsing = numreg = 0 + #rects.each {|min, max, action| if min == max then numsing += 1 else numreg += 1 end } + #puts "#{numsing} singleton mappings and #{numreg} region mappings." + singleton_rects = [] + region_rects = [] + rects.each {|rect| + min, max, action = rect + if min == max + singleton_rects << rect else - has_nonempty = true + region_rects << rect 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) + expand_rec(prefix, singleton_rects, region_rects, &block) + end + + def self.expand_rec(prefix, singleton_rects, region_rects, &block) + some_mapping = singleton_rects[0] || region_rects[0] + return [] if !some_mapping + if some_mapping[0].empty? + h = {} + (singleton_rects + region_rects).each {|min, max, action| + raise ArgumentError, "ambiguous pattern: #{prefix}" if !min.empty? + h[action] = true + } + actions = h.keys + act = block.call(prefix, actions) tree = Action.new(act) else tree = [] - each_firstbyte_range(prefix, rects) {|byte_min, byte_max, rects2| - prefix2 = prefix + each_firstbyte_range(prefix, singleton_rects, region_rects) {|byte_min, byte_max, s_rects2, r_rects2| if byte_min == byte_max - prefix2 += "%02X" % byte_min + prefix2 = prefix + "%02X" % byte_min else - prefix2 += "{%02X-%02X}" % [byte_min, byte_max] + prefix2 = prefix + "{%02X-%02X}" % [byte_min, byte_max] end - child_tree = expand(prefix2, rects2, &block) - tree << [byte_min, byte_max, child_tree] + child_tree = expand_rec(prefix2, s_rects2, r_rects2, &block) + tree << Branch.new(byte_min, byte_max, child_tree) } end return tree end - def self.each_firstbyte_range(prefix, rects) - a = [] + def self.each_firstbyte_range(prefix, singleton_rects, region_rects) index_from = {} - rects.each {|min, max, action| - raise ArgumentError, "emptyable pattern" if min.empty? + + singleton_ary = [] + singleton_rects.each {|seq, _, action| + raise ArgumentError, "ambiguous pattern: #{prefix}" if seq.empty? + seq_firstbyte = seq[0,2].to_i(16) + seq_rest = seq[2..-1] + singleton_ary << [seq_firstbyte, [seq_rest, seq_rest, action]] + index_from[seq_firstbyte] = true + index_from[seq_firstbyte+1] = true + } + + region_ary = [] + region_rects.each {|min, max, action| + raise ArgumentError, "ambiguous pattern: #{prefix}" if min.empty? 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]] + region_ary << [min_firstbyte, max_firstbyte, [min_rest, max_rest, action]] index_from[min_firstbyte] = true index_from[max_firstbyte+1] = true } - byte_from = {} + + byte_from = Array.new(index_from.size) 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| + + singleton_rects_hash = {} + singleton_ary.each {|seq_firstbyte, rest_elt| + i = index_from[seq_firstbyte] + (singleton_rects_hash[i] ||= []) << rest_elt + } + + region_rects_hash = {} + region_ary.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 + (region_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 + s_rects = singleton_rects_hash[i] + r_rects = region_rects_hash[i] + if s_rects || r_rects + yield byte_from[i], byte_from[i+1]-1, (s_rects || []), (r_rects || []) + end } end - def initialize(prefix, tree) - @prefix = prefix # just for debug + def initialize(tree) @tree = tree end - def hash - return @hash if defined? @hash - @hash = @tree.hash - end - - def eql?(other) - self.class == other.class && - @tree == other.instance_eval { @tree } - end - - alias == eql? - def inspect "\#<#{self.class}:" + @tree.inspect + @@ -290,8 +326,8 @@ when Action 0 else - tree.map {|byte_min, byte_max, child_tree| - max_input_length_rec(child_tree) + tree.map {|branch| + max_input_length_rec(branch.child_tree) }.max + 1 end end @@ -308,16 +344,6 @@ end 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 - } - } - end - OffsetsMemo = {} InfosMemo = {} @@ -422,7 +448,9 @@ code end - def generate_lookup_node(bytes_code, words_code, name, table) + def generate_lookup_node(name, table) + bytes_code = @bytes_code + words_code = @words_code offsets = [] infos = [] infomap = {} @@ -480,24 +508,29 @@ PostMemo = {} NextName = "a" - def generate_node(bytes_code, words_code, name_hint=nil) - if n = PreMemo[self] + def generate_node(name_hint=nil) + if n = PreMemo[@tree] return n end table = Array.new(0x100, :invalid) - each_firstbyte {|byte, rest| + @tree.each {|branch| + byte_min, byte_max, child_tree = branch.byte_min, branch.byte_max, branch.child_tree + rest = ActionMap.new(child_tree) if a = rest.empty_action - table[byte] = a + table.fill(a, byte_min..byte_max) 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) + if name_hint + name_hint2 = "#{name_hint}_#{byte_min == byte_max ? '%02X' % byte_min : '%02Xto%02X' % [byte_min, byte_max]}" + end + v = "/*BYTE_LOOKUP*/" + rest.gennode(@bytes_code, @words_code, name_hint2) + table.fill(v, byte_min..byte_max) end } if n = PostMemo[table] - return PreMemo[self] = n + return PreMemo[@tree] = n end if !name_hint @@ -505,16 +538,16 @@ NextName.succ! end - PreMemo[self] = PostMemo[table] = name_hint + PreMemo[@tree] = PostMemo[table] = name_hint - generate_lookup_node(bytes_code, words_code, name_hint, table) + generate_lookup_node(name_hint, table) name_hint end 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) + name = generate_node(name_hint) @bytes_code = nil @words_code = nil return name @@ -649,18 +682,20 @@ r end -def transcode_compile_tree(name, from, map) +def transcode_compile_tree(name, from, map, valid_encoding=nil) map = encode_utf8(map) h = {} map.each {|k, v| h[k] = v unless h[k] # use first mapping } - 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) + valid_encoding = ValidEncoding[from] if valid_encoding == nil + if valid_encoding + am = ActionMap.merge(h, {valid_encoding => :undef}) {|prefix, as1, as2| + a1 = as1.empty? ? nil : ActionMap.unambiguous_action(as1) + a2 = as2.empty? ? nil : ActionMap.unambiguous_action(as2) + if !a2 + raise "invalid mapping: #{prefix}" + end a1 || a2 } else @@ -675,7 +710,7 @@ TRANSCODERS = [] TRANSCODE_GENERATED_TRANSCODER_CODE = '' -def transcode_tbl_only(from, to, map) +def transcode_tbl_only(from, to, map, valid_encoding=nil) if VERBOSE_MODE if from.empty? || to.empty? STDERR.puts "converter for #{from.empty? ? to : from}" @@ -692,12 +727,12 @@ else tree_name = "from_#{id_from}_to_#{id_to}" end - real_tree_name, max_input = transcode_compile_tree(tree_name, from, map) + real_tree_name, max_input = transcode_compile_tree(tree_name, from, map, valid_encoding) return map, tree_name, real_tree_name, max_input end -def transcode_tblgen(from, to, map) - map, tree_name, real_tree_name, max_input = transcode_tbl_only(from, to, map) +def transcode_tblgen(from, to, map, valid_encoding=nil) + map, tree_name, real_tree_name, max_input = transcode_tbl_only(from, to, map, valid_encoding) transcoder_name = "rb_#{tree_name}" TRANSCODERS << transcoder_name input_unit_length = UnitLength[from] Index: mvm/test/ruby/test_string.rb =================================================================== --- mvm/test/ruby/test_string.rb (revision 26967) +++ mvm/test/ruby/test_string.rb (revision 26968) @@ -1385,6 +1385,15 @@ assert_equal(5.9742e24, S("5.9742e24").to_f) assert_equal(98.6, S("98.6 degrees").to_f) assert_equal(0.0, S("degrees 100.0").to_f) + assert_equal([ 0.0].pack('G'), [S(" 0.0").to_f].pack('G')) + assert_equal([-0.0].pack('G'), [S("-0.0").to_f].pack('G')) + assert_equal([ 0.0].pack('G'), [S(" 0x0p+0").to_f].pack('G')) + assert_equal([-0.0].pack('G'), [S("-0x0p+0").to_f].pack('G')) + assert_equal(1.0, S("0X1.P+0").to_f) + assert_equal(1024.0, S("0x1p+10").to_f) + assert_equal(0.0009765625, S("0x1p-10").to_f) + assert_equal(2.6881171418161356e+43, S("0x1.3494a9b171bf5p+144").to_f) + assert_equal(-3.720075976020836e-44, S("-0x1.a8c1f14e2af5dp-145").to_f) end def test_to_i Index: mvm/test/ruby/test_m17n_comb.rb =================================================================== --- mvm/test/ruby/test_m17n_comb.rb (revision 26967) +++ mvm/test/ruby/test_m17n_comb.rb (revision 26968) @@ -1040,10 +1040,12 @@ STRINGS.each {|s| if /\0/ =~ a(s) assert_raise(ArgumentError) { s.intern } - else + elsif s.valid_encoding? sym = s.intern assert_equal(s, sym.to_s, "#{encdump s}.intern.to_s") assert_equal(sym, s.to_sym) + else + assert_raise(EncodingError) { s.intern } end } end Index: mvm/test/uri/test_common.rb =================================================================== --- mvm/test/uri/test_common.rb (revision 26967) +++ mvm/test/uri/test_common.rb (revision 26968) @@ -50,16 +50,22 @@ 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" \ + def test_encode_www_form_component + assert_equal("%00+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \ "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E", - URI.encode_www_component(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~")) + URI.encode_www_form_component("\x00 !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~")) + assert_equal("%95%41", URI.encode_www_form_component( + "\x95\x41".force_encoding(Encoding::Shift_JIS))) + assert_equal("%30%42", URI.encode_www_form_component( + "\x30\x42".force_encoding(Encoding::UTF_16BE))) + assert_equal("%30%42", URI.encode_www_form_component( + "\x30\x42".force_encoding(Encoding::ISO_2022_JP))) 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" \ + def test_decode_www_form_component + assert_equal(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~", + URI.decode_www_form_component( + "%20+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \ "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E")) end @@ -74,6 +80,12 @@ assert_equal(expected, URI.encode_www_form([["a", "1"], ["\u3042", "\u6F22"]])) assert_equal(expected, URI.encode_www_form([[:a, 1], [:"\u3042", "\u6F22"]])) end + + def test_decode_www_form + assert_equal([%w[a 1], %w[a 2]], URI.decode_www_form("a=1&a=2")) + assert_equal([%w[a 1], ["\u3042", "\u6F22"]], + URI.decode_www_form("a=1&%E3%81%82=%E6%BC%A2")) + end end Index: mvm/file.c =================================================================== --- mvm/file.c (revision 26967) +++ mvm/file.c (revision 26968) @@ -2566,6 +2566,12 @@ # define CharNext(p) ((p) + 1) #endif +#if defined(DOSISH_UNC) +#define has_unc(buf) (isdirsep((buf)[0]) && isdirsep((buf)[1])) +#else +#define has_unc(buf) 0 +#endif + #ifdef DOSISH_DRIVE_LETTER static inline int has_drive_letter(const char *buf) @@ -2604,6 +2610,19 @@ } return drvcwd; } + +static inline int +not_same_drive(VALUE path, int drive) +{ + const char *p = RSTRING_PTR(path); + if (RSTRING_LEN(path) < 2) return 0; + if (has_drive_letter(p)) { + return TOLOWER(p[0]) != TOLOWER(drive); + } + else { + return has_unc(p); + } +} #endif static inline char * @@ -2829,7 +2848,7 @@ else { /* specified drive, but not full path */ int same = 0; - if (!NIL_P(dname)) { + if (!NIL_P(dname) || !not_same_drive(dname, s[0])) { file_expand_path(dname, Qnil, abs_mode, result); BUFINIT(); if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) { @@ -3217,8 +3236,8 @@ } } -static VALUE -realpath_internal(VALUE basedir, VALUE path, int strict) +VALUE +rb_realpath_internal(VALUE basedir, VALUE path, int strict) { long prefixlen; VALUE resolved; @@ -3306,7 +3325,7 @@ { VALUE path, basedir; rb_scan_args(argc, argv, "11", &path, &basedir); - return realpath_internal(basedir, path, 1); + return rb_realpath_internal(basedir, path, 1); } /* @@ -3326,7 +3345,7 @@ { VALUE path, basedir; rb_scan_args(argc, argv, "11", &path, &basedir); - return realpath_internal(basedir, path, 0); + return rb_realpath_internal(basedir, path, 0); } static size_t @@ -3458,7 +3477,7 @@ * File.dirname("/home/gumby/work/ruby.rb") #=> "/home/gumby/work" */ -static VALUE +VALUE rb_file_s_dirname(VALUE klass, VALUE fname) { const char *name, *root, *p; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/