From 1b0f90ca333ddbf7ed57eba28465fbb922daa957 Mon Sep 17 00:00:00 2001 From: matz Date: Fri, 7 May 2004 08:44:24 +0000 Subject: * parse.y (string_content): turn off NODE_NEWLINE flag to avoid unnecessary line trace for inlined expression. (ruby-bugs PR#1320) * numeric.c (flo_to_s): tweak output string based to preserve decimal point and to remove trailing zeros. [ruby-talk:97891] * string.c (rb_str_index_m): use unsigned comparison for T_FIXNUM search. [ruby-talk:97342] * hash.c (rb_hash_equal): returns true if two hashes have same set of key-value set. [ruby-talk:97559] * hash.c (rb_hash_eql): returns true if two hashes are equal and have same default values. * string.c (rb_str_equal): always returns true or false, never returns nil. [ruby-dev:23404] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6262 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 27 ++++++++++++++++++++ array.c | 60 +++++++++++++++++++++++++++++++------------ bignum.c | 3 +++ eval.c | 29 +++++++++++++++++---- ext/dbm/dbm.c | 20 +++++++++++---- ext/gdbm/gdbm.c | 24 ++++++++++++------ ext/iconv/charset_alias.rb | 4 +-- ext/sdbm/init.c | 20 +++++++++++---- gc.c | 4 +-- hash.c | 63 +++++++++++++++++++++++++++++++++------------- intern.h | 2 ++ io.c | 12 +++++++++ lib/delegate.rb | 31 ++++++++++++++--------- lib/logger.rb | 1 + lib/net/imap.rb | 5 +++- lib/tempfile.rb | 10 +++++--- misc/ruby-mode.el | 2 +- node.h | 1 + numeric.c | 34 ++++++++++--------------- object.c | 2 +- parse.y | 15 ++++++++--- string.c | 10 ++++---- 22 files changed, 270 insertions(+), 109 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b7b50b101..4648a0ebe7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -85,6 +85,12 @@ Tue Apr 27 14:43:32 2004 Nobuyoshi Nakada * common.mk: LIBURUBY_A is needed for extconf.rb even when cross-compiling. +Tue Apr 27 13:33:50 2004 Yukihiro Matsumoto + + * parse.y (string_content): turn off NODE_NEWLINE flag to avoid + unnecessary line trace for inlined expression. + (ruby-bugs PR#1320) + Tue Apr 27 08:15:13 2004 why the lucky stiff * lib/yaml/rubytypes.rb: passing Range tests. @@ -164,6 +170,14 @@ Thu Apr 22 04:17:57 2004 Nobuyoshi Nakada * parse.y (aref_args): should pass expanded list. [ruby-core:02793] +Thu Apr 22 01:12:57 2004 Yukihiro Matsumoto + + * numeric.c (flo_to_s): tweak output string based to preserve + decimal point and to remove trailing zeros. [ruby-talk:97891] + + * string.c (rb_str_index_m): use unsigned comparison for T_FIXNUM + search. [ruby-talk:97342] + Wed Apr 21 23:04:42 2004 Masatoshi SEKI * lib/rinda/rinda.rb, test/rinda/test_rinda.rb: check Hash tuple size. @@ -215,6 +229,14 @@ Mon Apr 19 20:58:44 Hirokazu Yamamoto * dir.c: Updated RDocs. +Mon Apr 19 18:11:15 2004 Yukihiro Matsumoto + + * hash.c (rb_hash_equal): returns true if two hashes have same set + of key-value set. [ruby-talk:97559] + + * hash.c (rb_hash_eql): returns true if two hashes are equal and + have same default values. + Mon Apr 19 08:19:11 2004 Doug Kearns * dln.c, io.c, pack.c, lib/benchmark.rb, lib/cgi.rb, lib/csv.rb, @@ -232,6 +254,11 @@ Mon Apr 19 08:14:18 2004 Dave Thomas * lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::find_body): Allow for #ifdef HAVE_PROTOTYPES +Fri Apr 16 17:04:07 2004 Yukihiro Matsumoto + + * string.c (rb_str_equal): always returns true or false, never + returns nil. [ruby-dev:23404] + Fri Apr 16 12:38:48 2004 Nobuyoshi Nakada * lib/drb/drb.rb (DRb::DRbUnknown::initialize): Exception#to_str is diff --git a/array.c b/array.c index 18d4b02bdd..d779f279a0 100644 --- a/array.c +++ b/array.c @@ -234,6 +234,50 @@ rb_values_new2(n, elts) return val; } +static void +ary_make_shared(ary) + VALUE ary; +{ + if (!FL_TEST(ary, ELTS_SHARED)) { + NEWOBJ(shared, struct RArray); + OBJSETUP(shared, rb_cArray, T_ARRAY); + + shared->len = RARRAY(ary)->len; + shared->ptr = RARRAY(ary)->ptr; + shared->aux.capa = RARRAY(ary)->aux.capa; + RARRAY(ary)->aux.shared = (VALUE)shared; + FL_SET(ary, ELTS_SHARED); + } +} + +static VALUE +ary_shared_array(klass, ary) + VALUE klass, ary; +{ + VALUE val = ary_alloc(klass); + + ary_make_shared(ary); + RARRAY(val)->ptr = RARRAY(ary)->ptr; + RARRAY(val)->len = RARRAY(ary)->len; + RARRAY(val)->aux.shared = RARRAY(ary)->aux.shared; + FL_SET(val, ELTS_SHARED); + return val; +} + +VALUE +rb_values_from_ary(ary) + VALUE ary; +{ + return ary_shared_array(rb_cValues, ary); +} + +VALUE +rb_ary_from_values(val) + VALUE val; +{ + return ary_shared_array(rb_cArray, val); +} + VALUE rb_assoc_new(car, cdr) VALUE car, cdr; @@ -500,22 +544,6 @@ rb_ary_pop(ary) return RARRAY(ary)->ptr[--RARRAY(ary)->len]; } -static void -ary_make_shared(ary) - VALUE ary; -{ - if (!FL_TEST(ary, ELTS_SHARED)) { - NEWOBJ(shared, struct RArray); - OBJSETUP(shared, rb_cArray, T_ARRAY); - - shared->len = RARRAY(ary)->len; - shared->ptr = RARRAY(ary)->ptr; - shared->aux.capa = RARRAY(ary)->aux.capa; - RARRAY(ary)->aux.shared = (VALUE)shared; - FL_SET(ary, ELTS_SHARED); - } -} - /* * call-seq: * array.shift => obj or nil diff --git a/bignum.c b/bignum.c index f56d5a6377..31a5f58c24 100644 --- a/bignum.c +++ b/bignum.c @@ -464,6 +464,9 @@ rb_cstr_to_inum(str, base, badcheck) } continue; } + else if (!ISASCII(c)) { + break; + } else if (isdigit(c)) { c -= '0'; } diff --git a/eval.c b/eval.c index 9f099cdca3..faff5e4442 100644 --- a/eval.c +++ b/eval.c @@ -2573,14 +2573,14 @@ svalue_to_mrhs(v, lhs) { VALUE tmp; - if (v == Qundef) return rb_ary_new2(0); + if (v == Qundef) return rb_values_new2(0, 0); tmp = rb_check_array_type(v); if (NIL_P(tmp)) { - return rb_ary_new3(1, v); + return rb_values_new(1, v); } /* no lhs means splat lhs only */ if (!lhs) { - return rb_ary_new3(1, v); + return rb_values_new(1, v); } return tmp; } @@ -2602,8 +2602,11 @@ static VALUE splat_value(v) VALUE v; { - if (NIL_P(v)) return rb_ary_new3(1, Qnil); - return rb_Array(v); + VALUE val; + + if (NIL_P(v)) val = rb_ary_new3(1, Qnil); + else val = rb_Array(v); + return rb_values_from_ary(val); } static VALUE @@ -3569,6 +3572,22 @@ rb_eval(self, n) } break; + case NODE_VALUES: + { + VALUE val; + long i; + + i = node->nd_alen; + val = rb_values_new2(i, 0); + for (i=0;node;node=node->nd_next) { + RARRAY(val)->ptr[i++] = rb_eval(self, node->nd_head); + RARRAY(val)->len = i; + } + + result = val; + } + break; + case NODE_STR: result = rb_str_new3(node->nd_lit); break; diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c index c422394405..1e4fe00fe7 100644 --- a/ext/dbm/dbm.c +++ b/ext/dbm/dbm.c @@ -280,6 +280,16 @@ fdbm_values_at(argc, argv, obj) return new; } +static void +fdbm_modify(obj) + VALUE obj; +{ + rb_secure(4); + if (OBJ_FROZEN_P(obj)) { + if (OBJ_FROZEN(obj)) rb_error_frozen("DBM"); + } +} + static VALUE fdbm_delete(obj, keystr) VALUE obj, keystr; @@ -289,7 +299,7 @@ fdbm_delete(obj, keystr) DBM *dbm; VALUE valstr; - rb_secure(4); + fdbm_modify(obj); StringValue(keystr); key.dptr = RSTRING(keystr)->ptr; key.dsize = RSTRING(keystr)->len; @@ -325,7 +335,7 @@ fdbm_shift(obj) DBM *dbm; VALUE keystr, valstr; - rb_secure(4); + fdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; dbmp->di_size = -1; @@ -351,7 +361,7 @@ fdbm_delete_if(obj) VALUE ret, ary = rb_ary_new(); int i, status = 0, n; - rb_secure(4); + fdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; n = dbmp->di_size; @@ -388,7 +398,7 @@ fdbm_clear(obj) struct dbmdata *dbmp; DBM *dbm; - rb_secure(4); + fdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; dbmp->di_size = -1; @@ -471,7 +481,7 @@ fdbm_store(obj, keystr, valstr) struct dbmdata *dbmp; DBM *dbm; - rb_secure(4); + fdbm_modify(obj); keystr = rb_obj_as_string(keystr); key.dptr = RSTRING(keystr)->ptr; diff --git a/ext/gdbm/gdbm.c b/ext/gdbm/gdbm.c index ee56fbf5d1..705cecfa97 100644 --- a/ext/gdbm/gdbm.c +++ b/ext/gdbm/gdbm.c @@ -387,6 +387,16 @@ fgdbm_values_at(argc, argv, obj) return new; } +static void +rb_gdbm_modify(obj) + VALUE obj; +{ + rb_secure(4); + if (OBJ_FROZEN_P(obj)) { + if (OBJ_FROZEN(obj)) rb_error_frozen("GDBM"); + } +} + static VALUE rb_gdbm_delete(obj, keystr) VALUE obj, keystr; @@ -395,7 +405,7 @@ rb_gdbm_delete(obj, keystr) struct dbmdata *dbmp; GDBM_FILE dbm; - rb_secure(4); + rb_gdbm_modify(obj); StringValue(keystr); key.dptr = RSTRING(keystr)->ptr; key.dsize = RSTRING(keystr)->len; @@ -436,7 +446,7 @@ fgdbm_shift(obj) GDBM_FILE dbm; VALUE keystr, valstr; - rb_secure(4); + rb_gdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; @@ -458,7 +468,7 @@ fgdbm_delete_if(obj) VALUE ret, ary = rb_ary_new(); int i, status = 0, n; - rb_secure(4); + rb_gdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; n = dbmp->di_size; @@ -489,7 +499,7 @@ fgdbm_clear(obj) struct dbmdata *dbmp; GDBM_FILE dbm; - rb_secure(4); + rb_gdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; dbmp->di_size = -1; @@ -588,7 +598,7 @@ fgdbm_store(obj, keystr, valstr) struct dbmdata *dbmp; GDBM_FILE dbm; - rb_secure(4); + rb_gdbm_modify(obj); StringValue(keystr); key.dptr = RSTRING(keystr)->ptr; key.dsize = RSTRING(keystr)->len; @@ -830,7 +840,7 @@ fgdbm_reorganize(obj) struct dbmdata *dbmp; GDBM_FILE dbm; - rb_secure(4); + rb_gdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; gdbm_reorganize(dbm); @@ -844,7 +854,7 @@ fgdbm_sync(obj) struct dbmdata *dbmp; GDBM_FILE dbm; - rb_secure(4); + rb_gdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; gdbm_sync(dbm); diff --git a/ext/iconv/charset_alias.rb b/ext/iconv/charset_alias.rb index 458dc89d4a..f1563b0dff 100644 --- a/ext/iconv/charset_alias.rb +++ b/ext/iconv/charset_alias.rb @@ -43,7 +43,7 @@ def charset_alias(config_charset, mapfile, target = OS) st = Hash.new(0) map = map.sort.collect do |can, *sys| if sys.grep(/^en_us(?=.|$)/i) {break true} == true - noen = %r"^(?!en_us)\w+_\w+#{Regexp.new($')}$"i + noen = %r"^(?!en_us)\w+_\w+#{Regexp.new($')}$"i #" sys.reject! {|s| noen =~ s} end sys = sys.first @@ -67,7 +67,7 @@ def charset_alias(config_charset, mapfile, target = OS) else sys = "'#{sys}'.freeze" end - f.puts(" charset_map['#{can}'.freeze] = #{sys}") + f.puts(" charset_map['#{can}'] = #{sys}") end f.puts("end") end diff --git a/ext/sdbm/init.c b/ext/sdbm/init.c index 4352d21f9c..77b27afe5b 100644 --- a/ext/sdbm/init.c +++ b/ext/sdbm/init.c @@ -268,6 +268,16 @@ fsdbm_values_at(argc, argv, obj) return new; } +static void +fdbm_modify(obj) + VALUE obj; +{ + rb_secure(4); + if (OBJ_FROZEN_P(obj)) { + if (OBJ_FROZEN(obj)) rb_error_frozen("SDBM"); + } +} + static VALUE fsdbm_delete(obj, keystr) VALUE obj, keystr; @@ -277,7 +287,7 @@ fsdbm_delete(obj, keystr) DBM *dbm; VALUE valstr; - rb_secure(4); + fdbm_modify(obj); StringValue(keystr); key.dptr = RSTRING(keystr)->ptr; key.dsize = RSTRING(keystr)->len; @@ -314,7 +324,7 @@ fsdbm_shift(obj) DBM *dbm; VALUE keystr, valstr; - rb_secure(4); + fdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; @@ -342,7 +352,7 @@ fsdbm_delete_if(obj) VALUE ret, ary = rb_ary_new(); int i, status = 0, n; - rb_secure(4); + fdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; n = dbmp->di_size; @@ -378,7 +388,7 @@ fsdbm_clear(obj) struct dbmdata *dbmp; DBM *dbm; - rb_secure(4); + fdbm_modify(obj); GetDBM(obj, dbmp); dbm = dbmp->di_dbm; dbmp->di_size = -1; @@ -466,7 +476,7 @@ fsdbm_store(obj, keystr, valstr) return Qnil; } - rb_secure(4); + fdbm_modify(obj); keystr = rb_obj_as_string(keystr); key.dptr = RSTRING(keystr)->ptr; diff --git a/gc.c b/gc.c index 2c4bb6d96f..def4acb3bb 100644 --- a/gc.c +++ b/gc.c @@ -1718,12 +1718,10 @@ rb_gc_copy_finalizer(dest, obj) if (!finalizer_table) return; if (!FL_TEST(obj, FL_FINALIZE)) return; - if (FL_TEST(dest, FL_FINALIZE)) { - rb_warn("copy_finalizer: discarding old finalizers"); - } if (st_lookup(finalizer_table, obj, &table)) { st_insert(finalizer_table, dest, table); } + RBASIC(dest)->flags |= FL_FINALIZE; } static VALUE diff --git a/hash.c b/hash.c index 9c2a156371..b078d168eb 100644 --- a/hash.c +++ b/hash.c @@ -1391,6 +1391,35 @@ equal_i(key, val1, data) return ST_CONTINUE; } +static VALUE +hash_equal(hash1, hash2, eql) + VALUE hash1, hash2; + int eql; /* compare default value if true */ +{ + struct equal_data data; + + if (hash1 == hash2) return Qtrue; + if (TYPE(hash2) != T_HASH) { + if (!rb_respond_to(hash2, rb_intern("to_hash"))) { + return Qfalse; + } + return rb_equal(hash2, hash1); + } + if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries) + return Qfalse; + if (eql) { + if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) && + FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT))) + return Qfalse; + } + + data.tbl = RHASH(hash2)->tbl; + data.result = Qtrue; + st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data); + + return data.result; +} + /* * call-seq: * hsh == other_hash => true or false @@ -1414,26 +1443,23 @@ static VALUE rb_hash_equal(hash1, hash2) VALUE hash1, hash2; { - struct equal_data data; - - if (hash1 == hash2) return Qtrue; - if (TYPE(hash2) != T_HASH) { - if (!rb_respond_to(hash2, rb_intern("to_hash"))) { - return Qfalse; - } - return rb_equal(hash2, hash1); - } - if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries) - return Qfalse; - if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) && - FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT))) - return Qfalse; + return hash_equal(hash1, hash2, Qfalse); +} - data.tbl = RHASH(hash2)->tbl; - data.result = Qtrue; - st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data); +/* + * call-seq: + * hsh.eql?(other_hash) => true or false + * + * Returns true if two hashes are equal, i.e they have same key-value set, + * and same default values. + * + */ - return data.result; +static VALUE +rb_hash_eql(hash1, hash2) + VALUE hash1, hash2; +{ + return hash_equal(hash1, hash2, Qtrue); } static int @@ -2365,6 +2391,7 @@ Init_Hash() rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0); rb_define_method(rb_cHash,"==", rb_hash_equal, 1); + rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1); rb_define_method(rb_cHash,"[]", rb_hash_aref, 1); rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1); rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2); diff --git a/intern.h b/intern.h index feafc9ffed..6575a61cad 100644 --- a/intern.h +++ b/intern.h @@ -32,6 +32,8 @@ VALUE rb_ary_new3 __((long,...)); VALUE rb_ary_new4 _((long, const VALUE *)); VALUE rb_values_new __((long,...)); VALUE rb_values_new2 _((long, const VALUE *)); +VALUE rb_values_from_ary _((VALUE)); +VALUE rb_ary_from_values _((VALUE)); VALUE rb_ary_freeze _((VALUE)); VALUE rb_ary_aref _((int, VALUE*, VALUE)); void rb_ary_store _((VALUE, long, VALUE)); diff --git a/io.c b/io.c index bd4dce0a72..9765fa7566 100644 --- a/io.c +++ b/io.c @@ -2396,15 +2396,27 @@ rb_fdopen(fd, mode) { FILE *file; +#if defined(sun) + errno = 0; +#endif file = fdopen(fd, mode); if (!file) { +#if defined(sun) + if (errno == 0 || errno == EMFILE || errno == ENFILE) { +#else if (errno == EMFILE || errno == ENFILE) { +#endif rb_gc(); +#if defined(sun) + errno = 0; +#endif file = fdopen(fd, mode); } if (!file) { #ifdef _WIN32 if (errno == 0) errno = EINVAL; +#elif defined(sun) + if (errno == 0) errno = EMFILE; #endif rb_sys_fail(0); } diff --git a/lib/delegate.rb b/lib/delegate.rb index 6e2637393f..60d3afe151 100644 --- a/lib/delegate.rb +++ b/lib/delegate.rb @@ -87,20 +87,27 @@ def DelegateClass(superclass) methods = superclass.public_instance_methods(true) methods -= ::Kernel.public_instance_methods(false) methods |= ["to_s","to_a","inspect","==","=~","==="] - klass.module_eval <<-EOS - def initialize(obj) - @_dc_obj = obj - end - def __getobj__ - @_dc_obj - end - def __setobj__(obj) - @_dc_obj = obj - end - EOS + klass.module_eval { + def initialize(obj) + @_dc_obj = obj + end + def method_missing(m, *args) + p [m, *args] + unless @_dc_obj.respond_to?(m) + super(m, *args) + end + @_dc_obj.__send__(m, *args) + end + def __getobj__ + @_dc_obj + end + def __setobj__(obj) + @_dc_obj = obj + end + } for method in methods begin - klass.module_eval <<-EOS + klass.module_eval <<-EOS, __FILE__, __LINE__+1 def #{method}(*args, &block) begin @_dc_obj.__send__(:#{method}, *args, &block) diff --git a/lib/logger.rb b/lib/logger.rb index 988ea24f11..363e9774b4 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -539,6 +539,7 @@ private def create_logfile(filename) logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT)) + logdev.sync = true add_log_header(logdev) logdev end diff --git a/lib/net/imap.rb b/lib/net/imap.rb index 0845009813..bfb677f22d 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -3195,7 +3195,8 @@ EOF end parser = GetoptLong.new - parser.set_options(['--help', GetoptLong::NO_ARGUMENT], + parser.set_options(['--debug', GetoptLong::NO_ARGUMENT], + ['--help', GetoptLong::NO_ARGUMENT], ['--port', GetoptLong::REQUIRED_ARGUMENT], ['--user', GetoptLong::REQUIRED_ARGUMENT], ['--auth', GetoptLong::REQUIRED_ARGUMENT]) @@ -3208,6 +3209,8 @@ EOF $user = arg when "--auth" $auth = arg + when "--debug" + Net::IMAP.debug = true when "--help" usage exit(1) diff --git a/lib/tempfile.rb b/lib/tempfile.rb index 38a72e1255..9333505178 100644 --- a/lib/tempfile.rb +++ b/lib/tempfile.rb @@ -108,9 +108,13 @@ class Tempfile < DelegateClass(File) # file. def unlink # keep this order for thread safeness - File.unlink(@tmpname) if File.exist?(@tmpname) - @@cleanlist.delete(@tmpname) - @tmpname = nil + begin + File.unlink(@tmpname) if File.exist?(@tmpname) + @@cleanlist.delete(@tmpname) + @tmpname = nil + rescue Errno::EACCESS + # may not be able to unlink on Windows; just ignore + end end alias delete unlink diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index 1972003059..4d1174ba63 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -325,7 +325,7 @@ The variable ruby-indent-level controls the amount of indentation. (looking-at ruby-block-op-re) (looking-at ruby-block-mid-re)) (goto-char (match-end 0)) - (looking-at "\\>")) + (not (looking-at "\\s_"))) ((eq option 'expr-qstr) (looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]")) ((eq option 'expr-re) diff --git a/node.h b/node.h index da71ee7070..c994961bad 100644 --- a/node.h +++ b/node.h @@ -62,6 +62,7 @@ enum node_type { NODE_ZSUPER, NODE_ARRAY, NODE_ZARRAY, + NODE_VALUES, NODE_HASH, NODE_RETURN, NODE_YIELD, diff --git a/numeric.c b/numeric.c index bcd6599a86..f7439ec34b 100644 --- a/numeric.c +++ b/numeric.c @@ -490,37 +490,29 @@ flo_to_s(flt) VALUE flt; { char buf[32]; - char *fmt = "%.15g"; + char *fmt = "%.15f"; double value = RFLOAT(flt)->value; double avalue, d1, d2; + char *p, *e; if (isinf(value)) return rb_str_new2(value < 0 ? "-Infinity" : "Infinity"); else if(isnan(value)) return rb_str_new2("NaN"); - + avalue = fabs(value); - if (avalue == 0.0) { - fmt = "%.1f"; - } - else if (avalue < 1.0e-3) { - d1 = avalue; - while (d1 < 1.0) d1 *= 10.0; - d1 = modf(d1, &d2); - if (d1 == 0) fmt = "%.1e"; - } - else if (avalue >= 1.0e15) { - d1 = avalue; - while (d1 > 10.0) d1 /= 10.0; - d1 = modf(d1, &d2); - if (d1 == 0) fmt = "%.1e"; - else fmt = "%.16e"; + if (avalue < 1.0e-7 || avalue >= 1.0e15) { + fmt = "%.16e"; } - else if ((d1 = modf(value, &d2)) == 0) { - fmt = "%.1f"; - } sprintf(buf, fmt, value); - + if (!(e = strchr(buf, 'e'))) { + e = buf + strlen(buf); + } + p = e; + while (*--p=='0') + ; + if (*p == '.') *p++; + memmove(p+1, e, strlen(e)+1); return rb_str_new2(buf); } diff --git a/object.c b/object.c index 2ceb5b0349..95d00a9732 100644 --- a/object.c +++ b/object.c @@ -262,7 +262,7 @@ rb_obj_clone(obj) } clone = rb_obj_alloc(rb_obj_class(obj)); RBASIC(clone)->klass = rb_singleton_class_clone(obj); - RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~FL_FREEZE; + RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE); init_copy(clone, obj); RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE; diff --git a/parse.y b/parse.y index 09d2a67a55..03369ea242 100644 --- a/parse.y +++ b/parse.y @@ -1455,7 +1455,8 @@ primary : literal } | tLPAREN compstmt ')' { - $$ = $2; + if (!$2) $$ = NEW_NIL(); + else $$ = $2; } | primary_value tCOLON2 tCONSTANT { @@ -2090,6 +2091,7 @@ string_content : tSTRING_CONTENT lex_strterm = $2; COND_LEXPOP(); CMDARG_LEXPOP(); + FL_UNSET($3, NODE_NEWLINE); $$ = new_evstr($3); } ; @@ -5432,10 +5434,15 @@ ret_args(node) { if (node) { no_blockarg(node); - if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) { - node = node->nd_head; + if (nd_type(node) == NODE_ARRAY) { + if (node->nd_next == 0) { + node = node->nd_head; + } + else { + nd_set_type(node, NODE_VALUES); + } } - else if (node && nd_type(node) == NODE_SPLAT) { + else if (nd_type(node) == NODE_SPLAT) { node = NEW_SVALUE(node); } } diff --git a/string.c b/string.c index 2f11e9bee6..c30aaf78b9 100644 --- a/string.c +++ b/string.c @@ -888,7 +888,7 @@ rb_str_equal(str1, str2) if (str1 == str2) return Qtrue; if (TYPE(str2) != T_STRING) { if (!rb_respond_to(str2, rb_intern("to_str"))) { - return Qnil; + return Qfalse; } return rb_equal(str2, str1); } @@ -1080,7 +1080,7 @@ rb_str_index_m(argc, argv, str) { int c = FIX2INT(sub); long len = RSTRING(str)->len; - char *p = RSTRING(str)->ptr; + unsigned char *p = RSTRING(str)->ptr; for (;posptr + pos; - char *pbeg = RSTRING(str)->ptr; + unsigned char *p = RSTRING(str)->ptr + pos; + unsigned char *pbeg = RSTRING(str)->ptr; if (pos == RSTRING(str)->len) { if (pos == 0) return Qnil; --p; } while (pbeg <= p) { - if (*p == c) return LONG2NUM(p - RSTRING(str)->ptr); + if (*p == c) return LONG2NUM((char*)p - RSTRING(str)->ptr); p--; } return Qnil; -- cgit v1.2.3