mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* eval.c (is_defined): should not dump core for "defined?(())".
* eval.c (umethod_bind): recv can be an instance of descender of oklass if oklass is a Module. * hash.c (rb_hash_equal): check identiry equality first. * file.c (group_member): should check real gid only. * file.c (eaccess): do not cache euid, since effective euid may be changed via Process.euid=(). * file.c (eaccess): return -1 unless every specified access mode is permitted. * eval.c (rb_eval): while/until returns the value which is given to break. * parse.y (value_expr): using while/until/class/def as an expression is now gives a warning, not an error. * range.c (range_eqq): should compare strings based on magical increment (using String#upto), not dictionary order. * enum.c (enum_sort_by): new method for Schewartzian transformed stable sort. * variable.c (mod_av_set): detect constant overriding for built-in classes/modules. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1707 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e15efe7733
commit
1289a7a11f
15 changed files with 176 additions and 42 deletions
44
ChangeLog
44
ChangeLog
|
@ -1,9 +1,53 @@
|
|||
Thu Aug 23 10:10:59 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (is_defined): should not dump core for "defined?(())".
|
||||
|
||||
* eval.c (umethod_bind): recv can be an instance of descender of
|
||||
oklass if oklass is a Module.
|
||||
|
||||
Wed Aug 22 23:20:03 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* hash.c (rb_hash_equal): check identiry equality first.
|
||||
|
||||
Tue Aug 21 22:28:09 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||
|
||||
* file.c (group_member): should check real gid only.
|
||||
|
||||
* file.c (eaccess): do not cache euid, since effective euid may be
|
||||
changed via Process.euid=().
|
||||
|
||||
* file.c (eaccess): return -1 unless every specified access mode
|
||||
is permitted.
|
||||
|
||||
Tue Aug 21 16:09:27 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_eval): while/until returns the value which is given
|
||||
to break.
|
||||
|
||||
* parse.y (value_expr): using while/until/class/def as an
|
||||
expression is now gives a warning, not an error.
|
||||
|
||||
Tue Aug 21 11:56:02 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* range.c (range_eqq): should compare strings based on magical
|
||||
increment (using String#upto), not dictionary order.
|
||||
|
||||
Mon Aug 20 19:53:16 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||
|
||||
* ext/digest/sha2/extconf.rb: fix support for cross-compiling.
|
||||
|
||||
* mkconfig.rb: fix support for autoconf 2.52.
|
||||
|
||||
Mon Aug 20 17:24:15 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* enum.c (enum_sort_by): new method for Schewartzian transformed
|
||||
stable sort.
|
||||
|
||||
Mon Aug 20 16:09:05 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* variable.c (mod_av_set): detect constant overriding for built-in
|
||||
classes/modules.
|
||||
|
||||
Mon Aug 20 15:14:27 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (tokadd_escape): escaped backslashes too much.
|
||||
|
|
1
ToDo
1
ToDo
|
@ -28,6 +28,7 @@ Language Spec.
|
|||
* jar like combined library package.
|
||||
* resumable Exception via Exception#resume.
|
||||
* method combination, e.g. before, after, around, etc.
|
||||
* .. or something like defactive in Emacs.
|
||||
|
||||
Hacking Interpreter
|
||||
|
||||
|
|
2
array.c
2
array.c
|
@ -1443,7 +1443,7 @@ rb_ary_includes(ary, item)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
VALUE
|
||||
rb_ary_cmp(ary, ary2)
|
||||
VALUE ary;
|
||||
VALUE ary2;
|
||||
|
|
39
enum.c
39
enum.c
|
@ -203,6 +203,44 @@ enum_sort(obj)
|
|||
return rb_ary_sort(enum_to_a(obj));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
sort_by_i(i, memo)
|
||||
VALUE i;
|
||||
NODE *memo;
|
||||
{
|
||||
VALUE e = rb_ary_new3(3, rb_yield(e), INT2NUM(memo->u3.cnt), i);
|
||||
rb_ary_push(memo->u1.value, e);
|
||||
memo->u3.cnt++;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
sort_by_sort_body(a)
|
||||
VALUE a;
|
||||
{
|
||||
return rb_ary_cmp(RARRAY(a)->ptr[0], RARRAY(a)->ptr[1]);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
enum_sort_by(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE ary = rb_ary_new();
|
||||
NODE *memo = rb_node_newnode(NODE_MEMO, ary, 0, 0);
|
||||
long i;
|
||||
|
||||
rb_iterate(rb_each, obj, sort_by_i, (VALUE)memo);
|
||||
rb_gc_force_recycle((VALUE)memo);
|
||||
rb_iterate(rb_ary_sort_bang, ary, sort_by_sort_body, 0);
|
||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||
VALUE e = RARRAY(ary)->ptr[i];
|
||||
RARRAY(ary)->ptr[i] = rb_ary_entry(e, 2);
|
||||
rb_gc_force_recycle(e);
|
||||
}
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
all_i(i, memo)
|
||||
VALUE i;
|
||||
|
@ -397,6 +435,7 @@ Init_Enumerable()
|
|||
rb_define_method(rb_mEnumerable,"entries", enum_to_a, 0);
|
||||
|
||||
rb_define_method(rb_mEnumerable,"sort", enum_sort, 0);
|
||||
rb_define_method(rb_mEnumerable,"sort_by", enum_sort_by, 0);
|
||||
rb_define_method(rb_mEnumerable,"grep", enum_grep, 1);
|
||||
rb_define_method(rb_mEnumerable,"find", enum_find, -1);
|
||||
rb_define_method(rb_mEnumerable,"detect", enum_find, -1);
|
||||
|
|
13
eval.c
13
eval.c
|
@ -1748,6 +1748,7 @@ is_defined(self, node, buf)
|
|||
VALUE val; /* OK */
|
||||
int state;
|
||||
|
||||
if (!node) return "expression";
|
||||
switch (nd_type(node)) {
|
||||
case NODE_SUPER:
|
||||
case NODE_ZSUPER:
|
||||
|
@ -2272,7 +2273,7 @@ rb_eval(self, n)
|
|||
switch (state = EXEC_TAG()) {
|
||||
case 0:
|
||||
ruby_sourceline = nd_line(node);
|
||||
if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
|
||||
if (node->nd_state && !RTEST(result = rb_eval(self, node->nd_cond)))
|
||||
goto while_out;
|
||||
do {
|
||||
while_redo:
|
||||
|
@ -2290,19 +2291,20 @@ rb_eval(self, n)
|
|||
goto while_next;
|
||||
case TAG_BREAK:
|
||||
state = 0;
|
||||
result = prot_tag->retval;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
while_out:
|
||||
POP_TAG();
|
||||
if (state) JUMP_TAG(state);
|
||||
RETURN(Qnil);
|
||||
RETURN(result);
|
||||
|
||||
case NODE_UNTIL:
|
||||
PUSH_TAG(PROT_NONE);
|
||||
switch (state = EXEC_TAG()) {
|
||||
case 0:
|
||||
if (node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
|
||||
if (node->nd_state && RTEST(result = rb_eval(self, node->nd_cond)))
|
||||
goto until_out;
|
||||
do {
|
||||
until_redo:
|
||||
|
@ -2320,6 +2322,7 @@ rb_eval(self, n)
|
|||
goto until_next;
|
||||
case TAG_BREAK:
|
||||
state = 0;
|
||||
result = prot_tag->retval;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6804,7 +6807,9 @@ umethod_bind(method, recv)
|
|||
st_lookup(RCLASS(CLASS_OF(recv))->m_tbl, data->oid, 0)) {
|
||||
rb_raise(rb_eTypeError, "method `%s' overridden", rb_id2name(data->oid));
|
||||
}
|
||||
if (!rb_obj_is_instance_of(recv, data->oklass)) {
|
||||
if (!((TYPE(data->oklass) == T_MODULE) ?
|
||||
rb_obj_is_kind_of(recv, data->oklass) :
|
||||
rb_obj_is_instance_of(recv, data->oklass))) {
|
||||
rb_raise(rb_eTypeError, "bind argument must be an instance of %s",
|
||||
rb_class2name(data->oklass));
|
||||
}
|
||||
|
|
44
file.c
44
file.c
|
@ -390,7 +390,7 @@ group_member(gid)
|
|||
GETGROUPS_T gid;
|
||||
{
|
||||
#if !defined(NT)
|
||||
if (getgid() == gid || getegid() == gid)
|
||||
if (getgid() == gid)
|
||||
return Qtrue;
|
||||
|
||||
# ifdef HAVE_GETGROUPS
|
||||
|
@ -421,36 +421,36 @@ eaccess(path, mode)
|
|||
int mode;
|
||||
{
|
||||
#ifdef S_IXGRP
|
||||
struct stat st;
|
||||
static int euid = -1;
|
||||
struct stat st;
|
||||
int euid;
|
||||
|
||||
if (stat(path, &st) < 0) return (-1);
|
||||
if (stat(path, &st) < 0) return -1;
|
||||
|
||||
if (euid == -1)
|
||||
euid = geteuid ();
|
||||
euid = geteuid();
|
||||
|
||||
if (euid == 0)
|
||||
{
|
||||
/* Root can read or write any file. */
|
||||
if (mode != X_OK)
|
||||
return 0;
|
||||
if (euid == 0) {
|
||||
/* Root can read or write any file. */
|
||||
if (!(mode & X_OK))
|
||||
return 0;
|
||||
|
||||
/* Root can execute any file that has any one of the execute
|
||||
bits set. */
|
||||
if (st.st_mode & S_IXUGO)
|
||||
return 0;
|
||||
/* Root can execute any file that has any one of the execute
|
||||
bits set. */
|
||||
if (st.st_mode & S_IXUGO)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (st.st_uid == euid) /* owner */
|
||||
mode <<= 6;
|
||||
else if (group_member (st.st_gid))
|
||||
mode <<= 3;
|
||||
if (st.st_uid == euid) /* owner */
|
||||
mode <<= 6;
|
||||
else if (getegid() == st.st_gid || group_member(st.st_gid))
|
||||
mode <<= 3;
|
||||
|
||||
if (st.st_mode & mode) return 0;
|
||||
if ((st.st_mode & mode) == mode) return 0;
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
#else
|
||||
return access(path, mode);
|
||||
return access(path, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
1
hash.c
1
hash.c
|
@ -804,6 +804,7 @@ rb_hash_equal(hash1, hash2)
|
|||
{
|
||||
struct equal_data data;
|
||||
|
||||
if (hash1 == hash2) return Qtrue;
|
||||
if (TYPE(hash2) != T_HASH) return Qfalse;
|
||||
if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries)
|
||||
return Qfalse;
|
||||
|
|
1
intern.h
1
intern.h
|
@ -49,6 +49,7 @@ VALUE rb_ary_concat _((VALUE, VALUE));
|
|||
VALUE rb_ary_assoc _((VALUE, VALUE));
|
||||
VALUE rb_ary_rassoc _((VALUE, VALUE));
|
||||
VALUE rb_ary_includes _((VALUE, VALUE));
|
||||
VALUE rb_ary_cmp _((VALUE, VALUE));
|
||||
VALUE rb_protect_inspect _((VALUE(*)(),VALUE,VALUE));
|
||||
VALUE rb_inspecting_p _((VALUE));
|
||||
/* bignum.c */
|
||||
|
|
2
io.c
2
io.c
|
@ -3399,7 +3399,7 @@ argf_eof()
|
|||
int first = first_p;
|
||||
|
||||
if (!next_argv()) return Qtrue;
|
||||
if (!first && next_p == -1) {
|
||||
if (next_p == 1) {
|
||||
return Qtrue;
|
||||
}
|
||||
if (TYPE(current_file) != T_FILE) {
|
||||
|
|
|
@ -293,7 +293,7 @@ w_object(obj, arg, limit)
|
|||
w_byte(TYPE_FIXNUM, arg);
|
||||
w_long(FIX2INT(obj), arg);
|
||||
#else
|
||||
if (RSHIFT((long)obj, 30) == 0 || RSHIFT((long)obj, 30) == -1) {
|
||||
if (RSHIFT((long)obj, 31) == 0 || RSHIFT((long)obj, 31) == -1) {
|
||||
w_byte(TYPE_FIXNUM, arg);
|
||||
w_long(FIX2LONG(obj), arg);
|
||||
}
|
||||
|
|
16
parse.y
16
parse.y
|
@ -1191,7 +1191,7 @@ primary : literal
|
|||
}
|
||||
| tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} ')'
|
||||
{
|
||||
rb_warning("%s (...) interpreted as command call", rb_id2name($<id>1));
|
||||
rb_warning("%s (...) interpreted as grouped expression", rb_id2name($<id>1));
|
||||
$$ = $2;
|
||||
}
|
||||
| tLPAREN compstmt ')'
|
||||
|
@ -4355,20 +4355,22 @@ value_expr(node)
|
|||
if (node == 0) return Qtrue;
|
||||
|
||||
switch (nd_type(node)) {
|
||||
case NODE_RETURN:
|
||||
case NODE_BREAK:
|
||||
case NODE_NEXT:
|
||||
case NODE_REDO:
|
||||
case NODE_RETRY:
|
||||
case NODE_WHILE:
|
||||
case NODE_UNTIL:
|
||||
case NODE_CLASS:
|
||||
case NODE_MODULE:
|
||||
case NODE_DEFN:
|
||||
case NODE_DEFS:
|
||||
rb_warning("void value expression");
|
||||
return Qfalse;
|
||||
|
||||
case NODE_RETURN:
|
||||
case NODE_BREAK:
|
||||
case NODE_NEXT:
|
||||
case NODE_REDO:
|
||||
case NODE_RETRY:
|
||||
yyerror("void value expression");
|
||||
return Qfalse;
|
||||
break;
|
||||
|
||||
case NODE_BLOCK:
|
||||
while (node->nd_next) {
|
||||
|
|
21
range.c
21
range.c
|
@ -148,6 +148,18 @@ r_gt(a,b)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
r_eqq_str_i(i, data)
|
||||
VALUE i;
|
||||
VALUE *data;
|
||||
{
|
||||
if (rb_str_cmp(i, data[0]) == 0) {
|
||||
data[1] = Qtrue;
|
||||
rb_iter_break();
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
range_eqq(range, obj)
|
||||
VALUE range, obj;
|
||||
|
@ -168,6 +180,15 @@ range_eqq(range, obj)
|
|||
}
|
||||
return Qfalse;
|
||||
}
|
||||
else if (TYPE(beg) == T_STRING &&
|
||||
TYPE(obj) == T_STRING &&
|
||||
TYPE(end) == T_STRING) {
|
||||
VALUE data[2];
|
||||
|
||||
data[0] = obj; data[1] = Qfalse;
|
||||
rb_iterate(rb_each, range, r_eqq_str_i, (VALUE)data);
|
||||
return data[1];
|
||||
}
|
||||
else if (r_le(beg, obj)) {
|
||||
if (EXCL(range)) {
|
||||
if (r_lt(obj, end)) return Qtrue;
|
||||
|
|
21
signal.c
21
signal.c
|
@ -609,7 +609,7 @@ rb_trap_restore_mask()
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_f_trap(argc, argv)
|
||||
sig_trap(argc, argv)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
{
|
||||
|
@ -643,11 +643,28 @@ rb_f_trap(argc, argv)
|
|||
#endif
|
||||
}
|
||||
|
||||
static VALUE
|
||||
sig_list()
|
||||
{
|
||||
VALUE h = rb_hash_new();
|
||||
struct signals *sigs;
|
||||
|
||||
for (sigs = siglist; sigs->signm; sigs++) {
|
||||
rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void
|
||||
Init_signal()
|
||||
{
|
||||
#ifndef MACOS_UNUSE_SIGNAL
|
||||
rb_define_global_function("trap", rb_f_trap, -1);
|
||||
VALUE mSignal = rb_define_module("Signal");
|
||||
|
||||
rb_define_global_function("trap", sig_trap, -1);
|
||||
rb_define_module_function(mSignal, "trap", sig_trap, -1);
|
||||
rb_define_module_function(mSignal, "list", sig_list, 0);
|
||||
|
||||
ruby_signal(SIGINT, sighandle);
|
||||
#ifdef SIGHUP
|
||||
ruby_signal(SIGHUP, sighandle);
|
||||
|
|
|
@ -1282,8 +1282,11 @@ mod_av_set(klass, id, val, isconst)
|
|||
if (!RCLASS(klass)->iv_tbl) {
|
||||
RCLASS(klass)->iv_tbl = st_init_numtable();
|
||||
}
|
||||
else if (isconst && st_lookup(RCLASS(klass)->iv_tbl, id, 0)) {
|
||||
rb_warn("already initialized %s %s", dest, rb_id2name(id));
|
||||
else if (isconst) {
|
||||
if (st_lookup(RCLASS(klass)->iv_tbl, id, 0) ||
|
||||
(klass == rb_cObject && st_lookup(rb_class_tbl, id, 0))) {
|
||||
rb_warn("already initialized %s %s", dest, rb_id2name(id));
|
||||
}
|
||||
}
|
||||
|
||||
st_insert(RCLASS(klass)->iv_tbl, id, val);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define RUBY_VERSION "1.7.1"
|
||||
#define RUBY_RELEASE_DATE "2001-08-20"
|
||||
#define RUBY_RELEASE_DATE "2001-08-23"
|
||||
#define RUBY_VERSION_CODE 171
|
||||
#define RUBY_RELEASE_CODE 20010820
|
||||
#define RUBY_RELEASE_CODE 20010823
|
||||
|
|
Loading…
Reference in a new issue