summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog44
-rw-r--r--ToDo1
-rw-r--r--array.c2
-rw-r--r--enum.c39
-rw-r--r--eval.c13
-rw-r--r--file.c44
-rw-r--r--hash.c1
-rw-r--r--intern.h1
-rw-r--r--io.c2
-rw-r--r--marshal.c2
-rw-r--r--parse.y16
-rw-r--r--range.c21
-rw-r--r--signal.c21
-rw-r--r--variable.c7
-rw-r--r--version.h4
15 files changed, 176 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index 03924d6159..b39280095a 100644
--- a/ChangeLog
+++ b/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.
diff --git a/ToDo b/ToDo
index 3bd014f892..0c439a87e2 100644
--- a/ToDo
+++ b/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
diff --git a/array.c b/array.c
index 918dd12056..66f61fcb1d 100644
--- a/array.c
+++ b/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;
diff --git a/enum.c b/enum.c
index 56d69502a0..d79178d393 100644
--- a/enum.c
+++ b/enum.c
@@ -204,6 +204,44 @@ enum_sort(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;
NODE *memo;
@@ -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);
diff --git a/eval.c b/eval.c
index d4a8f6f5f9..f88510e15c 100644
--- a/eval.c
+++ b/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));
}
diff --git a/file.c b/file.c
index 5357163fe8..58eebe52d5 100644
--- a/file.c
+++ b/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
}
diff --git a/hash.c b/hash.c
index 9b3bb3f97a..35d950a8ed 100644
--- a/hash.c
+++ b/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;
diff --git a/intern.h b/intern.h
index f427791267..fe08ea49f5 100644
--- a/intern.h
+++ b/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 */
diff --git a/io.c b/io.c
index 0d8f489511..42d3530246 100644
--- a/io.c
+++ b/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) {
diff --git a/marshal.c b/marshal.c
index 297be7575f..5a8e4232b0 100644
--- a/marshal.c
+++ b/marshal.c
@@ -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);
}
diff --git a/parse.y b/parse.y
index 9ea4954368..17361cd5d9 100644
--- a/parse.y
+++ b/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) {
diff --git a/range.c b/range.c
index 4ea1df2442..6a1afde610 100644
--- a/range.c
+++ b/range.c
@@ -149,6 +149,18 @@ r_gt(a,b)
}
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;
diff --git a/signal.c b/signal.c
index bdfa321789..57e70024de 100644
--- a/signal.c
+++ b/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);
diff --git a/variable.c b/variable.c
index eab951d102..28013e76a8 100644
--- a/variable.c
+++ b/variable.c
@@ -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);
diff --git a/version.h b/version.h
index dcecd4ae91..658c2e833c 100644
--- a/version.h
+++ b/version.h
@@ -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