* 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
This commit is contained in:
matz 2004-05-07 08:44:24 +00:00
parent c4216a26e2
commit 1b0f90ca33
22 changed files with 272 additions and 111 deletions

View File

@ -85,6 +85,12 @@ Tue Apr 27 14:43:32 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* common.mk: LIBURUBY_A is needed for extconf.rb even when * common.mk: LIBURUBY_A is needed for extconf.rb even when
cross-compiling. cross-compiling.
Tue Apr 27 13:33:50 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <why@ruby-lang.org> Tue Apr 27 08:15:13 2004 why the lucky stiff <why@ruby-lang.org>
* lib/yaml/rubytypes.rb: passing Range tests. * lib/yaml/rubytypes.rb: passing Range tests.
@ -164,6 +170,14 @@ Thu Apr 22 04:17:57 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (aref_args): should pass expanded list. [ruby-core:02793] * parse.y (aref_args): should pass expanded list. [ruby-core:02793]
Thu Apr 22 01:12:57 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <m_seki@mva.biglobe.ne.jp> Wed Apr 21 23:04:42 2004 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* lib/rinda/rinda.rb, test/rinda/test_rinda.rb: check Hash tuple size. * 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 <ocean@m2.ccsnet.ne.jp>
* dir.c: Updated RDocs. * dir.c: Updated RDocs.
Mon Apr 19 18:11:15 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <djkea2@mugca.its.monash.edu.au> Mon Apr 19 08:19:11 2004 Doug Kearns <djkea2@mugca.its.monash.edu.au>
* dln.c, io.c, pack.c, lib/benchmark.rb, lib/cgi.rb, lib/csv.rb, * 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 <dave@pragprog.com>
* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::find_body): Allow for * lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::find_body): Allow for
#ifdef HAVE_PROTOTYPES #ifdef HAVE_PROTOTYPES
Fri Apr 16 17:04:07 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <nobu@ruby-lang.org> Fri Apr 16 12:38:48 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/drb/drb.rb (DRb::DRbUnknown::initialize): Exception#to_str is * lib/drb/drb.rb (DRb::DRbUnknown::initialize): Exception#to_str is

60
array.c
View File

@ -234,6 +234,50 @@ rb_values_new2(n, elts)
return val; 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 VALUE
rb_assoc_new(car, cdr) rb_assoc_new(car, cdr)
VALUE car, cdr; VALUE car, cdr;
@ -500,22 +544,6 @@ rb_ary_pop(ary)
return RARRAY(ary)->ptr[--RARRAY(ary)->len]; 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: * call-seq:
* array.shift => obj or nil * array.shift => obj or nil

View File

@ -464,6 +464,9 @@ rb_cstr_to_inum(str, base, badcheck)
} }
continue; continue;
} }
else if (!ISASCII(c)) {
break;
}
else if (isdigit(c)) { else if (isdigit(c)) {
c -= '0'; c -= '0';
} }

29
eval.c
View File

@ -2573,14 +2573,14 @@ svalue_to_mrhs(v, lhs)
{ {
VALUE tmp; 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); tmp = rb_check_array_type(v);
if (NIL_P(tmp)) { if (NIL_P(tmp)) {
return rb_ary_new3(1, v); return rb_values_new(1, v);
} }
/* no lhs means splat lhs only */ /* no lhs means splat lhs only */
if (!lhs) { if (!lhs) {
return rb_ary_new3(1, v); return rb_values_new(1, v);
} }
return tmp; return tmp;
} }
@ -2602,8 +2602,11 @@ static VALUE
splat_value(v) splat_value(v)
VALUE v; VALUE v;
{ {
if (NIL_P(v)) return rb_ary_new3(1, Qnil); VALUE val;
return rb_Array(v);
if (NIL_P(v)) val = rb_ary_new3(1, Qnil);
else val = rb_Array(v);
return rb_values_from_ary(val);
} }
static VALUE static VALUE
@ -3569,6 +3572,22 @@ rb_eval(self, n)
} }
break; 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: case NODE_STR:
result = rb_str_new3(node->nd_lit); result = rb_str_new3(node->nd_lit);
break; break;

View File

@ -280,6 +280,16 @@ fdbm_values_at(argc, argv, obj)
return new; 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 static VALUE
fdbm_delete(obj, keystr) fdbm_delete(obj, keystr)
VALUE obj, keystr; VALUE obj, keystr;
@ -289,7 +299,7 @@ fdbm_delete(obj, keystr)
DBM *dbm; DBM *dbm;
VALUE valstr; VALUE valstr;
rb_secure(4); fdbm_modify(obj);
StringValue(keystr); StringValue(keystr);
key.dptr = RSTRING(keystr)->ptr; key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len; key.dsize = RSTRING(keystr)->len;
@ -325,7 +335,7 @@ fdbm_shift(obj)
DBM *dbm; DBM *dbm;
VALUE keystr, valstr; VALUE keystr, valstr;
rb_secure(4); fdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
dbmp->di_size = -1; dbmp->di_size = -1;
@ -351,7 +361,7 @@ fdbm_delete_if(obj)
VALUE ret, ary = rb_ary_new(); VALUE ret, ary = rb_ary_new();
int i, status = 0, n; int i, status = 0, n;
rb_secure(4); fdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
n = dbmp->di_size; n = dbmp->di_size;
@ -388,7 +398,7 @@ fdbm_clear(obj)
struct dbmdata *dbmp; struct dbmdata *dbmp;
DBM *dbm; DBM *dbm;
rb_secure(4); fdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
dbmp->di_size = -1; dbmp->di_size = -1;
@ -471,7 +481,7 @@ fdbm_store(obj, keystr, valstr)
struct dbmdata *dbmp; struct dbmdata *dbmp;
DBM *dbm; DBM *dbm;
rb_secure(4); fdbm_modify(obj);
keystr = rb_obj_as_string(keystr); keystr = rb_obj_as_string(keystr);
key.dptr = RSTRING(keystr)->ptr; key.dptr = RSTRING(keystr)->ptr;

View File

@ -387,6 +387,16 @@ fgdbm_values_at(argc, argv, obj)
return new; 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 static VALUE
rb_gdbm_delete(obj, keystr) rb_gdbm_delete(obj, keystr)
VALUE obj, keystr; VALUE obj, keystr;
@ -395,7 +405,7 @@ rb_gdbm_delete(obj, keystr)
struct dbmdata *dbmp; struct dbmdata *dbmp;
GDBM_FILE dbm; GDBM_FILE dbm;
rb_secure(4); rb_gdbm_modify(obj);
StringValue(keystr); StringValue(keystr);
key.dptr = RSTRING(keystr)->ptr; key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len; key.dsize = RSTRING(keystr)->len;
@ -436,7 +446,7 @@ fgdbm_shift(obj)
GDBM_FILE dbm; GDBM_FILE dbm;
VALUE keystr, valstr; VALUE keystr, valstr;
rb_secure(4); rb_gdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
@ -458,7 +468,7 @@ fgdbm_delete_if(obj)
VALUE ret, ary = rb_ary_new(); VALUE ret, ary = rb_ary_new();
int i, status = 0, n; int i, status = 0, n;
rb_secure(4); rb_gdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
n = dbmp->di_size; n = dbmp->di_size;
@ -489,7 +499,7 @@ fgdbm_clear(obj)
struct dbmdata *dbmp; struct dbmdata *dbmp;
GDBM_FILE dbm; GDBM_FILE dbm;
rb_secure(4); rb_gdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
dbmp->di_size = -1; dbmp->di_size = -1;
@ -588,7 +598,7 @@ fgdbm_store(obj, keystr, valstr)
struct dbmdata *dbmp; struct dbmdata *dbmp;
GDBM_FILE dbm; GDBM_FILE dbm;
rb_secure(4); rb_gdbm_modify(obj);
StringValue(keystr); StringValue(keystr);
key.dptr = RSTRING(keystr)->ptr; key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len; key.dsize = RSTRING(keystr)->len;
@ -830,7 +840,7 @@ fgdbm_reorganize(obj)
struct dbmdata *dbmp; struct dbmdata *dbmp;
GDBM_FILE dbm; GDBM_FILE dbm;
rb_secure(4); rb_gdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
gdbm_reorganize(dbm); gdbm_reorganize(dbm);
@ -844,7 +854,7 @@ fgdbm_sync(obj)
struct dbmdata *dbmp; struct dbmdata *dbmp;
GDBM_FILE dbm; GDBM_FILE dbm;
rb_secure(4); rb_gdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
gdbm_sync(dbm); gdbm_sync(dbm);

View File

@ -43,7 +43,7 @@ def charset_alias(config_charset, mapfile, target = OS)
st = Hash.new(0) st = Hash.new(0)
map = map.sort.collect do |can, *sys| map = map.sort.collect do |can, *sys|
if sys.grep(/^en_us(?=.|$)/i) {break true} == true 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} sys.reject! {|s| noen =~ s}
end end
sys = sys.first sys = sys.first
@ -67,7 +67,7 @@ def charset_alias(config_charset, mapfile, target = OS)
else else
sys = "'#{sys}'.freeze" sys = "'#{sys}'.freeze"
end end
f.puts(" charset_map['#{can}'.freeze] = #{sys}") f.puts(" charset_map['#{can}'] = #{sys}")
end end
f.puts("end") f.puts("end")
end end

View File

@ -268,6 +268,16 @@ fsdbm_values_at(argc, argv, obj)
return new; 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 static VALUE
fsdbm_delete(obj, keystr) fsdbm_delete(obj, keystr)
VALUE obj, keystr; VALUE obj, keystr;
@ -277,7 +287,7 @@ fsdbm_delete(obj, keystr)
DBM *dbm; DBM *dbm;
VALUE valstr; VALUE valstr;
rb_secure(4); fdbm_modify(obj);
StringValue(keystr); StringValue(keystr);
key.dptr = RSTRING(keystr)->ptr; key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len; key.dsize = RSTRING(keystr)->len;
@ -314,7 +324,7 @@ fsdbm_shift(obj)
DBM *dbm; DBM *dbm;
VALUE keystr, valstr; VALUE keystr, valstr;
rb_secure(4); fdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
@ -342,7 +352,7 @@ fsdbm_delete_if(obj)
VALUE ret, ary = rb_ary_new(); VALUE ret, ary = rb_ary_new();
int i, status = 0, n; int i, status = 0, n;
rb_secure(4); fdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
n = dbmp->di_size; n = dbmp->di_size;
@ -378,7 +388,7 @@ fsdbm_clear(obj)
struct dbmdata *dbmp; struct dbmdata *dbmp;
DBM *dbm; DBM *dbm;
rb_secure(4); fdbm_modify(obj);
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
dbmp->di_size = -1; dbmp->di_size = -1;
@ -466,7 +476,7 @@ fsdbm_store(obj, keystr, valstr)
return Qnil; return Qnil;
} }
rb_secure(4); fdbm_modify(obj);
keystr = rb_obj_as_string(keystr); keystr = rb_obj_as_string(keystr);
key.dptr = RSTRING(keystr)->ptr; key.dptr = RSTRING(keystr)->ptr;

4
gc.c
View File

@ -1718,12 +1718,10 @@ rb_gc_copy_finalizer(dest, obj)
if (!finalizer_table) return; if (!finalizer_table) return;
if (!FL_TEST(obj, FL_FINALIZE)) 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)) { if (st_lookup(finalizer_table, obj, &table)) {
st_insert(finalizer_table, dest, table); st_insert(finalizer_table, dest, table);
} }
RBASIC(dest)->flags |= FL_FINALIZE;
} }
static VALUE static VALUE

63
hash.c
View File

@ -1391,6 +1391,35 @@ equal_i(key, val1, data)
return ST_CONTINUE; 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: * call-seq:
* hsh == other_hash => true or false * hsh == other_hash => true or false
@ -1414,26 +1443,23 @@ static VALUE
rb_hash_equal(hash1, hash2) rb_hash_equal(hash1, hash2)
VALUE hash1, hash2; VALUE hash1, hash2;
{ {
struct equal_data data; return hash_equal(hash1, hash2, Qfalse);
}
if (hash1 == hash2) return Qtrue; /*
if (TYPE(hash2) != T_HASH) { * call-seq:
if (!rb_respond_to(hash2, rb_intern("to_hash"))) { * hsh.eql?(other_hash) => true or false
return Qfalse; *
} * Returns true if two hashes are equal, i.e they have same key-value set,
return rb_equal(hash2, hash1); * and same default values.
} *
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;
data.tbl = RHASH(hash2)->tbl; static VALUE
data.result = Qtrue; rb_hash_eql(hash1, hash2)
st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data); VALUE hash1, hash2;
{
return data.result; return hash_equal(hash1, hash2, Qtrue);
} }
static int static int
@ -2365,6 +2391,7 @@ Init_Hash()
rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0); rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
rb_define_method(rb_cHash,"==", rb_hash_equal, 1); 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,"[]", rb_hash_aref, 1);
rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1); rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1);
rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2); rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);

View File

@ -32,6 +32,8 @@ VALUE rb_ary_new3 __((long,...));
VALUE rb_ary_new4 _((long, const VALUE *)); VALUE rb_ary_new4 _((long, const VALUE *));
VALUE rb_values_new __((long,...)); VALUE rb_values_new __((long,...));
VALUE rb_values_new2 _((long, const VALUE *)); 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_freeze _((VALUE));
VALUE rb_ary_aref _((int, VALUE*, VALUE)); VALUE rb_ary_aref _((int, VALUE*, VALUE));
void rb_ary_store _((VALUE, long, VALUE)); void rb_ary_store _((VALUE, long, VALUE));

12
io.c
View File

@ -2396,15 +2396,27 @@ rb_fdopen(fd, mode)
{ {
FILE *file; FILE *file;
#if defined(sun)
errno = 0;
#endif
file = fdopen(fd, mode); file = fdopen(fd, mode);
if (!file) { if (!file) {
#if defined(sun)
if (errno == 0 || errno == EMFILE || errno == ENFILE) {
#else
if (errno == EMFILE || errno == ENFILE) { if (errno == EMFILE || errno == ENFILE) {
#endif
rb_gc(); rb_gc();
#if defined(sun)
errno = 0;
#endif
file = fdopen(fd, mode); file = fdopen(fd, mode);
} }
if (!file) { if (!file) {
#ifdef _WIN32 #ifdef _WIN32
if (errno == 0) errno = EINVAL; if (errno == 0) errno = EINVAL;
#elif defined(sun)
if (errno == 0) errno = EMFILE;
#endif #endif
rb_sys_fail(0); rb_sys_fail(0);
} }

View File

@ -87,20 +87,27 @@ def DelegateClass(superclass)
methods = superclass.public_instance_methods(true) methods = superclass.public_instance_methods(true)
methods -= ::Kernel.public_instance_methods(false) methods -= ::Kernel.public_instance_methods(false)
methods |= ["to_s","to_a","inspect","==","=~","==="] methods |= ["to_s","to_a","inspect","==","=~","==="]
klass.module_eval <<-EOS klass.module_eval {
def initialize(obj) def initialize(obj)
@_dc_obj = obj @_dc_obj = obj
end end
def __getobj__ def method_missing(m, *args)
@_dc_obj p [m, *args]
end unless @_dc_obj.respond_to?(m)
def __setobj__(obj) super(m, *args)
@_dc_obj = obj end
end @_dc_obj.__send__(m, *args)
EOS end
def __getobj__
@_dc_obj
end
def __setobj__(obj)
@_dc_obj = obj
end
}
for method in methods for method in methods
begin begin
klass.module_eval <<-EOS klass.module_eval <<-EOS, __FILE__, __LINE__+1
def #{method}(*args, &block) def #{method}(*args, &block)
begin begin
@_dc_obj.__send__(:#{method}, *args, &block) @_dc_obj.__send__(:#{method}, *args, &block)

View File

@ -539,6 +539,7 @@ private
def create_logfile(filename) def create_logfile(filename)
logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT)) logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT))
logdev.sync = true
add_log_header(logdev) add_log_header(logdev)
logdev logdev
end end

View File

@ -3195,7 +3195,8 @@ EOF
end end
parser = GetoptLong.new 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], ['--port', GetoptLong::REQUIRED_ARGUMENT],
['--user', GetoptLong::REQUIRED_ARGUMENT], ['--user', GetoptLong::REQUIRED_ARGUMENT],
['--auth', GetoptLong::REQUIRED_ARGUMENT]) ['--auth', GetoptLong::REQUIRED_ARGUMENT])
@ -3208,6 +3209,8 @@ EOF
$user = arg $user = arg
when "--auth" when "--auth"
$auth = arg $auth = arg
when "--debug"
Net::IMAP.debug = true
when "--help" when "--help"
usage usage
exit(1) exit(1)

View File

@ -108,9 +108,13 @@ class Tempfile < DelegateClass(File)
# file. # file.
def unlink def unlink
# keep this order for thread safeness # keep this order for thread safeness
File.unlink(@tmpname) if File.exist?(@tmpname) begin
@@cleanlist.delete(@tmpname) File.unlink(@tmpname) if File.exist?(@tmpname)
@tmpname = nil @@cleanlist.delete(@tmpname)
@tmpname = nil
rescue Errno::EACCESS
# may not be able to unlink on Windows; just ignore
end
end end
alias delete unlink alias delete unlink

View File

@ -325,7 +325,7 @@ The variable ruby-indent-level controls the amount of indentation.
(looking-at ruby-block-op-re) (looking-at ruby-block-op-re)
(looking-at ruby-block-mid-re)) (looking-at ruby-block-mid-re))
(goto-char (match-end 0)) (goto-char (match-end 0))
(looking-at "\\>")) (not (looking-at "\\s_")))
((eq option 'expr-qstr) ((eq option 'expr-qstr)
(looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]")) (looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]"))
((eq option 'expr-re) ((eq option 'expr-re)

1
node.h
View File

@ -62,6 +62,7 @@ enum node_type {
NODE_ZSUPER, NODE_ZSUPER,
NODE_ARRAY, NODE_ARRAY,
NODE_ZARRAY, NODE_ZARRAY,
NODE_VALUES,
NODE_HASH, NODE_HASH,
NODE_RETURN, NODE_RETURN,
NODE_YIELD, NODE_YIELD,

View File

@ -490,37 +490,29 @@ flo_to_s(flt)
VALUE flt; VALUE flt;
{ {
char buf[32]; char buf[32];
char *fmt = "%.15g"; char *fmt = "%.15f";
double value = RFLOAT(flt)->value; double value = RFLOAT(flt)->value;
double avalue, d1, d2; double avalue, d1, d2;
char *p, *e;
if (isinf(value)) if (isinf(value))
return rb_str_new2(value < 0 ? "-Infinity" : "Infinity"); return rb_str_new2(value < 0 ? "-Infinity" : "Infinity");
else if(isnan(value)) else if(isnan(value))
return rb_str_new2("NaN"); 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";
}
else if ((d1 = modf(value, &d2)) == 0) {
fmt = "%.1f";
}
sprintf(buf, fmt, value);
avalue = fabs(value);
if (avalue < 1.0e-7 || avalue >= 1.0e15) {
fmt = "%.16e";
}
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); return rb_str_new2(buf);
} }

View File

@ -262,7 +262,7 @@ rb_obj_clone(obj)
} }
clone = rb_obj_alloc(rb_obj_class(obj)); clone = rb_obj_alloc(rb_obj_class(obj));
RBASIC(clone)->klass = rb_singleton_class_clone(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); init_copy(clone, obj);
RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE; RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;

15
parse.y
View File

@ -1455,7 +1455,8 @@ primary : literal
} }
| tLPAREN compstmt ')' | tLPAREN compstmt ')'
{ {
$$ = $2; if (!$2) $$ = NEW_NIL();
else $$ = $2;
} }
| primary_value tCOLON2 tCONSTANT | primary_value tCOLON2 tCONSTANT
{ {
@ -2090,6 +2091,7 @@ string_content : tSTRING_CONTENT
lex_strterm = $<node>2; lex_strterm = $<node>2;
COND_LEXPOP(); COND_LEXPOP();
CMDARG_LEXPOP(); CMDARG_LEXPOP();
FL_UNSET($3, NODE_NEWLINE);
$$ = new_evstr($3); $$ = new_evstr($3);
} }
; ;
@ -5432,10 +5434,15 @@ ret_args(node)
{ {
if (node) { if (node) {
no_blockarg(node); no_blockarg(node);
if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) { if (nd_type(node) == NODE_ARRAY) {
node = node->nd_head; 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); node = NEW_SVALUE(node);
} }
} }

View File

@ -888,7 +888,7 @@ rb_str_equal(str1, str2)
if (str1 == str2) return Qtrue; if (str1 == str2) return Qtrue;
if (TYPE(str2) != T_STRING) { if (TYPE(str2) != T_STRING) {
if (!rb_respond_to(str2, rb_intern("to_str"))) { if (!rb_respond_to(str2, rb_intern("to_str"))) {
return Qnil; return Qfalse;
} }
return rb_equal(str2, str1); return rb_equal(str2, str1);
} }
@ -1080,7 +1080,7 @@ rb_str_index_m(argc, argv, str)
{ {
int c = FIX2INT(sub); int c = FIX2INT(sub);
long len = RSTRING(str)->len; long len = RSTRING(str)->len;
char *p = RSTRING(str)->ptr; unsigned char *p = RSTRING(str)->ptr;
for (;pos<len;pos++) { for (;pos<len;pos++) {
if (p[pos] == c) return LONG2NUM(pos); if (p[pos] == c) return LONG2NUM(pos);
@ -1202,15 +1202,15 @@ rb_str_rindex_m(argc, argv, str)
case T_FIXNUM: case T_FIXNUM:
{ {
int c = FIX2INT(sub); int c = FIX2INT(sub);
char *p = RSTRING(str)->ptr + pos; unsigned char *p = RSTRING(str)->ptr + pos;
char *pbeg = RSTRING(str)->ptr; unsigned char *pbeg = RSTRING(str)->ptr;
if (pos == RSTRING(str)->len) { if (pos == RSTRING(str)->len) {
if (pos == 0) return Qnil; if (pos == 0) return Qnil;
--p; --p;
} }
while (pbeg <= p) { while (pbeg <= p) {
if (*p == c) return LONG2NUM(p - RSTRING(str)->ptr); if (*p == c) return LONG2NUM((char*)p - RSTRING(str)->ptr);
p--; p--;
} }
return Qnil; return Qnil;