summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog43
-rw-r--r--bignum.c56
-rw-r--r--class.c4
-rw-r--r--defines.h17
-rw-r--r--ext/socket/socket.c10
-rw-r--r--file.c27
-rw-r--r--lib/cgi/session.rb1
-rw-r--r--marshal.c8
-rw-r--r--math.c28
-rw-r--r--numeric.c2
-rw-r--r--sprintf.c106
-rw-r--r--struct.c18
-rw-r--r--variable.c31
-rw-r--r--version.h4
14 files changed, 209 insertions, 146 deletions
diff --git a/ChangeLog b/ChangeLog
index ff3b28d3fa..766c64a839 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+<<<<<<< ChangeLog
+Wed Apr 10 17:30:19 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * variable.c (rb_obj_remove_instance_variable): raise NameError if
+ specified instance variable is not defined.
+
+ * variable.c (generic_ivar_remove): modified to check ivar
+ existence.
+
Wed Apr 10 14:16:45 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* misc/ruby-mode.el (ruby-font-lock-keywords): fontify symbols for
@@ -29,6 +38,11 @@ Tue Apr 9 05:17:48 2002 Akinori MUSHA <knu@iDaemons.org>
* re.c (match_select): fix index references and make
MatchData#select actually work.
+Tue Apr 9 00:20:52 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * file.c (rb_file_s_extname): new method based on the proposal
+ (and patch) from Mike Hall. [new]
+
Mon Apr 8 04:50:51 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* eval.c (error_handle): default to 1 unless status is set.
@@ -37,6 +51,27 @@ Mon Apr 8 04:50:51 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* eval.c (ruby_stop): ditto.
+Mon Apr 8 01:22:24 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * math.c (math_acosh): added. [new]
+
+ * math.c (math_asinh): ditto.
+
+ * math.c (math_atanh): ditto.
+
+ * struct.c (rb_struct_each_pair): method added. [new]
+
+Sat Apr 6 02:04:49 2002 Guy Decoux <ts@moulon.inra.fr>
+
+ * class.c (rb_singleton_class): wrong condition; was creating
+ unnecessary singleton class.
+
+Sat Apr 6 01:09:41 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * sprintf.c (remove_sign_bits): simplifies the condition.
+
+ * bignum.c (get2comp): calculate proper carry over.
+
Fri Apr 5 05:07:28 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
* ext/dl: Add dl/struct.rb.
@@ -46,9 +81,9 @@ Thu Apr 4 14:08:52 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
* ext/dl/lib/dl/import.rb: Get rid of ineffective
encoding/decoding procedures.
-Wed Apr 3 15:37:24 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
+Thu Apr 4 01:08:23 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
- * ext/dl: Add dl/types.rb.
+ * numeric.c (int_step): step may be a float less than 1.
Wed Apr 3 20:42:34 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
@@ -56,6 +91,10 @@ Wed Apr 3 20:42:34 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
* ext/dl/dl.h: define StringValuePtr for ruby-1.6.
+Wed Apr 3 15:37:24 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
+
+ * ext/dl: Add dl/types.rb.
+
Wed Apr 3 01:54:10 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* ext/extmk.rb.in (enable_config): follow lib/mkmf.rb.
diff --git a/bignum.c b/bignum.c
index 6b558287c3..873d359540 100644
--- a/bignum.c
+++ b/bignum.c
@@ -20,26 +20,12 @@ VALUE rb_cBignum;
#define USHORT _USHORT
#endif
-#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
-typedef unsigned int BDIGIT;
-typedef unsigned LONG_LONG BDIGIT_DBL;
-typedef LONG_LONG BDIGIT_DBL_SIGNED;
-#elif SIZEOF_INT*2 <= SIZEOF_LONG
-typedef unsigned int BDIGIT;
-typedef unsigned long BDIGIT_DBL;
-typedef LONG_LONG BDIGIT_DBL_SIGNED;
-#else
-typedef unsigned short BDIGIT;
-typedef unsigned long BDIGIT_DBL;
-typedef long BDIGIT_DBL_SIGNED;
-#endif
-
#define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits)
-#define BITSPERDIG (sizeof(BDIGIT)*CHAR_BIT)
+#define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
-#define DIGSPERLONG ((unsigned int)(sizeof(long)/sizeof(BDIGIT)))
+#define DIGSPERLONG ((unsigned int)(SIZEOF_LONG/SIZEOF_BDIGITS))
#if HAVE_LONG_LONG
-# define DIGSPERLL ((unsigned int)(sizeof(LONG_LONG)/sizeof(BDIGIT)))
+# define DIGSPERLL ((unsigned int)(SIZEOF_LONG_LONG/SIZEOF_BDIGITS))
#endif
#define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG)
#define BIGDN(x) RSHIFT(x,BITSPERDIG)
@@ -89,14 +75,10 @@ get2comp(x, carry) /* get 2's complement */
num = BIGDN(num);
} while (i < RBIGNUM(x)->len);
if (!carry) return;
- if (ds[0] == 1 || ds[0] == 0) {
- if (RBIGNUM(x)->len == 1) return;
- for (i=1; i<RBIGNUM(x)->len; i++) {
- if (ds[i] != 0) return;
- }
+ if ((ds[RBIGNUM(x)->len-1] & (1<<(BITSPERDIG-1))) == 0) {
REALLOC_N(RBIGNUM(x)->digits, BDIGIT, RBIGNUM(x)->len++);
ds = BDIGITS(x);
- ds[RBIGNUM(x)->len-1] = 1;
+ ds[RBIGNUM(x)->len-1] = ~0;
}
}
@@ -118,7 +100,7 @@ bignorm(x)
while (len-- && !ds[len]) ;
RBIGNUM(x)->len = ++len;
- if (len*sizeof(BDIGIT) <= sizeof(VALUE)) {
+ if (len*SIZEOF_BDIGITS <= sizeof(VALUE)) {
long num = 0;
while (len--) {
num = BIGUP(num) + ds[len];
@@ -200,7 +182,7 @@ rb_int2inum(n)
#ifdef HAVE_LONG_LONG
-#define DIGSPERLONGLONG ((unsigned int)(sizeof(LONG_LONG)/sizeof(BDIGIT)))
+#define DIGSPERLONGLONG ((unsigned int)(SIZEOF_LONG_LONG/SIZEOF_BDIGITS))
void
rb_quad_pack(buf, val)
@@ -224,7 +206,7 @@ rb_quad_pack(buf, val)
q += ds[len];
}
}
- memcpy(buf, (char*)&q, sizeof(LONG_LONG));
+ memcpy(buf, (char*)&q, SIZEOF_LONG_LONG);
}
VALUE
@@ -238,7 +220,7 @@ rb_quad_unpack(buf, sign)
BDIGIT *digits;
VALUE big;
- memcpy(&q, buf, sizeof(LONG_LONG));
+ memcpy(&q, buf, SIZEOF_LONG_LONG);
if (sign) {
if (FIXABLE((LONG_LONG)q)) return INT2FIX((LONG_LONG)q);
if ((LONG_LONG)q < 0) {
@@ -284,7 +266,7 @@ rb_quad_pack(buf, val)
if (FIXNUM_P(val)) {
val = rb_int2big(FIX2LONG(val));
}
- len = RBIGNUM(val)->len * sizeof(BDIGIT);
+ len = RBIGNUM(val)->len * SIZEOF_BDIGITS;
if (len > QUAD_SIZE) len = QUAD_SIZE;
memcpy(buf, (char*)BDIGITS(val), len);
if (!RBIGNUM(val)->sign) {
@@ -296,14 +278,14 @@ rb_quad_pack(buf, val)
}
}
-#define BNEG(b) (RSHIFT(((BDIGIT*)b)[QUAD_SIZE/sizeof(BDIGIT)-1],BITSPERDIG-1) != 0)
+#define BNEG(b) (RSHIFT(((BDIGIT*)b)[QUAD_SIZE/SIZEOF_BDIGITS-1],BITSPERDIG-1) != 0)
VALUE
rb_quad_unpack(buf, sign)
const char *buf;
int sign;
{
- VALUE big = bignew(QUAD_SIZE/sizeof(BDIGIT), 1);
+ VALUE big = bignew(QUAD_SIZE/SIZEOF_BDIGITS, 1);
memcpy((char*)BDIGITS(big), buf, QUAD_SIZE);
if (sign && BNEG(buf)) {
@@ -607,19 +589,19 @@ rb_big2str(x, base)
i = RBIGNUM(x)->len;
if (i == 0) return rb_str_new2("0");
if (base == 10) {
- j = (sizeof(BDIGIT)/sizeof(char)*CHAR_BIT*i*241L)/800+2;
+ j = (SIZEOF_BDIGITS/sizeof(char)*CHAR_BIT*i*241L)/800+2;
hbase = 10000;
}
else if (base == 16) {
- j = (sizeof(BDIGIT)/sizeof(char)*CHAR_BIT*i)/4+2;
+ j = (SIZEOF_BDIGITS/sizeof(char)*CHAR_BIT*i)/4+2;
hbase = 0x10000;
}
else if (base == 8) {
- j = (sizeof(BDIGIT)/sizeof(char)*CHAR_BIT*i)+2;
+ j = (SIZEOF_BDIGITS/sizeof(char)*CHAR_BIT*i)+2;
hbase = 010000;
}
else if (base == 2) {
- j = (sizeof(BDIGIT)*CHAR_BIT*i)+2;
+ j = (SIZEOF_BDIGITS*CHAR_BIT*i)+2;
hbase = 020;
}
else {
@@ -682,7 +664,7 @@ big2ulong(x, type)
BDIGIT_DBL num;
BDIGIT *ds;
- if (len > sizeof(long)/sizeof(BDIGIT))
+ if (len > SIZEOF_LONG/SIZEOF_BDIGITS)
rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
ds = BDIGITS(x);
num = 0;
@@ -727,7 +709,7 @@ big2ull(x, type)
BDIGIT_DBL num;
BDIGIT *ds;
- if (len > sizeof(LONG_LONG)/sizeof(BDIGIT))
+ if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS)
rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
ds = BDIGITS(x);
num = 0;
@@ -1715,7 +1697,7 @@ static VALUE
rb_big_size(big)
VALUE big;
{
- return INT2FIX(RBIGNUM(big)->len*sizeof(BDIGIT));
+ return INT2FIX(RBIGNUM(big)->len*SIZEOF_BDIGITS);
}
static VALUE
diff --git a/class.c b/class.c
index 26b2ba7f28..45dcf417b1 100644
--- a/class.c
+++ b/class.c
@@ -695,8 +695,8 @@ rb_singleton_class(obj)
DEFER_INTS;
if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
- (BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE) &&
- rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
+ ((BUILTIN_TYPE(obj) != T_CLASS && BUILTIN_TYPE(obj) != T_MODULE) ||
+ rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj)) {
klass = RBASIC(obj)->klass;
}
else {
diff --git a/defines.h b/defines.h
index c79178adc8..b4a1894d71 100644
--- a/defines.h
+++ b/defines.h
@@ -64,6 +64,23 @@ void xfree _((void*));
# define SIZEOF_LONG_LONG SIZEOF___INT64
#endif
+#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
+# define BDIGIT unsigned int
+# define SIZEOF_BDIGITS SIZEOF_INT
+# define BDIGIT_DBL unsigned LONG_LONG
+# define BDIGIT_DBL_SIGNED LONG_LONG
+#elif SIZEOF_INT*2 <= SIZEOF_LONG
+# define BDIGIT unsigned int
+# define SIZEOF_BDIGITS SIZEOF_INT
+# define BDIGIT_DBL unsigned long
+# define BDIGIT_DBL_SIGNED long
+#else
+# define BDIGIT unsigned short
+# define SIZEOF_BDIGITS SIZEOF_SHORT
+# define BDIGIT_DBL unsigned long
+# define BDIGIT_DBL_SIGNED long
+#endif
+
/* define RUBY_USE_EUC/SJIS for default kanji-code */
#ifndef DEFAULT_KCODE
#if defined(MSDOS) || defined(__CYGWIN__) || defined(__human68k__) || defined(__MACOS__) || defined(__EMX__) || defined(OS2) || defined(NT)
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 9a64399637..e2f1f0ce12 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -770,7 +770,7 @@ ruby_connect(fd, sockaddr, len, socks)
case EAGAIN:
#ifdef EINPROGRESS
case EINPROGRESS:
-#if defined __CYGWIN__
+#ifdef __CYGWIN__
case EALREADY:
wait_in_progress = 10;
#endif
@@ -2224,6 +2224,10 @@ sock_s_unpack_sockaddr_in(self, addr)
struct sockaddr_in * sockaddr;
sockaddr = (struct sockaddr_in*)StringValuePtr(addr);
+ if (RSTRING(addr)->len != sizeof(struct sockaddr_in)) {
+ rb_raise(rb_eTypeError, "sockaddr_in size differs - %d required; %d given",
+ RSTRING(addr)->len, sizeof(struct sockaddr_in));
+ }
return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), mkipaddr(sockaddr));
}
@@ -2251,6 +2255,10 @@ sock_s_unpack_sockaddr_un(self, addr)
struct sockaddr_un * sockaddr;
sockaddr = (struct sockaddr_un*)StringValuePtr(addr);
+ if (RSTRING(addr)->len != sizeof(struct sockaddr_un)) {
+ rb_raise(rb_eTypeError, "sockaddr_un size differs - %d required; %d given",
+ RSTRING(addr)->len, sizeof(struct sockaddr_un));
+ }
/* xxx: should I check against sun_path size? */
return rb_tainted_str_new2(sockaddr->sun_path);
}
diff --git a/file.c b/file.c
index 1735012584..ca036ea5d3 100644
--- a/file.c
+++ b/file.c
@@ -1564,9 +1564,9 @@ rmext(p, e)
{
int l1, l2;
- l1 = strlen(p);
if (!e) return 0;
+ l1 = strlen(p);
l2 = strlen(e);
if (l2 == 2 && e[1] == '*') {
e = strrchr(p, *e);
@@ -1628,11 +1628,33 @@ rb_file_s_dirname(klass, fname)
if (p == name)
p++;
dirname = rb_str_new(name, p - name);
- if (OBJ_TAINTED(fname)) OBJ_TAINT(dirname);
+ OBJ_INFECT(dirname, fname);
return dirname;
}
static VALUE
+rb_file_s_extname(klass, fname)
+ VALUE klass, fname;
+{
+ char *name, *p, *e;
+ VALUE extname;
+
+ name = StringValuePtr(fname);
+ p = strrdirsep(name); /* get the last path component */
+ if (!p)
+ p = name;
+ else
+ p++;
+
+ e = strrchr(p, '.'); /* get the last dot of the last component */
+ if (!e || e == p) /* no dot, or the only dot is first? */
+ return rb_str_new2("");
+ extname = rb_str_new2(e); /* keep the dot, too! */
+ OBJ_INFECT(extname, fname);
+ return extname;
+}
+
+static VALUE
rb_file_s_split(klass, path)
VALUE klass, path;
{
@@ -2559,6 +2581,7 @@ Init_File()
rb_define_singleton_method(rb_cFile, "expand_path", rb_file_s_expand_path, -1);
rb_define_singleton_method(rb_cFile, "basename", rb_file_s_basename, -1);
rb_define_singleton_method(rb_cFile, "dirname", rb_file_s_dirname, 1);
+ rb_define_singleton_method(rb_cFile, "extname", rb_file_s_extname, 1);
separator = rb_obj_freeze(rb_str_new2("/"));
rb_define_const(rb_cFile, "Separator", separator);
diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb
index eb8f0cbaf6..cfefa8f0b0 100644
--- a/lib/cgi/session.rb
+++ b/lib/cgi/session.rb
@@ -137,6 +137,7 @@ class CGI
end
def update
+ return unless @hash
@f.rewind
for k,v in @hash
@f.printf "%s=%s\n", CGI::escape(k), CGI::escape(String(v))
diff --git a/marshal.c b/marshal.c
index 4bd7a35ecb..0aefac1f8d 100644
--- a/marshal.c
+++ b/marshal.c
@@ -20,14 +20,6 @@
double strtod();
#endif
-#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG || SIZEOF_INT*2 <= SIZEOF_LONG
-typedef unsigned int BDIGIT;
-#define SIZEOF_BDIGITS SIZEOF_INT
-#else
-typedef unsigned short BDIGIT;
-#define SIZEOF_BDIGITS SIZEOF_SHORT
-#endif
-
#define BITSPERSHORT (2*CHAR_BIT)
#define SHORTMASK ((1<<BITSPERSHORT)-1)
#define SHORTDN(x) RSHIFT(x,BITSPERSHORT)
diff --git a/math.c b/math.c
index 4af3cef96e..c900a0b7aa 100644
--- a/math.c
+++ b/math.c
@@ -113,6 +113,30 @@ math_tanh(obj, x)
}
static VALUE
+math_acosh(obj, x)
+ VALUE obj, x;
+{
+ Need_Float(x);
+ return rb_float_new(acosh(RFLOAT(x)->value));
+}
+
+static VALUE
+math_asinh(obj, x)
+ VALUE obj, x;
+{
+ Need_Float(x);
+ return rb_float_new(asinh(RFLOAT(x)->value));
+}
+
+static VALUE
+math_atanh(obj, x)
+ VALUE obj, x;
+{
+ Need_Float(x);
+ return rb_float_new(atanh(RFLOAT(x)->value));
+}
+
+static VALUE
math_exp(obj, x)
VALUE obj, x;
{
@@ -212,6 +236,10 @@ Init_Math()
rb_define_module_function(rb_mMath, "sinh", math_sinh, 1);
rb_define_module_function(rb_mMath, "tanh", math_tanh, 1);
+ rb_define_module_function(rb_mMath, "acosh", math_acosh, 1);
+ rb_define_module_function(rb_mMath, "asinh", math_asinh, 1);
+ rb_define_module_function(rb_mMath, "atanh", math_atanh, 1);
+
rb_define_module_function(rb_mMath, "exp", math_exp, 1);
rb_define_module_function(rb_mMath, "log", math_log, 1);
rb_define_module_function(rb_mMath, "log10", math_log10, 1);
diff --git a/numeric.c b/numeric.c
index 39703fae31..c24c49d9c7 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1483,7 +1483,7 @@ int_step(from, to, step)
VALUE i = from;
ID cmp;
- if (NUM2INT(step) == 0) {
+ if (rb_equal(step, INT2FIX(0))) {
rb_raise(rb_eArgError, "step cannot be 0");
}
diff --git a/sprintf.c b/sprintf.c
index c1e6b47f84..e9742f3fd5 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -26,78 +26,26 @@ remove_sign_bits(str, base)
int base;
{
char *s, *t, *end;
+ int len;
s = t = str;
- end = str + strlen(str);
+ len = strlen(str);
+ end = str + len;
if (base == 16) {
- x_retry:
- switch (*t) {
- case 'c': case 'C':
- *t = '4';
- break;
- case 'd': case 'D':
- *t = '5';
- break;
- case 'e': case 'E':
- *t = '2';
- break;
- case 'f': case 'F':
- if (t[1] > '8') {
- t++;
- goto x_retry;
- }
- *t = '1';
- break;
- case '1':
- case '3':
- case '7':
- if (t[1] > '8') {
- t++;
- goto x_retry;
- }
- break;
- }
- switch (*t) {
- case '1': *t = 'f'; break;
- case '2': *t = 'e'; break;
- case '3': *t = 'f'; break;
- case '4': *t = 'c'; break;
- case '5': *t = 'd'; break;
- case '6': *t = 'e'; break;
- case '7': *t = 'f'; break;
+ while (t<end && *t == 'f') {
+ t++;
}
}
else if (base == 8) {
- o_retry:
- switch (*t) {
- case '6':
- *t = '2';
- break;
- case '7':
- if (t[1] > '3') {
- t++;
- goto o_retry;
- }
- *t = '1';
- break;
- case '1':
- case '3':
- if (t[1] > '3') {
- t++;
- goto o_retry;
- }
- break;
- }
- switch (*t) {
- case '1': *t = '7'; break;
- case '2': *t = '6'; break;
- case '3': *t = '7'; break;
+ while (t<end && *t == '7') {
+ t++;
}
}
else if (base == 2) {
- while (t<end && *t == '1') t++;
- t--;
+ while (t<end && *t == '1') {
+ t++;
+ }
}
while (*t) *s++ = *t++;
*s = '\0';
@@ -398,12 +346,12 @@ rb_f_sprintf(argc, argv)
case T_BIGNUM:
bignum = 1;
break;
- default:
- v = NUM2LONG(val);
- break;
case T_FIXNUM:
v = FIX2LONG(val);
break;
+ default:
+ v = NUM2LONG(val);
+ break;
}
if (*p == 'u' || *p == 'd' || *p == 'i') base = 10;
@@ -454,8 +402,7 @@ rb_f_sprintf(argc, argv)
remove_sign_bits(s, base);
switch (base) {
case 16:
- d = 'f';
- break;
+ d = 'f'; break;
case 8:
d = '7'; break;
}
@@ -493,24 +440,27 @@ rb_f_sprintf(argc, argv)
val = rb_big2str(val, base);
s = RSTRING(val)->ptr;
if (*s == '-') {
- remove_sign_bits(++s, base);
- val = rb_str_new(0, 3+strlen(s));
- t = RSTRING(val)->ptr;
if (base == 10) {
rb_warning("negative number for %%u specifier");
+ s++;
}
else {
+ remove_sign_bits(++s, base);
+ val = rb_str_new(0, 3+strlen(s));
+ t = RSTRING(val)->ptr;
strcpy(t, "..");
t += 2;
- }
- switch (base) {
- case 16:
- if (s[0] != 'f') strcpy(t++, "f"); break;
- case 8:
- if (s[0] != '7') strcpy(t++, "7"); break;
+ switch (base) {
+ case 16:
+ if (s[0] != 'f') strcpy(t++, "f"); break;
+ case 8:
+ if (s[0] != '7') strcpy(t++, "7"); break;
+ case 2:
+ if (s[0] != '1') strcpy(t++, "1"); break;
+ }
+ strcpy(t, s);
+ bignum = 2;
}
- strcpy(t, s);
- bignum = 2;
}
s = RSTRING(val)->ptr;
diff --git a/struct.c b/struct.c
index 6a2bb640ab..7e97e170f5 100644
--- a/struct.c
+++ b/struct.c
@@ -334,6 +334,23 @@ rb_struct_each(s)
}
static VALUE
+rb_struct_each_pair(s)
+ VALUE s;
+{
+ VALUE member;
+ long i;
+
+ member = rb_struct_iv_get(rb_obj_class(s), "__member__");
+ if (NIL_P(member)) {
+ rb_bug("non-initialized struct");
+ }
+ for (i=0; i<RSTRUCT(s)->len; i++) {
+ rb_yield(rb_assoc_new(RARRAY(member)->ptr[i], RSTRUCT(s)->ptr[i]));
+ }
+ return s;
+}
+
+static VALUE
rb_struct_to_s(s)
VALUE s;
{
@@ -584,6 +601,7 @@ Init_Struct()
rb_define_method(rb_cStruct, "length", rb_struct_size, 0);
rb_define_method(rb_cStruct, "each", rb_struct_each, 0);
+ rb_define_method(rb_cStruct, "each_pair", rb_struct_each_pair, 0);
rb_define_method(rb_cStruct, "[]", rb_struct_aref, 1);
rb_define_method(rb_cStruct, "[]=", rb_struct_aset, 2);
rb_define_method(rb_cStruct, "select", rb_struct_select, -1);
diff --git a/variable.c b/variable.c
index e8b8605576..9a25caa2a7 100644
--- a/variable.c
+++ b/variable.c
@@ -259,7 +259,7 @@ rb_autoload_id(id, filename)
{
rb_secure(4);
if (!rb_is_const_id(id)) {
- rb_name_error(id, "autoload must be constant name", rb_id2name(id));
+ rb_name_error(id, "autoload must be constant name");
}
if (!autoload_tbl) {
@@ -845,22 +845,23 @@ generic_ivar_defined(obj, id)
return Qfalse;
}
-static VALUE
-generic_ivar_remove(obj, id)
+static int
+generic_ivar_remove(obj, id, valp)
VALUE obj;
ID id;
+ VALUE *valp;
{
st_table *tbl;
- VALUE val;
+ int status;
- if (!generic_iv_tbl) return Qnil;
- if (!st_lookup(generic_iv_tbl, obj, &tbl)) return Qnil;
- st_delete(tbl, &id, &val);
+ if (!generic_iv_tbl) return 0;
+ if (!st_lookup(generic_iv_tbl, obj, &tbl)) return 0;
+ status = st_delete(tbl, &id, valp);
if (tbl->num_entries == 0) {
st_delete(generic_iv_tbl, &obj, &tbl);
st_free_table(tbl);
}
- return val;
+ return status;
}
void
@@ -1052,16 +1053,20 @@ rb_obj_remove_instance_variable(obj, name)
case T_OBJECT:
case T_CLASS:
case T_MODULE:
- if (ROBJECT(obj)->iv_tbl) {
- st_delete(ROBJECT(obj)->iv_tbl, &id, &val);
+ if (ROBJECT(obj)->iv_tbl && st_delete(ROBJECT(obj)->iv_tbl, &id, &val)) {
+ return val;
}
break;
default:
- if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
- return generic_ivar_remove(obj, id);
+ if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
+ if (generic_ivar_remove(obj, id, &val)) {
+ return val;
+ }
+ }
break;
}
- return val;
+ rb_name_error(id, "instance variable %s not defined", rb_id2name(id));
+ return Qnil; /* not reached */
}
static int
diff --git a/version.h b/version.h
index 1dea5091c8..d22da4f8af 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
#define RUBY_VERSION "1.7.2"
-#define RUBY_RELEASE_DATE "2002-04-09"
+#define RUBY_RELEASE_DATE "2002-04-10"
#define RUBY_VERSION_CODE 172
-#define RUBY_RELEASE_CODE 20020409
+#define RUBY_RELEASE_CODE 20020410