summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog39
-rw-r--r--array.c6
-rw-r--r--bignum.c25
-rw-r--r--class.c1
-rw-r--r--configure.in3
-rw-r--r--error.c4
-rw-r--r--eval.c27
-rw-r--r--ext/extmk.rb.in30
-rw-r--r--ext/md5/md5.txt11
-rw-r--r--ext/md5/md5.txt.jp12
-rw-r--r--hash.c7
-rw-r--r--lib/mkmf.rb30
-rw-r--r--marshal.c4
-rw-r--r--object.c10
-rw-r--r--re.c7
-rw-r--r--ruby.h2
-rw-r--r--sample/tsvr.rb7
-rw-r--r--string.c33
-rw-r--r--time.c10
19 files changed, 194 insertions, 74 deletions
diff --git a/ChangeLog b/ChangeLog
index 597ff6c33f5..c7c504f65d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,41 @@
+Thu Jun 22 17:27:46 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * string.c (rb_str_substr): str[n,m] now returns nil when n equals
+ to str.size.
+
Thu Jun 22 13:49:02 2000 Uechi Yasumasa <uechi@ryucom.ne.jp>
- * lib/net/ftp.rb: support resume.
+ * lib/net/ftp.rb: support resuming.
Thu Jun 22 13:37:19 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* eval.c (rb_thread_sleep_forever): merge pause() macro.
+Wed Jun 21 08:49:04 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * eval.c (rb_eval): should not raise exception just by defining
+ singleton class.
+
+Wed Jun 21 01:18:03 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * ruby.h: two macros RUBY_DATA_FUNC and RUBY_METHOD_FUNC are added
+ to make writing C++ extensions easier.
+
+ * array.c (rb_ary_dup): internal classes should not be shared by dup.
+
+ * hash.c (rb_hash_dup): ditto.
+
+ * object.c (rb_obj_dup): ditto.
+
+ * string.c (rb_str_dup): ditto.
+
+ * error.c (Init_Exception): renamed NotImplementError to
+ NotImplementedError.
+
+Tue Jun 20 16:22:38 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * time.c (make_time_t): bug in DST boundary.
+
Tue Jun 20 10:54:19 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* configure.in: add eval sitedir.
@@ -16,6 +46,13 @@ Tue Jun 20 06:14:43 2000 Wakou Aoyama <wakou@fsinet.or.jp>
* lib/net/telnet.rb: ditto.
+Tue Jun 20 00:37:45 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * re.c (rb_reg_kcode_m): Regexp#kcode returns nil for code unfixed
+ regexp object.
+
+ * bignum.c (bigdivmod): bignum zero check was wrong.
+
Mon Jun 19 10:48:28 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
* variable.c (rb_cvar_set): forgot to add security check for class
diff --git a/array.c b/array.c
index d8dc37195ca..f2089996e5f 100644
--- a/array.c
+++ b/array.c
@@ -680,9 +680,13 @@ static VALUE
rb_ary_dup(ary)
VALUE ary;
{
+ VALUE klass = CLASS_OF(ary);
VALUE dup;
- dup = rb_ary_s_create(RARRAY(ary)->len, RARRAY(ary)->ptr, CLASS_OF(ary));
+ while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
+ klass = (VALUE)RCLASS(klass)->super;
+ }
+ dup = rb_ary_s_create(RARRAY(ary)->len, RARRAY(ary)->ptr, klass);
if (OBJ_TAINTED(ary)) OBJ_TAINT(dup);
return dup;
}
diff --git a/bignum.c b/bignum.c
index dabb96a82e5..ec36a0946c8 100644
--- a/bignum.c
+++ b/bignum.c
@@ -451,8 +451,8 @@ rb_big_to_i(x)
return bignorm(x);
}
-VALUE
-rb_dbl2big(d)
+static VALUE
+dbl2big(d)
double d;
{
unsigned long i = 0;
@@ -481,7 +481,14 @@ rb_dbl2big(d)
digits[i] = (USHORT)c;
}
- return bignorm(z);
+ return z;
+}
+
+VALUE
+rb_dbl2big(d)
+ double d;
+{
+ return bignorm(dbl2big(d));
}
double
@@ -521,7 +528,7 @@ rb_big_cmp(x, y)
break;
case T_FLOAT:
- y = rb_dbl2big(RFLOAT(y)->value);
+ y = dbl2big(RFLOAT(y)->value);
break;
default:
@@ -553,7 +560,7 @@ rb_big_eq(x, y)
case T_BIGNUM:
break;
case T_FLOAT:
- y = rb_dbl2big(RFLOAT(y)->value);
+ y = dbl2big(RFLOAT(y)->value);
break;
default:
return Qfalse;
@@ -894,7 +901,7 @@ bigdivmod(x, y, div, mod, modulo)
if (modulo && RBIGNUM(x)->sign != RBIGNUM(y)->sign) {
long len = ny;
zds = BDIGITS(*mod);
- while (len-- && !zds[len]);
+ while (len && !zds[len]) len--;
if (len > 0) {
*mod = bigadd(*mod, y, 1);
return;
@@ -946,7 +953,7 @@ rb_big_modulo(x, y, modulo)
break;
case T_FLOAT:
- y = rb_dbl2big(RFLOAT(y)->value);
+ y = dbl2big(RFLOAT(y)->value);
break;
default:
@@ -983,7 +990,7 @@ rb_big_divmod(x, y)
break;
case T_FLOAT:
- y = rb_dbl2big(RFLOAT(y)->value);
+ y = dbl2big(RFLOAT(y)->value);
break;
case T_BIGNUM:
@@ -994,7 +1001,7 @@ rb_big_divmod(x, y)
}
bigdivmod(x, y, &div, &mod, 1);
- return rb_assoc_new(div, mod);;
+ return rb_assoc_new(div, mod);
}
VALUE
diff --git a/class.c b/class.c
index f92ceda8e4b..d26269d2c80 100644
--- a/class.c
+++ b/class.c
@@ -540,6 +540,7 @@ rb_singleton_class(obj)
else {
FL_UNSET(klass, FL_TAINT);
}
+ if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
return klass;
}
diff --git a/configure.in b/configure.in
index 2b64920778c..667b43fd97d 100644
--- a/configure.in
+++ b/configure.in
@@ -866,7 +866,8 @@ test "$program_suffix" != NONE &&
RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}"
RUBY_LIB_PREFIX="${prefix}/lib/ruby"
RUBY_LIB_PATH="${RUBY_LIB_PREFIX}/${MAJOR}.${MINOR}"
-sitedir='${prefix}/lib/ruby/site_ruby'
+#sitedir='${prefix}/lib/ruby/site_ruby'
+sitedir="${prefix}/lib/ruby/site_ruby"
AC_ARG_WITH(sitedir,
[--with-sitedir=DIR site libraries in DIR [PREFIX/lib/ruby/site_ruby]],
[sitedir=$withval])
diff --git a/error.c b/error.c
index e174ff6c98a..c65ad06d672 100644
--- a/error.c
+++ b/error.c
@@ -549,7 +549,9 @@ Init_Exception()
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
rb_eNameError = rb_define_class("NameError", rb_eScriptError);
rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
- rb_eNotImpError = rb_define_class("NotImplementError", rb_eScriptError);
+ rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
+ /* backward compatibility -- will be removed in the future */
+ rb_define_global_const("NotImplementError", rb_eNotImpError);
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
rb_eSecurityError = rb_define_class("SecurityError", rb_eStandardError);
diff --git a/eval.c b/eval.c
index 88f51ea53c7..c92384fd7cf 100644
--- a/eval.c
+++ b/eval.c
@@ -1420,6 +1420,28 @@ rb_mod_s_constants()
return ary;
}
+static void
+frozen_class_p(klass)
+ VALUE klass;
+{
+ char *desc = "something(?!)";
+
+ if (OBJ_FROZEN(klass)) {
+ if (FL_TEST(klass, FL_SINGLETON))
+ desc = "object";
+ else {
+ switch (TYPE(klass)) {
+ case T_MODULE:
+ case T_ICLASS:
+ desc = "module"; break;
+ case T_CLASS:
+ desc = "class"; break;
+ }
+ }
+ rb_error_frozen(desc);
+ }
+}
+
void
rb_undef(klass, id)
VALUE klass;
@@ -1434,7 +1456,7 @@ rb_undef(klass, id)
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
rb_raise(rb_eSecurityError, "Insecure: can't undef");
}
- if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
+ frozen_class_p(klass);
body = search_method(ruby_class, id, &origin);
if (!body || !body->nd_body) {
char *s0 = " class";
@@ -1476,6 +1498,7 @@ rb_alias(klass, name, def)
VALUE origin;
NODE *orig, *body;
+ frozen_class_p(klass);
if (name == def) return;
if (klass == rb_cObject) {
rb_secure(4);
@@ -2757,6 +2780,7 @@ rb_eval(self, n)
if (ruby_class == rb_cObject && node->nd_mid == init) {
rb_warn("re-defining Object#initialize may cause infinite loop");
}
+ frozen_class_p(ruby_class);
body = search_method(ruby_class, node->nd_mid, &origin);
if (body){
if (RTEST(ruby_verbose) && ruby_class == origin) {
@@ -2975,7 +2999,6 @@ rb_eval(self, n)
}
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass))
rb_raise(rb_eSecurityError, "Insecure: can't extend object");
- if (OBJ_FROZEN(klass)) rb_error_frozen("object");
if (FL_TEST(CLASS_OF(klass), FL_SINGLETON)) {
rb_clear_cache();
}
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index c97f86a6877..272a508e0ff 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -218,29 +218,31 @@ SRC
return true
end
-def have_func(func)
+def have_func(func, header=nil)
libs = $libs
-
- if /mswin32|mingw/ =~ RUBY_PLATFORM
- r = try_link(<<"SRC", libs)
+ src =
+ if /mswin32|mingw/ =~ RUBY_PLATFORM
+ r = <<"SRC"
#include <windows.h>
#include <winsock.h>
+SRC
+ else
+ ""
+ end
+ unless header.nil?
+ src << <<"SRC"
+#include <#{header}>
+SRC
+ end
+ r = try_link(src + <<"SRC", libs)
int main() { return 0; }
int t() { #{func}(); return 0; }
SRC
- unless r
- r = try_link(<<"SRC", libs)
-#include <windows.h>
-#include <winsock.h>
+ unless r
+ r = try_link(src + <<"SRC", libs)
int main() { return 0; }
int t() { void ((*p)()); p = (void ((*)()))#{func}; return 0; }
SRC
- end
- else
- r = try_link(<<"SRC", libs)
-int main() { return 0; }
-int t() { #{func}(); return 0; }
-SRC
end
unless r
return false
diff --git a/ext/md5/md5.txt b/ext/md5/md5.txt
index 0eca7c90253..e2b072401b0 100644
--- a/ext/md5/md5.txt
+++ b/ext/md5/md5.txt
@@ -25,6 +25,17 @@ Methods:
returns have value of the added strings as a 16 bytes string.
+ hexdigest
+
+ returns have value of the added strings as an 32 bytes ASCII
+ string. This method is equal to:
+
+ def hexdigest
+ ret = ''
+ digest.each_byte {|i| ret << sprintf('%02x', i) }
+ ret
+ end
+
update(str)
Update the MD5 object with the string. Repeated calls are
diff --git a/ext/md5/md5.txt.jp b/ext/md5/md5.txt.jp
index a1451f1175b..04cf32908d3 100644
--- a/ext/md5/md5.txt.jp
+++ b/ext/md5/md5.txt.jp
@@ -26,6 +26,18 @@ Methods:
今までに追加した文字列に対するハッシュ値を16バイト長の文字列で
返す.
+ hexdigest
+
+ 今までに追加した文字列に対するハッシュ値を、ASCIIコードを使って
+ 16進数の列を示す'fe5c2235f48d2bcc911afabea23cd5aa'のような32文字
+ の文字列にエンコードして返す。Rubyで書くと以下と同じ。
+
+ def hexdigest
+ ret = ''
+ digest.each_byte {|i| ret << sprintf('%02x', i) }
+ ret
+ end
+
update(str)
MD5オブジェクトに文字列を追加する。複数回updateを呼ぶことは文
diff --git a/hash.c b/hash.c
index e66ab126e9d..a8251dac7f9 100644
--- a/hash.c
+++ b/hash.c
@@ -268,8 +268,13 @@ static VALUE
rb_hash_dup(hash)
VALUE hash;
{
+ VALUE klass = CLASS_OF(hash);
+
NEWOBJ(dup, struct RHash);
- OBJSETUP(dup, CLASS_OF(hash), T_HASH);
+ while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
+ klass = (VALUE)RCLASS(klass)->super;
+ }
+ OBJSETUP(dup, klass, T_HASH);
dup->iter_lev = 0;
dup->ifnone = RHASH(hash)->ifnone;
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 1ee1d680bce..d14f9bd55af 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -210,32 +210,34 @@ SRC
return true
end
-def have_func(func)
+def have_func(func, header=nil)
printf "checking for %s()... ", func
STDOUT.flush
libs = $libs
-
- if /mswin32|mingw/ =~ RUBY_PLATFORM
- r = try_link(<<"SRC", libs)
+ src =
+ if /mswin32|mingw/ =~ RUBY_PLATFORM
+ r = <<"SRC"
#include <windows.h>
#include <winsock.h>
+SRC
+ else
+ ""
+ end
+ unless header.nil?
+ src << <<"SRC"
+#include <#{header}>
+SRC
+ end
+ r = try_link(src + <<"SRC", libs)
int main() { return 0; }
int t() { #{func}(); return 0; }
SRC
- unless r
- r = try_link(<<"SRC", libs)
-#include <windows.h>
-#include <winsock.h>
+ unless r
+ r = try_link(src + <<"SRC", libs)
int main() { return 0; }
int t() { void ((*p)()); p = (void ((*)()))#{func}; return 0; }
SRC
- end
- else
- r = try_link(<<"SRC", libs)
-int main() { return 0; }
-int t() { #{func}(); return 0; }
-SRC
end
unless r
print "no\n"
diff --git a/marshal.c b/marshal.c
index 4b385dc117e..19a06a99f42 100644
--- a/marshal.c
+++ b/marshal.c
@@ -397,7 +397,9 @@ w_object(obj, arg, limit)
char *path;
if (FL_TEST(klass, FL_SINGLETON)) {
- rb_raise(rb_eTypeError, "singleton can't be dumped");
+ if (RCLASS(klass)->m_tbl->num_entries > 0) {
+ rb_raise(rb_eTypeError, "singleton can't be dumped");
+ }
}
path = rb_class2name(klass);
w_unique(path, arg);
diff --git a/object.c b/object.c
index 410c964d0ea..b9333f75d8e 100644
--- a/object.c
+++ b/object.c
@@ -113,10 +113,14 @@ static VALUE
rb_obj_dup(obj)
VALUE obj;
{
- VALUE dup;
-
if (TYPE(obj) == T_OBJECT) {
- dup = rb_obj_alloc(RBASIC(obj)->klass);
+ VALUE klass = CLASS_OF(obj);
+ VALUE dup;
+
+ while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
+ klass = (VALUE)RCLASS(klass)->super;
+ }
+ dup = rb_obj_alloc(klass);
if (ROBJECT(obj)->iv_tbl) {
ROBJECT(dup)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl);
}
diff --git a/re.c b/re.c
index a28ac4a2355..a778efca6c4 100644
--- a/re.c
+++ b/re.c
@@ -373,7 +373,7 @@ static VALUE
rb_reg_kcode_m(re)
VALUE re;
{
- char *kcode = "$KCODE";
+ char *kcode;
if (FL_TEST(re, KCODE_FIXED)) {
switch (RBASIC(re)->flags & KCODE_MASK) {
@@ -386,11 +386,12 @@ rb_reg_kcode_m(re)
case KCODE_UTF8:
kcode = "utf8"; break;
default:
+ rb_bug("unknow kcode - should not happen");
break;
}
+ return rb_str_new2(kcode);
}
-
- return rb_str_new2(kcode);
+ return Qnil;
}
static Regexp*
diff --git a/ruby.h b/ruby.h
index e208c7a1132..40d128086eb 100644
--- a/ruby.h
+++ b/ruby.h
@@ -290,6 +290,7 @@ struct RData {
#define DATA_PTR(dta) (RDATA(dta)->data)
+#define RUBY_DATA_FUNC(func) ((void (*)_((void*)))func)
VALUE rb_data_object_alloc _((VALUE,void*,void (*) _((void*)),void (*) _((void*))));
#define Data_Make_Struct(klass,type,mark,free,sval) (\
sval = ALLOC(type),\
@@ -406,6 +407,7 @@ void rb_define_readonly_variable _((const char*,VALUE*));
void rb_define_const _((VALUE,const char*,VALUE));
void rb_define_global_const _((const char*,VALUE));
+#define RUBY_METHOD_FUNC(func) ((VALUE (*)__((...)))func)
void rb_define_method _((VALUE,const char*,VALUE(*)(),int));
void rb_define_module_function _((VALUE,const char*,VALUE(*)(),int));
void rb_define_global_function _((const char*,VALUE(*)(),int));
diff --git a/sample/tsvr.rb b/sample/tsvr.rb
index d6a5620d114..ebfad4beeb6 100644
--- a/sample/tsvr.rb
+++ b/sample/tsvr.rb
@@ -2,7 +2,6 @@
# usage: ruby tsvr.rb
require "socket"
-require "thread"
gs = TCPserver.open(0)
addr = gs.addr
@@ -10,10 +9,8 @@ addr.shift
printf("server is on %d\n", addr.join(":"))
while TRUE
- ns = gs.accept
- print(ns, " is accepted\n")
- Thread.start do
- s = ns # save to thread-local variable
+ Thread.start(gs.accept) do |s|
+ print(s, " is accepted\n")
while s.gets
s.write($_)
end
diff --git a/string.c b/string.c
index f547323a58b..f6ae91bdf1c 100644
--- a/string.c
+++ b/string.c
@@ -181,31 +181,34 @@ rb_str_dup(str)
VALUE str;
{
VALUE str2;
+ VALUE klass;
if (TYPE(str) != T_STRING) str = rb_str_to_str(str);
- if (OBJ_FROZEN(str)) return rb_str_new3(str);
- if (FL_TEST(str, STR_NO_ORIG)) {
+ klass = CLASS_OF(str);
+ while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
+ klass = (VALUE)RCLASS(klass)->super;
+ }
+
+ if (OBJ_FROZEN(str)) str2 = rb_str_new3(str);
+ else if (FL_TEST(str, STR_NO_ORIG)) {
str2 = rb_str_new(RSTRING(str)->ptr, RSTRING(str)->len);
- OBJ_INFECT(str2, str);
- return str2;
}
- if (RSTRING(str)->orig) {
+ else if (RSTRING(str)->orig) {
str2 = rb_str_new3(RSTRING(str)->orig);
- OBJ_INFECT(str2, str);
- return str2;
}
-
- str2 = rb_str_new4(str);
- {
+ else {
NEWOBJ(dup, struct RString);
- OBJSETUP(dup, rb_cString, T_STRING);
+ OBJSETUP(dup, klass, T_STRING);
+
+ str2 = rb_str_new4(str);
dup->len = RSTRING(str2)->len;
dup->ptr = RSTRING(str2)->ptr;
dup->orig = str2;
- OBJ_INFECT(dup, str);
-
- return (VALUE)dup;
+ str2 = (VALUE)dup;
}
+ OBJ_INFECT(str2, str);
+ RBASIC(str2)->klass = klass;
+ return str2;
}
@@ -326,7 +329,7 @@ rb_str_substr(str, beg, len)
VALUE str2;
if (len < 0) return Qnil;
- if (beg > RSTRING(str)->len) return Qnil;
+ if (beg >= RSTRING(str)->len) return Qnil;
if (beg < 0) {
beg += RSTRING(str)->len;
if (beg < 0) return Qnil;
diff --git a/time.c b/time.c
index 9028b7337d2..a165bafe7f8 100644
--- a/time.c
+++ b/time.c
@@ -316,6 +316,11 @@ make_time_t(tptr, utc_or_local)
tm = localtime(&guess);
if (!tm) goto error;
guess -= tm->tm_gmtoff;
+ tm = localtime(&guess);
+ if (!tm) goto error;
+ if (tm->tm_hour != tptr->tm_hour) {
+ guess += (tptr->tm_hour - tm->tm_hour)*3600;
+ }
#else
struct tm gt, lt;
long tzsec;
@@ -338,18 +343,17 @@ make_time_t(tptr, utc_or_local)
else {
tzsec += (gt.tm_yday - lt.tm_yday)*24*3600;
}
-
if (lt.tm_isdst) guess += 3600;
guess += tzsec;
if (guess < 0) {
goto out_of_range;
}
-#endif
tm = localtime(&guess);
if (!tm) goto error;
- if (tm->tm_hour != tptr->tm_hour) {
+ if (lt.tm_isdst != tm->tm_isdst) {
guess -= 3600;
}
+#endif
if (guess < 0) {
goto out_of_range;
}