yarv-diff:219
From: ko1 atdot.net
Date: 9 Feb 2006 17:49:57 -0000
Subject: [yarv-diff:219] r377 - trunk
Author: matz
Date: 2006-02-10 02:49:56 +0900 (Fri, 10 Feb 2006)
New Revision: 377
Modified:
trunk/defines.h
trunk/dir.c
trunk/error.c
trunk/file.c
trunk/gc.c
trunk/io.c
trunk/marshal.c
trunk/process.c
trunk/range.c
trunk/ruby.h
trunk/string.c
trunk/struct.c
Log:
merge 1.9 modifies.
Modified: trunk/defines.h
===================================================================
--- trunk/defines.h 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/defines.h 2006-02-09 17:49:56 UTC (rev 377)
@@ -2,8 +2,8 @@
defines.h -
- $Author: nobu $
- $Date: 2005/10/25 16:59:15 $
+ $Author: akr $
+ $Date: 2006/01/22 13:34:41 $
created at: Wed May 18 00:21:44 JST 1994
************************************************/
@@ -48,11 +48,11 @@
#define xrealloc2 ruby_xrealloc2
#define xfree ruby_xfree
-void *xmalloc(long);
-void *xmalloc2(long,long);
-void *xcalloc(long,long);
-void *xrealloc(void*,long);
-void *xrealloc2(void*,long,long);
+void *xmalloc(size_t);
+void *xmalloc2(size_t,size_t);
+void *xcalloc(size_t,size_t);
+void *xrealloc(void*,size_t);
+void *xrealloc2(void*,size_t,size_t);
void xfree(void*);
#if SIZEOF_LONG_LONG > 0
@@ -230,9 +230,10 @@
;
}
# define FLUSH_REGISTER_WINDOWS flush_register_windows()
-#elif defined(__ia64__)
-NOINLINE(void flush_register_windows(void));
-# define FLUSH_REGISTER_WINDOWS flush_register_windows()
+#elif defined(__ia64)
+void *rb_ia64_bsp(void);
+void rb_ia64_flushrs(void);
+# define FLUSH_REGISTER_WINDOWS rb_ia64_flushrs()
#else
# define FLUSH_REGISTER_WINDOWS ((void)0)
#endif
Modified: trunk/dir.c
===================================================================
--- trunk/dir.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/dir.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -3,7 +3,7 @@
dir.c -
$Author: nobu $
- $Date: 2005/09/16 13:46:03 $
+ $Date: 2005/12/14 14:40:14 $
created at: Wed Jan 5 09:51:01 JST 1994
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -67,10 +67,23 @@
#define lstat stat
#endif
+#ifndef CASEFOLD_FILESYSTEM
+# if defined DOSISH || defined __VMS
+# define CASEFOLD_FILESYSTEM 1
+# else
+# define CASEFOLD_FILESYSTEM 0
+# endif
+#endif
+
#define FNM_NOESCAPE 0x01
#define FNM_PATHNAME 0x02
#define FNM_DOTMATCH 0x04
#define FNM_CASEFOLD 0x08
+#if CASEFOLD_FILESYSTEM
+#define FNM_SYSCASE FNM_CASEFOLD
+#else
+#define FNM_SYSCASE 0
+#endif
#define FNM_NOMATCH 1
#define FNM_ERROR 2
@@ -121,7 +134,7 @@
if (len2 == 0) return -len1;
#ifdef _WIN32
- if (nocase) {
+ if (nocase && rb_w32_iswinnt()) {
if (len1 > 1) {
if (len1 >= sizeof(buf1)) {
rb_fatal("CompareImpl: too large len");
@@ -931,6 +944,7 @@
has_magic(const char *s, int flags)
{
const int escape = !(flags & FNM_NOESCAPE);
+ const int nocase = flags & FNM_CASEFOLD;
register const char *p = s;
register char c;
@@ -946,6 +960,10 @@
if (escape && !(c = *p++))
return 0;
continue;
+
+ default:
+ if (!FNM_SYSCASE && ISALPHA(c) && nocase)
+ return 1;
}
p = Next(p-1);
@@ -1295,11 +1313,9 @@
int status;
start = root = path;
+ flags |= FNM_SYSCASE;
#if defined DOSISH
- flags |= FNM_CASEFOLD;
root = rb_path_skip_prefix(root);
-#else
- flags &= ~FNM_CASEFOLD;
#endif
if (root && *root == '/') root++;
@@ -1342,8 +1358,8 @@
args.func = func;
args.value = arg;
- if (flags & FNM_CASEFOLD) {
- rb_warn("Dir.glob() ignores File::FNM_CASEFOLD");
+ if (flags & FNM_SYSCASE) {
+ rb_warning("Dir.glob() ignores File::FNM_CASEFOLD");
}
return ruby_glob0(path, flags | GLOB_VERBOSE, rb_glob_caller, (VALUE)&args);
@@ -1822,4 +1838,5 @@
rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME));
rb_file_const("FNM_DOTMATCH", INT2FIX(FNM_DOTMATCH));
rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD));
+ rb_file_const("FNM_SYSCASE", INT2FIX(FNM_SYSCASE));
}
Modified: trunk/error.c
===================================================================
--- trunk/error.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/error.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -967,7 +967,13 @@
rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
rb_eKeyError = rb_define_class("KeyError", rb_eIndexError);
rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
- rb_eNameError = rb_define_class("NameError", rb_eStandardError);
+
+ rb_eScriptError = rb_define_class("ScriptError", rb_eException);
+ rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
+ rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
+ rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
+
+ rb_eNameError = rb_define_class("NameError", rb_eScriptError);
rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
rb_define_method(rb_eNameError, "name", name_err_name, 0);
rb_define_method(rb_eNameError, "to_s", name_err_to_s, 0);
@@ -981,11 +987,6 @@
rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
- rb_eScriptError = rb_define_class("ScriptError", rb_eException);
- rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
- rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
- rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
-
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
rb_eSecurityError = rb_define_class("SecurityError", rb_eStandardError);
rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
Modified: trunk/file.c
===================================================================
--- trunk/file.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/file.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -2,8 +2,8 @@
file.c -
- $Author: eban $
- $Date: 2005/10/12 02:26:14 $
+ $Author: ocean $
+ $Date: 2006/02/06 07:26:16 $
created at: Mon Nov 15 12:24:34 JST 1993
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -53,10 +53,6 @@
#include <pwd.h>
#endif
-#ifndef HAVE_STRING_H
-char *strrchr(const char*,const char);
-#endif
-
#include <sys/types.h>
#include <sys/stat.h>
@@ -68,6 +64,33 @@
#define lstat stat
#endif
+#ifdef __BEOS__ /* should not change ID if -1 */
+static int
+be_chown(const char *path, uid_t owner, gid_t group)
+{
+ if (owner == -1 || group == -1) {
+ struct stat st;
+ if (stat(path, &st) < 0) return -1;
+ if (owner == -1) owner = st.st_uid;
+ if (group == -1) group = st.st_gid;
+ }
+ return chown(path, owner, group);
+}
+#define chown be_chown
+static int
+be_fchown(int fd, uid_t owner, gid_t group)
+{
+ if (owner == -1 || group == -1) {
+ struct stat st;
+ if (fstat(fd, &st) < 0) return -1;
+ if (owner == -1) owner = st.st_uid;
+ if (group == -1) group = st.st_gid;
+ }
+ return fchown(fd, owner, group);
+}
+#define fchown be_fchown
+#endif /* __BEOS__ */
+
VALUE rb_cFile;
VALUE rb_mFileTest;
static VALUE rb_cStat;
@@ -613,6 +636,38 @@
return stat(StringValueCStr(file), st);
}
+#ifdef _WIN32
+static HANDLE
+w32_io_info(VALUE *file, BY_HANDLE_FILE_INFORMATION *st)
+{
+ VALUE tmp;
+ HANDLE f, ret = 0;
+
+ tmp = rb_check_convert_type(*file, T_FILE, "IO", "to_io");
+ if (!NIL_P(tmp)) {
+ OpenFile *fptr;
+
+ GetOpenFile(tmp, fptr);
+ f = (HANDLE)rb_w32_get_osfhandle(fptr->fd);
+ if (f == (HANDLE)-1) return INVALID_HANDLE_VALUE;
+ }
+ else {
+ FilePathValue(*file);
+ f = CreateFile(StringValueCStr(*file), 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ rb_w32_iswin95() ? 0 : FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (f == INVALID_HANDLE_VALUE) return f;
+ ret = f;
+ }
+ if (GetFileType(f) == FILE_TYPE_DISK) {
+ ZeroMemory(st, sizeof(*st));
+ if (GetFileInformationByHandle(f, st)) return ret;
+ }
+ if (ret) CloseHandle(ret);
+ return INVALID_HANDLE_VALUE;
+}
+#endif
+
/*
* call-seq:
* File.stat(file_name) => stat
@@ -763,6 +818,7 @@
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
#endif
+#ifndef HAVE_EACCESS
int
eaccess(const char *path, int mode)
{
@@ -802,6 +858,7 @@
return access(path, mode);
#endif
}
+#endif
/*
@@ -1292,7 +1349,7 @@
* call-seq:
* File.setuid?(file_name) => true or false
*
- * Returns <code>true</code> if the named file is a has the setuid bit set.
+ * Returns <code>true</code> if the named file has the setuid bit set.
*/
static VALUE
@@ -1309,7 +1366,7 @@
* call-seq:
* File.setgid?(file_name) => true or false
*
- * Returns <code>true</code> if the named file is a has the setgid bit set.
+ * Returns <code>true</code> if the named file has the setgid bit set.
*/
static VALUE
@@ -1326,7 +1383,7 @@
* call-seq:
* File.sticky?(file_name) => true or false
*
- * Returns <code>true</code> if the named file is a has the sticky bit set.
+ * Returns <code>true</code> if the named file has the sticky bit set.
*/
static VALUE
@@ -1341,6 +1398,70 @@
/*
* call-seq:
+ * File.identical?(file_1, file_2) => true or false
+ *
+ * Returns <code>true</code> if the named files are identical.
+ *
+ * open("a", "w") {}
+ * p File.identical?("a", "a") #=> true
+ * p File.identical?("a", "./a") #=> true
+ * File.link("a", "b")
+ * p File.identical?("a", "b") #=> true
+ * File.symlink("a", "c")
+ * p File.identical?("a", "c") #=> true
+ * open("d", "w") {}
+ * p File.identical?("a", "d") #=> false
+ */
+
+static VALUE
+test_identical(VALUE obj, VALUE fname1, VALUE fname2)
+{
+#ifndef DOSISH
+ struct stat st1, st2;
+
+ if (rb_stat(fname1, &st1) < 0) return Qfalse;
+ if (rb_stat(fname2, &st2) < 0) return Qfalse;
+ if (st1.st_dev != st2.st_dev) return Qfalse;
+ if (st1.st_ino != st2.st_ino) return Qfalse;
+#else
+#ifdef _WIN32
+ BY_HANDLE_FILE_INFORMATION st1, st2;
+ HANDLE f1 = 0, f2 = 0;
+#endif
+
+ rb_secure(2);
+#ifdef _WIN32
+ f1 = w32_io_info(&fname1, &st1);
+ if (f1 == INVALID_HANDLE_VALUE) return Qfalse;
+ f2 = w32_io_info(&fname2, &st2);
+ if (f1) CloseHandle(f1);
+ if (f2 == INVALID_HANDLE_VALUE) return Qfalse;
+ if (f2) CloseHandle(f2);
+
+ if (st1.dwVolumeSerialNumber == st2.dwVolumeSerialNumber &&
+ st1.nFileIndexHigh == st2.nFileIndexHigh &&
+ st1.nFileIndexLow == st2.nFileIndexLow)
+ return Qtrue;
+ if (!f1 || !f2) return Qfalse;
+ if (rb_w32_iswin95()) return Qfalse;
+#else
+ FilePathValue(fname1);
+ fname1 = rb_str_new4(fname1);
+ FilePathValue(fname2);
+ if (access(RSTRING(fname1)->ptr, 0)) return Qfalse;
+ if (access(RSTRING(fname2)->ptr, 0)) return Qfalse;
+#endif
+ fname1 = rb_file_expand_path(fname1, Qnil);
+ fname2 = rb_file_expand_path(fname2, Qnil);
+ if (RSTRING(fname1)->len != RSTRING(fname2)->len) return Qfalse;
+ if (rb_memcicmp(RSTRING(fname1)->ptr, RSTRING(fname2)->ptr, RSTRING(fname1)->len))
+ return Qfalse;
+#endif
+ return Qtrue;
+}
+
+/*
+ * call-seq:
* File.size(file_name) => integer
*
* Returns the size of <code>file_name</code>.
@@ -1562,7 +1683,7 @@
static void
chmod_internal(const char *path, void *mode)
{
- if (chmod(path, (int)mode) < 0)
+ if (chmod(path, *(int *)mode) < 0)
rb_sys_fail(path);
}
@@ -1591,7 +1712,7 @@
rb_scan_args(argc, argv, "1*", &vmode, &rest);
mode = NUM2INT(vmode);
- n = apply2files(chmod_internal, rest, (void *)(long)mode);
+ n = apply2files(chmod_internal, rest, &mode);
return LONG2FIX(n);
}
@@ -1986,7 +2107,11 @@
rb_secure(2);
FilePathValue(path);
buf = xmalloc(size);
- while ((rv = readlink(StringValueCStr(path), buf, size)) == size) {
+ while ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size
+#ifdef _AIX
+ || (rv < 0 && errno == ERANGE) /* quirky behavior of GPFS */
+#endif
+ ) {
size *= 2;
buf = xrealloc(buf, size);
}
@@ -2053,7 +2178,7 @@
dst = StringValueCStr(to);
if (rename(src, dst) < 0) {
#if defined __CYGWIN__
- extern unsigned long __attribute__((stdcall)) GetLastError();
+ extern unsigned long __attribute__((stdcall)) GetLastError(void);
errno = GetLastError(); /* This is a Cygwin bug */
#elif defined DOSISH && !defined _WIN32
if (errno == EEXIST
@@ -2187,14 +2312,20 @@
return (char *)s;
}
+#if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
#define skipprefix rb_path_skip_prefix
+#else
+#define skipprefix(path) (path)
+#endif
char *
rb_path_skip_prefix(const char *path)
{
#if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
#ifdef DOSISH_UNC
if (isdirsep(path[0]) && isdirsep(path[1])) {
- if (*(path = nextdirsep(path + 2)))
+ path += 2;
+ while (isdirsep(*path)) path++;
+ if (*(path = nextdirsep(path)) && path[1] && !isdirsep(path[1]))
path = nextdirsep(path + 1);
return (char *)path;
}
@@ -2542,6 +2673,9 @@
{
VALUE fname, fext, basename;
char *name, *p;
+#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
+ char *root;
+#endif
int f;
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
@@ -2550,15 +2684,31 @@
StringValue(fname);
if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr))
return fname;
- if (!*(name = skiproot(name))) {
+ name = skipprefix(name);
+#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
+ root = name;
+#endif
+ while (isdirsep(*name))
+ name++;
+ if (!*name) {
p = name - 1;
f = 1;
+#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
+ if (name != root) {
+ /* has slashes */
+ }
#ifdef DOSISH_DRIVE_LETTER
- if (*p == ':') {
+ else if (*p == ':') {
p++;
f = 0;
}
#endif
+#ifdef DOSISH_UNC
+ else {
+ p = "/";
+ }
+#endif
+#endif
}
else if (!(p = strrdirsep(name))) {
if (NIL_P(fext) || !(f = rmext(name, StringValueCStr(fext)))) {
@@ -2599,8 +2749,8 @@
name = StringValueCStr(fname);
root = skiproot(name);
#ifdef DOSISH_UNC
- if (root > name + 2 && isdirsep(*name))
- name = root - 2;
+ if (root > name + 1 && isdirsep(*name))
+ root = skipprefix(name = root - 2);
#else
if (root > name + 1)
name = root - 1;
@@ -2611,9 +2761,16 @@
}
if (p == name)
return rb_str_new2(".");
+#ifdef DOSISH_DRIVE_LETTER
+ if (has_drive_letter(name) && isdirsep(*(name + 2))) {
+ dirname = rb_str_new(name, 3);
+ rb_str_cat(dirname, skiproot(name + 2), p - skiproot(name + 2));
+ }
+ else
+#endif
dirname = rb_str_new(name, p - name);
#ifdef DOSISH_DRIVE_LETTER
- if (root == name + 2 && name[1] == ':')
+ if (has_drive_letter(name) && root == name + 2 && p - name == 2)
rb_str_cat(dirname, ".", 1);
#endif
OBJ_INFECT(dirname, fname);
@@ -2745,7 +2902,7 @@
name = StringValueCStr(result);
if (i > 0 && !NIL_P(sep)) {
tail = chompdirsep(name);
- if (isdirsep(RSTRING(tmp)->ptr[0])) {
+ if (RSTRING(tmp)->ptr && isdirsep(RSTRING(tmp)->ptr[0])) {
RSTRING(result)->len = tail - name;
}
else if (!*tail) {
@@ -2882,8 +3039,23 @@
# define LOCK_UN 8
# endif
-#if 1
+#ifdef __CYGWIN__
+#include <winerror.h>
static int
+cygwin_flock(int fd, int op)
+{
+ int old_errno = errno;
+ int ret = flock(fd, op);
+ if (GetLastError() == ERROR_NOT_LOCKED) {
+ ret = 0;
+ errno = old_errno;
+ }
+ return ret;
+}
+# define flock(fd, op) cygwin_flock(fd, op)
+#endif
+
+static int
rb_thread_flock(int fd, int op, OpenFile *fptr)
{
if (rb_thread_alone() || (op & LOCK_NB)) {
@@ -2910,8 +3082,10 @@
}
return 0;
}
+#ifdef __CYGWIN__
+# undef flock
+#endif
#define flock(fd, op) rb_thread_flock(fd, op, fptr)
-#endif
/*
* call-seq:
@@ -3050,7 +3224,7 @@
*
* Tests that take two files:
*
- * ?- | boolean | True if file1 is a hard link to file2
+ * ?- | boolean | True if file1 and file2 are identical
* ?= | boolean | True if the modification times of file1
* | | and file2 are equal
* ?< | boolean | True if the modification time of file1
@@ -3162,7 +3336,12 @@
}
}
- if (strchr("-=<>", cmd)) {
+ if (cmd == '-') {
+ CHECK(2);
+ return test_identical(0, argv[1], argv[2]);
+ }
+
+ if (strchr("=<>", cmd)) {
struct stat st1, st2;
CHECK(2);
@@ -3170,11 +3349,6 @@
if (rb_stat(argv[2], &st2) < 0) return Qfalse;
switch (cmd) {
- case '-':
- if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
- return Qtrue;
- return Qfalse;
-
case '=':
if (st1.st_mtime == st2.st_mtime) return Qtrue;
return Qfalse;
@@ -3881,8 +4055,7 @@
#endif
static int
-fpath_check(path)
- char *path;
+fpath_check(const char *path)
{
#ifndef DOSISH
return path_check_0(rb_str_new2(path), Qfalse);
@@ -3928,15 +4101,9 @@
#endif
static int
-file_load_ok(const char *file)
+file_load_ok(const char *path)
{
- FILE *f;
-
- if (!file) return 0;
- f = fopen(file, "r");
- if (f == NULL) return 0;
- fclose(f);
- return 1;
+ return eaccess(path, R_OK) == 0;
}
extern VALUE rb_load_path;
@@ -4148,6 +4315,8 @@
define_filetest_function("setgid?", test_sgid, 1);
define_filetest_function("sticky?", test_sticky, 1);
+ define_filetest_function("identical?", test_identical, 2);
+
rb_define_singleton_method(rb_cFile, "stat", rb_file_s_stat, 1);
rb_define_singleton_method(rb_cFile, "lstat", rb_file_s_lstat, 1);
rb_define_singleton_method(rb_cFile, "ftype", rb_file_s_ftype, 1);
Modified: trunk/gc.c
===================================================================
--- trunk/gc.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/gc.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -31,24 +31,6 @@
#include <sys/resource.h>
#endif
-#ifdef __ia64__
-#include <ucontext.h>
-#if defined(__FreeBSD__)
-/*
- * FreeBSD/ia64 currently does not have a way for a process to get the
- * base address for the RSE backing store, so hardcode it.
- */
-#define __libc_ia64_register_backing_store_base (4ULL<<61)
-#else
-#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF)
-#include <unwind.h>
-#else
-#pragma weak __libc_ia64_register_backing_store_base
-extern unsigned long __libc_ia64_register_backing_store_base;
-#endif
-#endif
-#endif
-
#if defined _WIN32 || defined __CYGWIN__
#include <windows.h>
#endif
@@ -106,57 +88,80 @@
rb_exc_raise(nomem_error);
}
-static int gc_debug_flag = 0;
+int gc_stress = 0;
+/*
+ * call-seq:
+ * GC.stress => true or false
+ *
+ * returns current status of GC stress mode.
+ */
+
static VALUE
-get_gc_debug_flag(VALUE self){
- return gc_debug_flag ? Qtrue : Qfalse;
+gc_stress_get(VALUE self)
+{
+ return gc_stress ? Qtrue : Qfalse;
}
+/*
+ * call-seq:
+ * GC.stress = bool => bool
+ *
+ * updates GC stress mode.
+ *
+ * When GC.stress = true, GC is invoked for all GC opportunity:
+ * all memory and object allocation.
+ *
+ * Since it makes Ruby very slow, it is only for debugging.
+ */
+
static VALUE
-set_gc_debug_flag(VALUE self, VALUE v){
- gc_debug_flag = (v == Qtrue);
- return v;
+gc_stress_set(VALUE self, VALUE bool)
+{
+ rb_secure(2);
+ gc_stress = RTEST(bool);
+ return bool;
}
void *
-ruby_xmalloc(long size)
+ruby_xmalloc(size_t size)
{
- void *mem;
+ void *mem;
- if (size < 0) {
- rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
- }
- if (size == 0) size = 1;
- malloc_increase += size;
+ if (size < 0) {
+ rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
+ }
+ if (size == 0) size = 1;
+ malloc_increase += size;
- if (malloc_increase > malloc_limit || gc_debug_flag) {
- garbage_collect();
- }
- RUBY_CRITICAL(mem = malloc(size));
- if (!mem) {
- if (garbage_collect()) {
- RUBY_CRITICAL(mem = malloc(size));
+ if (gc_stress || malloc_increase > malloc_limit) {
+ garbage_collect();
}
+ RUBY_CRITICAL(mem = malloc(size));
if (!mem) {
- rb_memerror();
+ if (garbage_collect()) {
+ RUBY_CRITICAL(mem = malloc(size));
+ }
+ if (!mem) {
+ rb_memerror();
+ }
}
- }
- return mem;
+
+ return mem;
}
void *
-ruby_xmalloc2(long n, long size)
+ruby_xmalloc2(size_t n, size_t size)
{
long len = size * n;
- if (len < n || (n > 0 && len < size)) {
+ if (n != 0 && size != len / n) {
rb_raise(rb_eArgError, "malloc: possible integer overflow");
}
return ruby_xmalloc(len);
}
void *
-ruby_xcalloc(long n, long size)
+ruby_xcalloc(size_t n, size_t size)
{
void *mem;
@@ -167,7 +172,7 @@
}
void *
-ruby_xrealloc(void *ptr, long size)
+ruby_xrealloc(void *ptr, size_t size)
{
void *mem;
@@ -177,10 +182,11 @@
if (!ptr) return ruby_xmalloc(size);
if (size == 0) size = 1;
malloc_increase += size;
+ if (gc_stress) garbage_collect();
RUBY_CRITICAL(mem = realloc(ptr, size));
if (!mem) {
if (garbage_collect()) {
- RUBY_CRITICAL(mem = realloc(ptr, size));
+ RUBY_CRITICAL(mem = realloc(ptr, size));
}
if (!mem) {
rb_memerror();
@@ -191,10 +197,10 @@
}
void *
-ruby_xrealloc2(void *ptr, long n, long size)
+ruby_xrealloc2(void *ptr, size_t n, size_t size)
{
- long len = size * n;
- if (len < n || (n > 0 && len < size)) {
+ size_t len = size * n;
+ if (n != 0 && size != len / n) {
rb_raise(rb_eArgError, "realloc: possible integer overflow");
}
return ruby_xrealloc(ptr, len);
@@ -203,9 +209,8 @@
void
ruby_xfree(void *x)
{
- if (x){
- RUBY_CRITICAL(free(x));
- }
+ if (x)
+ RUBY_CRITICAL(free(x));
}
static int dont_gc;
@@ -405,20 +410,19 @@
VALUE
rb_newobj(void)
{
- VALUE obj;
+ VALUE obj;
- if (!freelist && !garbage_collect()){
- rb_memerror();
- }
+ if ((gc_stress || !freelist) && !garbage_collect())
+ rb_memerror();
- obj = (VALUE)freelist;
- freelist = freelist->as.free.next;
- MEMZERO((void*)obj, RVALUE, 1);
+ obj = (VALUE)freelist;
+ freelist = freelist->as.free.next;
+ MEMZERO((void*)obj, RVALUE, 1);
#ifdef GC_DEBUG
- RANY(obj)->file = ruby_sourcefile;
- RANY(obj)->line = ruby_sourceline;
+ RANY(obj)->file = ruby_sourcefile;
+ RANY(obj)->line = ruby_sourceline;
#endif
- return obj;
+ return obj;
}
VALUE
@@ -436,7 +440,11 @@
extern st_table *rb_class_tbl;
VALUE *rb_gc_stack_start = 0;
+#ifdef __ia64
+VALUE *rb_gc_register_stack_start = 0;
+#endif
+
#ifdef DJGPP
/* set stack size (http://www.delorie.com/djgpp/v2faq/faq15_9.html) */
unsigned int _stklen = 0x180000; /* 1.5 kB */
@@ -652,7 +660,7 @@
return ST_CONTINUE;
}
-void
+static void
mark_tbl(st_table *tbl, int lev)
{
if (!tbl) return;
@@ -673,7 +681,7 @@
return ST_CONTINUE;
}
-void
+static void
mark_hash(st_table *tbl, int lev)
{
if (!tbl) return;
@@ -967,8 +975,8 @@
case T_STRUCT:
{
- long len = obj->as.rstruct.len;
- VALUE *ptr = obj->as.rstruct.ptr;
+ long len = RSTRUCT_LEN(obj);
+ VALUE *ptr = RSTRUCT_PTR(obj);
while (len--) {
gc_mark(*ptr++, lev);
@@ -1027,6 +1035,8 @@
}
}
+void rb_gc_abort_threads(void);
+
static void
gc_sweep(void)
{
@@ -1036,7 +1046,9 @@
unsigned long live = 0;
mark_source_filename(ruby_sourcefile);
- st_foreach(source_filenames, sweep_source_filename, 0);
+ if (source_filenames) {
+ st_foreach(source_filenames, sweep_source_filename, 0);
+ }
freelist = 0;
final_list = deferred_final_list;
@@ -1066,7 +1078,7 @@
}
else if (RBASIC(p)->flags == FL_MARK) {
/* objects to be finalized */
- /* do notning remain marked */
+ /* do nothing remain marked */
}
else {
RBASIC(p)->flags &= ~FL_MARK;
@@ -1227,13 +1239,15 @@
break;
case T_STRUCT:
- if (RANY(obj)->as.rstruct.ptr) {
- RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr));
+ if (RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK == 0 &&
+ RANY(obj)->as.rstruct.as.heap.ptr) {
+ RUBY_CRITICAL(free(RANY(obj)->as.rstruct.as.heap.ptr));
}
+ break;
default:
rb_bug("gc_sweep(): unknown data type 0x%lx(%p)",
- RANY(obj)->as.basic.flags & T_MASK, (void*)obj);
+ RANY(obj)->as.basic.flags & T_MASK, obj);
}
}
@@ -1432,6 +1446,28 @@
void
Init_stack(VALUE *addr)
{
+#ifdef __ia64
+ if (rb_gc_register_stack_start == 0) {
+# if defined(__FreeBSD__)
+ /*
+ * FreeBSD/ia64 currently does not have a way for a process to get the
+ * base address for the RSE backing store, so hardcode it.
+ */
+ rb_gc_register_stack_start = (4ULL<<61);
+# elif defined(HAVE___LIBC_IA64_REGISTER_BACKING_STORE_BASE)
+# pragma weak __libc_ia64_register_backing_store_base
+ extern unsigned long __libc_ia64_register_backing_store_base;
+ rb_gc_register_stack_start = (VALUE*)__libc_ia64_register_backing_store_base;
+# endif
+ }
+ {
+ VALUE *bsp = (VALUE*)rb_ia64_bsp();
+ if (rb_gc_register_stack_start == 0 ||
+ bsp < rb_gc_register_stack_start) {
+ rb_gc_register_stack_start = bsp;
+ }
+ }
+#endif
#if defined(_WIN32) || defined(__CYGWIN__)
MEMORY_BASIC_INFORMATION m;
memset(&m, 0, sizeof(m));
@@ -1440,8 +1476,10 @@
STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress,
(VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1);
#elif defined(STACK_END_ADDRESS)
- extern void *STACK_END_ADDRESS;
- rb_gc_stack_start = STACK_END_ADDRESS;
+ {
+ extern void *STACK_END_ADDRESS;
+ rb_gc_stack_start = STACK_END_ADDRESS;
+ }
#else
if (!addr) addr = (VALUE *)&addr;
STACK_UPPER(&addr, addr, ++addr);
@@ -1468,7 +1506,38 @@
#endif
}
+void ruby_init_stack(VALUE *addr
+#ifdef __ia64
+ , void *bsp
+#endif
+ )
+{
+ if (!rb_gc_stack_start ||
+ STACK_UPPER(&addr,
+ rb_gc_stack_start > addr,
+ rb_gc_stack_start < addr)) {
+ rb_gc_stack_start = addr;
+ }
+#ifdef __ia64
+ if (!rb_gc_register_stack_start ||
+ (VALUE*)bsp < rb_gc_register_stack_start) {
+ rb_gc_register_stack_start = (VALUE*)bsp;
+ }
+#endif
+#ifdef HAVE_GETRLIMIT
+ {
+ struct rlimit rlim;
+ if (getrlimit(RLIMIT_STACK, &rlim) == 0) {
+ unsigned int space = rlim.rlim_cur/5;
+
+ if (space > 1024*1024) space = 1024*1024;
+ STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE);
+ }
+ }
+#endif
+}
+
/*
* Document-class: ObjectSpace
*
@@ -1903,8 +1972,8 @@
rb_define_singleton_method(rb_mGC, "start", rb_gc_start, 0);
rb_define_singleton_method(rb_mGC, "enable", rb_gc_enable, 0);
rb_define_singleton_method(rb_mGC, "disable", rb_gc_disable, 0);
- rb_define_singleton_method(rb_mGC, "debug_flag", get_gc_debug_flag, 0);
- rb_define_singleton_method(rb_mGC, "debug_flag=", set_gc_debug_flag, 1);
+ rb_define_singleton_method(rb_mGC, "stress", gc_stress_get, 0);
+ rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1);
rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0);
rb_mObSpace = rb_define_module("ObjectSpace");
@@ -1927,6 +1996,6 @@
source_filenames = st_init_strtable();
+ rb_global_variable(&nomem_error);
nomem_error = rb_exc_new2(rb_eNoMemError, "failed to allocate memory");
- rb_global_variable(&nomem_error);
}
Modified: trunk/io.c
===================================================================
--- trunk/io.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/io.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -2,8 +2,8 @@
io.c -
- $Author: ocean $
- $Date: 2005/11/11 11:08:17 $
+ $Author: matz $
+ $Date: 2006/02/03 09:15:40 $
created at: Fri Oct 15 18:08:59 JST 1993
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -3798,7 +3798,12 @@
void
rb_write_error2(const char *mesg, long len)
{
- rb_io_write(rb_stderr, rb_str_new(mesg, len));
+ if (rb_stderr == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0) {
+ fwrite(mesg, sizeof(char), len, stderr);
+ }
+ else {
+ rb_io_write(rb_stderr, rb_str_new(mesg, len));
+ }
}
void
@@ -4373,7 +4378,8 @@
static VALUE
rb_f_backquote(VALUE obj, VALUE str)
{
- VALUE port, result;
+ volatile VALUE port;
+ VALUE result;
OpenFile *fptr;
SafeStringValue(str);
@@ -5482,9 +5488,9 @@
rb_output_fs = Qnil;
rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter);
+ rb_global_variable(&rb_default_rs);
rb_rs = rb_default_rs = rb_str_new2("\n");
rb_output_rs = Qnil;
- rb_global_variable(&rb_default_rs);
OBJ_FREEZE(rb_default_rs); /* avoid modifying RS_default */
rb_define_hooked_variable("$/", &rb_rs, 0, rb_str_setter);
rb_define_hooked_variable("$-0", &rb_rs, 0, rb_str_setter);
@@ -5557,12 +5563,12 @@
rb_define_method(rb_cIO, "pid", rb_io_pid, 0);
rb_define_method(rb_cIO, "inspect", rb_io_inspect, 0);
+ rb_define_variable("$stdin", &rb_stdin);
rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO, "<STDIN>");
- rb_define_variable("$stdin", &rb_stdin);
+ rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter);
rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO, "<STDOUT>");
- rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter);
+ rb_define_hooked_variable("$stderr", &rb_stderr, 0, stdout_setter);
rb_stderr = prep_stdio(stderr, FMODE_WRITABLE|FMODE_SYNC, rb_cIO, "<STDERR>");
- rb_define_hooked_variable("$stderr", &rb_stderr, 0, stdout_setter);
rb_define_hooked_variable("$>", &rb_stdout, 0, stdout_setter);
orig_stdout = rb_stdout;
rb_deferr = orig_stderr = rb_stderr;
@@ -5576,10 +5582,9 @@
rb_define_global_const("STDOUT", rb_stdout);
rb_define_global_const("STDERR", rb_stderr);
+ rb_define_readonly_variable("$<", &argf);
argf = rb_obj_alloc(rb_cObject);
rb_extend_object(argf, rb_mEnumerable);
-
- rb_define_readonly_variable("$<", &argf);
rb_define_global_const("ARGF", argf);
rb_define_singleton_method(argf, "to_s", argf_to_s, 0);
@@ -5619,8 +5624,8 @@
rb_define_singleton_method(argf, "lineno=", argf_set_lineno, 1);
rb_global_variable(¤t_file);
+ rb_define_readonly_variable("$FILENAME", &filename);
filename = rb_str_new2("-");
- rb_define_readonly_variable("$FILENAME", &filename);
rb_define_virtual_variable("$-i", opt_i_get, opt_i_set);
Modified: trunk/marshal.c
===================================================================
--- trunk/marshal.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/marshal.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -2,8 +2,8 @@
marshal.c -
- $Author: ocean $
- $Date: 2005/10/21 06:46:39 $
+ $Author: akr $
+ $Date: 2006/02/05 14:40:01 $
created at: Thu Apr 27 16:30:01 JST 1995
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -585,7 +585,7 @@
case T_STRUCT:
w_class(TYPE_STRUCT, obj, arg, Qtrue);
{
- long len = RSTRUCT(obj)->len;
+ long len = RSTRUCT_LEN(obj);
VALUE mem;
long i;
@@ -593,7 +593,7 @@
mem = rb_struct_members(obj);
for (i=0; i<len; i++) {
w_symbol(SYM2ID(RARRAY(mem)->ptr[i]), arg);
- w_object(RSTRUCT(obj)->ptr[i], arg, limit);
+ w_object(RSTRUCT_PTR(obj)[i], arg, limit);
}
}
break;
@@ -765,7 +765,7 @@
static void
long_toobig(int size)
{
- rb_raise(rb_eTypeError, "long too big for this architecture (size %ld, given %d)",
+ rb_raise(rb_eTypeError, "long too big for this architecture (size %d, given %d)",
sizeof(long), size);
}
@@ -1038,7 +1038,7 @@
{
long len;
BDIGIT *digits;
- VALUE data;
+ volatile VALUE data;
NEWOBJ(big, struct RBignum);
OBJSETUP(big, rb_cBignum, T_BIGNUM);
Modified: trunk/process.c
===================================================================
--- trunk/process.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/process.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -2,8 +2,8 @@
process.c -
- $Author: matz $
- $Date: 2005/10/05 16:15:15 $
+ $Author: aamine $
+ $Date: 2005/12/27 05:10:38 $
created at: Tue Aug 10 14:30:50 JST 1993
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -1396,11 +1396,14 @@
* the parent, returning the process ID of the child, and once in
* the child, returning _nil_. The child process can exit using
* <code>Kernel.exit!</code> to avoid running any
- * <code>at_exit</code> functions. The parent process should
- * use <code>Process.wait</code> to collect the termination statuses
+ * <code>at_exit</code> functions. The parent process should
+ * use <code>Process.wait</code> to collect the termination statuses
* of its children or use <code>Process.detach</code> to register
* disinterest in their status; otherwise, the operating system
* may accumulate zombie processes.
+ *
+ * The thread calling fork is the only thread in the created child process.
+ * fork doesn't copy other threads.
*/
static VALUE
@@ -2629,7 +2632,7 @@
ngroups = RARRAY(ary)->len;
if (ngroups > maxgroups)
- rb_raise(rb_eArgError, "too many groups, %ld max", (long)maxgroups);
+ rb_raise(rb_eArgError, "too many groups, %lu max", (unsigned long)maxgroups);
groups = ALLOCA_N(rb_gid_t, ngroups);
@@ -3580,6 +3583,7 @@
#endif
#endif
+ rb_define_singleton_method(rb_mProcess, "exec", rb_f_exec, -1);
rb_define_singleton_method(rb_mProcess, "fork", rb_f_fork, 0);
rb_define_singleton_method(rb_mProcess, "spawn", rb_f_spawn, -1);
rb_define_singleton_method(rb_mProcess, "exit!", rb_f_exit_bang, -1);
Modified: trunk/range.c
===================================================================
--- trunk/range.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/range.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -3,7 +3,7 @@
range.c -
$Author: matz $
- $Date: 2005/10/05 16:15:15 $
+ $Date: 2005/12/12 01:01:29 $
created at: Thu Aug 19 17:46:47 JST 1993
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -366,47 +366,41 @@
* 10 11 12 13 14 15
*/
-VALUE yarv_invoke_Range_each_special_block(VALUE, VALUE, VALUE, int);
-
static VALUE
range_each(VALUE range)
{
- VALUE beg, end, val;
-
- RETURN_ENUMERATOR(range, 0, 0);
+ VALUE beg, end;
- beg = rb_ivar_get(range, id_beg);
- end = rb_ivar_get(range, id_end);
+ RETURN_ENUMERATOR(range, 0, 0);
- val = yarv_invoke_Range_each_special_block(range, beg, end, EXCL(range));
- if(val != Qundef){
- return val;
- }
- if (!rb_respond_to(beg, id_succ)) {
- rb_raise(rb_eTypeError, "can't iterate from %s",
- rb_obj_classname(beg));
- }
- if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
- long lim = FIX2LONG(end);
- long i;
+ beg = rb_ivar_get(range, id_beg);
+ end = rb_ivar_get(range, id_end);
- if (!EXCL(range)) lim += 1;
- for (i=FIX2LONG(beg); i<lim; i++) {
- rb_yield(LONG2NUM(i));
+ if (!rb_respond_to(beg, id_succ)) {
+ rb_raise(rb_eTypeError, "can't iterate from %s",
+ rb_obj_classname(beg));
}
- }
- else if (TYPE(beg) == T_STRING) {
- VALUE args[5];
- long iter[2];
+ if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
+ long lim = FIX2LONG(end);
+ long i;
- args[0] = beg; args[1] = end; args[2] = range;
- iter[0] = 1; iter[1] = 1;
- rb_iterate(str_step, (VALUE)args, step_i, (VALUE)iter);
- }
- else {
- range_each_func(range, each_i, beg, end, NULL);
- }
- return range;
+ if (!EXCL(range)) lim += 1;
+ for (i=FIX2LONG(beg); i<lim; i++) {
+ rb_yield(LONG2NUM(i));
+ }
+ }
+ else if (TYPE(beg) == T_STRING) {
+ VALUE args[5];
+ long iter[2];
+
+ args[0] = beg; args[1] = end; args[2] = range;
+ iter[0] = 1; iter[1] = 1;
+ rb_iterate(str_step, (VALUE)args, step_i, (VALUE)iter);
+ }
+ else {
+ range_each_func(range, each_i, beg, end, NULL);
+ }
+ return range;
}
/*
@@ -442,6 +436,70 @@
return rb_ivar_get(range, id_end);
}
+/*
+ * call-seq:
+ * rng.min => obj
+ * rng.min {| a,b | block } => obj
+ *
+ * Returns the minimum value in <i>rng</i>. The second uses
+ * the block to compare values. Returns nil if the first
+ * value in range is larger than the last value.
+ *
+ */
+
+
+static VALUE
+range_min(VALUE range)
+{
+ if (rb_block_given_p()) {
+ return rb_call_super(0, 0);
+ }
+ else {
+ VALUE b = rb_ivar_get(range, id_beg);
+ VALUE e = rb_ivar_get(range, id_end);
+ int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);
+
+ if (c > 0) return Qnil;
+ return b;
+ }
+}
+
+/*
+ * call-seq:
+ * rng.max => obj
+ * rng.max {| a,b | block } => obj
+ *
+ * Returns the maximum value in <i>rng</i>. The second uses
+ * the block to compare values. Returns nil if the first
+ * value in range is larger than the last value.
+ *
+ */
+
+
+static VALUE
+range_max(VALUE range)
+{
+ VALUE e = rb_ivar_get(range, id_end);
+ int ip = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cInteger);
+
+ if (rb_block_given_p() || (EXCL(range) && !ip)) {
+ return rb_call_super(0, 0);
+ }
+ else {
+ VALUE b = rb_ivar_get(range, id_beg);
+ int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);
+
+ if (c > 0) return Qnil;
+ if (EXCL(range)) {
+ if (FIXNUM_P(e)) {
+ return INT2NUM(FIX2INT(e)-1);
+ }
+ return rb_funcall(e, '-', 1, INT2FIX(1));
+ }
+ return e;
+ }
+}
+
VALUE
rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
{
@@ -560,6 +618,45 @@
static VALUE
range_include(VALUE range, VALUE val)
{
+ VALUE beg = rb_ivar_get(range, id_beg);
+ VALUE end = rb_ivar_get(range, id_end);
+ int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
+ rb_obj_is_kind_of(beg, rb_cNumeric) ||
+ rb_obj_is_kind_of(end, rb_cNumeric);
+
+ if (nv ||
+ !NIL_P(rb_check_to_integer(beg, "to_int")) ||
+ !NIL_P(rb_check_to_integer(end, "to_int"))) {
+ if (r_le(beg, val)) {
+ if (EXCL(range)) {
+ if (r_lt(val, end)) return Qtrue;
+ }
+ else {
+ if (r_le(val, end)) return Qtrue;
+ }
+ }
+ return Qfalse;
+ }
+ return rb_call_super(1, &val);
+}
+
+
+/*
+ * call-seq:
+ * rng.cover?(val) => true or false
+ *
+ * Returns <code>true</code> if <i>obj</i> is between beg and end,
+ * i.e <code>beg <= obj <= end</code> (or <i>end</i> exclusive when
+ * <code>exclude_end?</code> is true).
+ *
+ * ("a".."z").cover?("c") #=> true
+ * ("a".."z").cover?("5") #=> false
+ */
+
+static VALUE
+range_cover(range, val)
+ VALUE range, val;
+{
VALUE beg, end;
beg = rb_ivar_get(range, id_beg);
@@ -644,6 +741,8 @@
rb_define_method(rb_cRange, "last", range_last, 0);
rb_define_method(rb_cRange, "begin", range_first, 0);
rb_define_method(rb_cRange, "end", range_last, 0);
+ rb_define_method(rb_cRange, "min", range_min, 0);
+ rb_define_method(rb_cRange, "max", range_max, 0);
rb_define_method(rb_cRange, "to_s", range_to_s, 0);
rb_define_method(rb_cRange, "inspect", range_inspect, 0);
@@ -651,6 +750,7 @@
rb_define_method(rb_cRange, "member?", range_include, 1);
rb_define_method(rb_cRange, "include?", range_include, 1);
+ rb_define_method(rb_cRange, "cover?", range_cover, 1);
id_cmp = rb_intern("<=>");
id_succ = rb_intern("succ");
Modified: trunk/ruby.h
===================================================================
--- trunk/ruby.h 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/ruby.h 2006-02-09 17:49:56 UTC (rev 377)
@@ -2,7 +2,7 @@
ruby.h -
- $Author: ocean $
+ $Author: akr $
created at: Thu Jun 10 14:26:32 JST 1993
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -41,8 +41,6 @@
#define PRINTF_ARGS(decl, string_index, first_to_check) decl
#endif
-#include "defines.h"
-
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
@@ -60,6 +58,8 @@
#include <stddef.h>
#include <stdio.h>
+#include "defines.h"
+
/* need to include <ctype.h> to use these macros */
#ifndef ISPRINT
#define ISASCII(c) isascii((int)(unsigned char)(c))
@@ -425,11 +425,28 @@
sval = (type*)DATA_PTR(obj);\
} while (0)
+#define RSTRUCT_EMBED_LEN_MAX 3
struct RStruct {
struct RBasic basic;
- long len;
- VALUE *ptr;
+ union {
+ struct {
+ long len;
+ VALUE *ptr;
+ } heap;
+ VALUE ary[RSTRUCT_EMBED_LEN_MAX];
+ } as;
};
+#define RSTRUCT_EMBED_LEN_MASK (FL_USER2|FL_USER1)
+#define RSTRUCT_EMBED_LEN_SHIFT FL_USHIFT+1
+#define RSTRUCT_LEN(st) \
+ ((RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ? \
+ (RBASIC(st)->flags >> RSTRUCT_EMBED_LEN_SHIFT) & \
+ (RSTRUCT_EMBED_LEN_MASK >> RSTRUCT_EMBED_LEN_SHIFT) : \
+ RSTRUCT(st)->as.heap.len)
+#define RSTRUCT_PTR(st) \
+ ((RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ? \
+ RSTRUCT(st)->as.ary : \
+ RSTRUCT(st)->as.heap.ptr)
struct RBignum {
struct RBasic basic;
@@ -592,6 +609,17 @@
VALUE rb_require(const char*);
+#ifdef __ia64
+void ruby_init_stack(VALUE*, void*);
+#define RUBY_INIT_STACK \
+ VALUE variable_in_this_stack_frame; \
+ ruby_init_stack(&variable_in_this_stack_frame, rb_ia64_bsp());
+#else
+void ruby_init_stack(VALUE*);
+#define RUBY_INIT_STACK \
+ VALUE variable_in_this_stack_frame; \
+ ruby_init_stack(&variable_in_this_stack_frame);
+#endif
void ruby_init(void);
void ruby_options(int, char**);
NORETURN(void ruby_run(void));
Modified: trunk/string.c
===================================================================
--- trunk/string.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/string.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -2,8 +2,8 @@
string.c -
- $Author: matz $
- $Date: 2005/10/27 08:18:38 $
+ $Author: akr $
+ $Date: 2005/12/29 17:03:27 $
created at: Mon Aug 9 17:12:58 JST 1993
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -2155,99 +2155,8 @@
return str;
}
-static VALUE
-uscore_get(void)
-{
- VALUE line;
-
- line = rb_lastline_get();
- if (TYPE(line) != T_STRING) {
- rb_raise(rb_eTypeError, "$_ value need to be String (%s given)",
- NIL_P(line) ? "nil" : rb_obj_classname(line));
- }
- return line;
-}
-
/*
* call-seq:
- * sub!(pattern, replacement) => $_ or nil
- * sub!(pattern) {|...| block } => $_ or nil
- *
- * Equivalent to <code>$_.sub!(<i>args</i>)</code>.
- */
-
-static VALUE
-rb_f_sub_bang(int argc, VALUE *argv)
-{
- return rb_str_sub_bang(argc, argv, uscore_get());
-}
-
-/*
- * call-seq:
- * sub(pattern, replacement) => $_
- * sub(pattern) { block } => $_
- *
- * Equivalent to <code>$_.sub(<i>args</i>)</code>, except that
- * <code>$_</code> will be updated if substitution occurs.
- */
-
-static VALUE
-rb_f_sub(int argc, VALUE *argv)
-{
- VALUE str = rb_str_dup(uscore_get());
-
- if (NIL_P(rb_str_sub_bang(argc, argv, str)))
- return str;
- rb_lastline_set(str);
- return str;
-}
-
-/*
- * call-seq:
- * gsub!(pattern, replacement) => string or nil
- * gsub!(pattern) {|...| block } => string or nil
- *
- * Equivalent to <code>Kernel::gsub</code>, except <code>nil</code> is
- * returned if <code>$_</code> is not modified.
- *
- * $_ = "quick brown fox"
- * gsub! /cat/, '*' #=> nil
- * $_ #=> "quick brown fox"
- */
-
-static VALUE
-rb_f_gsub_bang(int argc, VALUE *argv)
-{
- return rb_str_gsub_bang(argc, argv, uscore_get());
-}
-
-/*
- * call-seq:
- * gsub(pattern, replacement) => string
- * gsub(pattern) {|...| block } => string
- *
- * Equivalent to <code>$_.gsub...</code>, except that <code>$_</code>
- * receives the modified result.
- *
- * $_ = "quick brown fox"
- * gsub /[aeiou]/, '*' #=> "q**ck br*wn f*x"
- * $_ #=> "q**ck br*wn f*x"
- */
-
-static VALUE
-rb_f_gsub(int argc, VALUE *argv)
-{
- VALUE str = rb_str_dup(uscore_get());
-
- if (NIL_P(rb_str_gsub_bang(argc, argv, str)))
- return str;
- rb_lastline_set(str);
- return str;
-}
-
-
-/*
- * call-seq:
* str.reverse! => str
*
* Reverses <i>str</i> in place.
@@ -3439,20 +3348,6 @@
/*
* call-seq:
- * split([pattern [, limit]]) => array
- *
- * Equivalent to <code>$_.split(<i>pattern</i>, <i>limit</i>)</code>.
- * See <code>String#split</code>.
- */
-
-static VALUE
-rb_f_split(int argc, VALUE *argv)
-{
- return rb_str_split_m(argc, argv, uscore_get());
-}
-
-/*
- * call-seq:
* str.each(separator=$/) {|substr| block } => str
* str.each_line(separator=$/) {|substr| block } => str
*
@@ -3622,61 +3517,6 @@
/*
* call-seq:
- * chop! => $_ or nil
- *
- * Equivalent to <code>$_.chop!</code>.
- *
- * a = "now\r\n"
- * $_ = a
- * chop! #=> "now"
- * chop! #=> "no"
- * chop! #=> "n"
- * chop! #=> ""
- * chop! #=> nil
- * $_ #=> ""
- * a #=> ""
- */
-
-static VALUE
-rb_f_chop_bang(VALUE str)
-{
- return rb_str_chop_bang(uscore_get());
-}
-
-/*
- * call-seq:
- * chop => string
- *
- * Equivalent to <code>($_.dup).chop!</code>, except <code>nil</code>
- * is never returned. See <code>String#chop!</code>.
- *
- * a = "now\r\n"
- * $_ = a
- * chop #=> "now"
- * $_ #=> "now"
- * chop #=> "no"
- * chop #=> "n"
- * chop #=> ""
- * chop #=> ""
- * a #=> "now\r\n"
- */
-
-static VALUE
-rb_f_chop(void)
-{
- VALUE str = uscore_get();
-
- if (RSTRING(str)->len > 0) {
- str = rb_str_dup(str);
- rb_str_chop_bang(str);
- rb_lastline_set(str);
- }
- return str;
-}
-
-
-/*
- * call-seq:
* str.chomp!(separator=$/) => str or nil
*
* Modifies <i>str</i> in place as described for <code>String#chomp</code>,
@@ -3782,57 +3622,6 @@
/*
* call-seq:
- * chomp! => $_ or nil
- * chomp!(string) => $_ or nil
- *
- * Equivalent to <code>$_.chomp!(<em>string</em>)</code>. See
- * <code>String#chomp!</code>
- *
- * $_ = "now\n"
- * chomp! #=> "now"
- * $_ #=> "now"
- * chomp! "x" #=> nil
- * $_ #=> "now"
- */
-
-static VALUE
-rb_f_chomp_bang(int argc, VALUE *argv)
-{
- return rb_str_chomp_bang(argc, argv, uscore_get());
-}
-
-/*
- * call-seq:
- * chomp => $_
- * chomp(string) => $_
- *
- * Equivalent to <code>$_ = $_.chomp(<em>string</em>)</code>. See
- * <code>String#chomp</code>.
- *
- * $_ = "now\n"
- * chomp #=> "now"
- * $_ #=> "now"
- * chomp "ow" #=> "n"
- * $_ #=> "n"
- * chomp "xxx" #=> "n"
- * $_ #=> "n"
- */
-
-static VALUE
-rb_f_chomp(int argc, VALUE *argv)
-{
- VALUE str = uscore_get();
- VALUE dup = rb_str_dup(str);
-
- if (NIL_P(rb_str_chomp_bang(argc, argv, dup)))
- return str;
- rb_lastline_set(dup);
- return dup;
-}
-
-
-/*
- * call-seq:
* str.lstrip! => self or nil
*
* Removes leading whitespace from <i>str</i>, returning <code>nil</code> if no
@@ -4075,22 +3864,7 @@
return str;
}
-/*
- * call-seq:
- * scan(pattern) => array
- * scan(pattern) {|///| block } => $_
- *
- * Equivalent to calling <code>$_.scan</code>. See
- * <code>String#scan</code>.
- */
-static VALUE
-rb_f_scan(VALUE self, VALUE pat)
-{
- return rb_str_scan(uscore_get(), pat);
-}
-
-
/*
* call-seq:
* str.hex => integer
@@ -4510,21 +4284,6 @@
rb_define_method(rb_cString, "sum", rb_str_sum, -1);
- rb_define_global_function("sub", rb_f_sub, -1);
- rb_define_global_function("gsub", rb_f_gsub, -1);
-
- rb_define_global_function("sub!", rb_f_sub_bang, -1);
- rb_define_global_function("gsub!", rb_f_gsub_bang, -1);
-
- rb_define_global_function("chop", rb_f_chop, 0);
- rb_define_global_function("chop!", rb_f_chop_bang, 0);
-
- rb_define_global_function("chomp", rb_f_chomp, -1);
- rb_define_global_function("chomp!", rb_f_chomp_bang, -1);
-
- rb_define_global_function("split", rb_f_split, -1);
- rb_define_global_function("scan", rb_f_scan, 1);
-
rb_define_method(rb_cString, "slice", rb_str_aref_m, -1);
rb_define_method(rb_cString, "slice!", rb_str_slice_bang, -1);
Modified: trunk/struct.c
===================================================================
--- trunk/struct.c 2006-02-09 17:19:49 UTC (rev 376)
+++ trunk/struct.c 2006-02-09 17:49:56 UTC (rev 377)
@@ -2,8 +2,8 @@
struct.c -
- $Author: ocean $
- $Date: 2005/10/21 06:46:39 $
+ $Author: akr $
+ $Date: 2006/02/05 14:40:01 $
created at: Tue Mar 22 18:44:30 JST 1995
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -47,9 +47,9 @@
{
VALUE members = rb_struct_s_members(rb_obj_class(s));
- if (RSTRUCT(s)->len != RARRAY(members)->len) {
+ if (RSTRUCT_LEN(s) != RARRAY(members)->len) {
rb_raise(rb_eTypeError, "struct size differs (%ld required %ld given)",
- RARRAY(members)->len, RSTRUCT(s)->len);
+ RARRAY(members)->len, RSTRUCT_LEN(s));
}
return members;
}
@@ -99,7 +99,7 @@
slot = ID2SYM(id);
for (i=0; i<RARRAY(members)->len; i++) {
if (RARRAY(members)->ptr[i] == slot) {
- return RSTRUCT(obj)->ptr[i];
+ return RSTRUCT_PTR(obj)[i];
}
}
rb_name_error(id, "%s is not struct member", rb_id2name(id));
@@ -112,16 +112,16 @@
return rb_struct_getmember(obj, rb_frame_this_func());
}
-static VALUE rb_struct_ref0(VALUE obj) {return RSTRUCT(obj)->ptr[0];}
-static VALUE rb_struct_ref1(VALUE obj) {return RSTRUCT(obj)->ptr[1];}
-static VALUE rb_struct_ref2(VALUE obj) {return RSTRUCT(obj)->ptr[2];}
-static VALUE rb_struct_ref3(VALUE obj) {return RSTRUCT(obj)->ptr[3];}
-static VALUE rb_struct_ref4(VALUE obj) {return RSTRUCT(obj)->ptr[4];}
-static VALUE rb_struct_ref5(VALUE obj) {return RSTRUCT(obj)->ptr[5];}
-static VALUE rb_struct_ref6(VALUE obj) {return RSTRUCT(obj)->ptr[6];}
-static VALUE rb_struct_ref7(VALUE obj) {return RSTRUCT(obj)->ptr[7];}
-static VALUE rb_struct_ref8(VALUE obj) {return RSTRUCT(obj)->ptr[8];}
-static VALUE rb_struct_ref9(VALUE obj) {return RSTRUCT(obj)->ptr[9];}
+static VALUE rb_struct_ref0(VALUE obj) {return RSTRUCT_PTR(obj)[0];}
+static VALUE rb_struct_ref1(VALUE obj) {return RSTRUCT_PTR(obj)[1];}
+static VALUE rb_struct_ref2(VALUE obj) {return RSTRUCT_PTR(obj)[2];}
+static VALUE rb_struct_ref3(VALUE obj) {return RSTRUCT_PTR(obj)[3];}
+static VALUE rb_struct_ref4(VALUE obj) {return RSTRUCT_PTR(obj)[4];}
+static VALUE rb_struct_ref5(VALUE obj) {return RSTRUCT_PTR(obj)[5];}
+static VALUE rb_struct_ref6(VALUE obj) {return RSTRUCT_PTR(obj)[6];}
+static VALUE rb_struct_ref7(VALUE obj) {return RSTRUCT_PTR(obj)[7];}
+static VALUE rb_struct_ref8(VALUE obj) {return RSTRUCT_PTR(obj)[8];}
+static VALUE rb_struct_ref9(VALUE obj) {return RSTRUCT_PTR(obj)[9];}
#define N_REF_FUNC (sizeof(ref_func) / sizeof(ref_func[0]))
@@ -157,7 +157,7 @@
for (i=0; i<RARRAY(members)->len; i++) {
slot = RARRAY(members)->ptr[i];
if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) {
- return RSTRUCT(obj)->ptr[i] = val;
+ return RSTRUCT_PTR(obj)[i] = val;
}
}
rb_name_error(rb_frame_this_func(), "`%s' is not a struct member",
@@ -315,9 +315,9 @@
if (n < RARRAY(values)->len) {
rb_raise(rb_eArgError, "struct size differs");
}
- MEMCPY(RSTRUCT(self)->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len);
+ MEMCPY(RSTRUCT_PTR(self), RARRAY(values)->ptr, VALUE, RARRAY(values)->len);
if (n > RARRAY(values)->len) {
- rb_mem_clear(RSTRUCT(self)->ptr+RARRAY(values)->len,
+ rb_mem_clear(RSTRUCT_PTR(self)+RARRAY(values)->len,
n-RARRAY(values)->len);
}
return Qnil;
@@ -334,9 +334,16 @@
size = rb_struct_iv_get(klass, "__size__");
n = FIX2LONG(size);
- st->ptr = ALLOC_N(VALUE, n);
- rb_mem_clear(st->ptr, n);
- st->len = n;
+ if (0 < n && n <= RSTRUCT_EMBED_LEN_MAX) {
+ RBASIC(st)->flags &= ~RSTRUCT_EMBED_LEN_MASK;
+ RBASIC(st)->flags |= n << RSTRUCT_EMBED_LEN_SHIFT;
+ rb_mem_clear(st->as.ary, n);
+ }
+ else {
+ st->as.heap.ptr = ALLOC_N(VALUE, n);
+ rb_mem_clear(st->as.heap.ptr, n);
+ st->as.heap.len = n;
+ }
return (VALUE)st;
}
@@ -390,8 +397,8 @@
long i;
RETURN_ENUMERATOR(s, 0, 0);
- for (i=0; i<RSTRUCT(s)->len; i++) {
- rb_yield(RSTRUCT(s)->ptr[i]);
+ for (i=0; i<RSTRUCT_LEN(s); i++) {
+ rb_yield(RSTRUCT_PTR(s)[i]);
}
return s;
}
@@ -422,8 +429,8 @@
RETURN_ENUMERATOR(s, 0, 0);
members = rb_struct_members(s);
- for (i=0; i<RSTRUCT(s)->len; i++) {
- rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT(s)->ptr[i]);
+ for (i=0; i<RSTRUCT_LEN(s); i++) {
+ rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT_PTR(s)[i]);
}
return s;
}
@@ -441,7 +448,7 @@
members = rb_struct_members(s);
str = rb_sprintf("#<struct %s ", cname);
- for (i=0; i<RSTRUCT(s)->len; i++) {
+ for (i=0; i<RSTRUCT_LEN(s); i++) {
VALUE slot;
ID id;
char *p;
@@ -459,7 +466,7 @@
rb_str_append(str, rb_inspect(slot));
}
rb_str_cat2(str, "=");
- rb_str_append(str, rb_inspect(RSTRUCT(s)->ptr[i]));
+ rb_str_append(str, rb_inspect(RSTRUCT_PTR(s)[i]));
}
rb_str_cat2(str, ">");
OBJ_INFECT(str, s);
@@ -496,7 +503,7 @@
static VALUE
rb_struct_to_a(VALUE s)
{
- return rb_ary_new4(RSTRUCT(s)->len, RSTRUCT(s)->ptr);
+ return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_PTR(s));
}
/* :nodoc: */
@@ -508,9 +515,15 @@
if (!rb_obj_is_instance_of(s, rb_obj_class(copy))) {
rb_raise(rb_eTypeError, "wrong argument class");
}
- RSTRUCT(copy)->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len);
- RSTRUCT(copy)->len = RSTRUCT(s)->len;
- MEMCPY(RSTRUCT(copy)->ptr, RSTRUCT(s)->ptr, VALUE, RSTRUCT(copy)->len);
+ if (0 < RSTRUCT_LEN(s) && RSTRUCT_LEN(s) <= RSTRUCT_EMBED_LEN_MAX) {
+ RBASIC(copy)->flags &= ~RSTRUCT_EMBED_LEN_MASK;
+ RBASIC(copy)->flags |= RSTRUCT_LEN(s) << RSTRUCT_EMBED_LEN_SHIFT;
+ }
+ else {
+ RSTRUCT(copy)->as.heap.ptr = ALLOC_N(VALUE, RSTRUCT_LEN(s));
+ RSTRUCT(copy)->as.heap.len = RSTRUCT_LEN(s);
+ }
+ MEMCPY(RSTRUCT_PTR(copy), RSTRUCT_PTR(s), VALUE, RSTRUCT_LEN(copy));
return copy;
}
@@ -525,7 +538,7 @@
len = RARRAY(members)->len;
for (i=0; i<len; i++) {
if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
- return RSTRUCT(s)->ptr[i];
+ return RSTRUCT_PTR(s)[i];
}
}
rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
@@ -561,14 +574,14 @@
}
i = NUM2LONG(idx);
- if (i < 0) i = RSTRUCT(s)->len + i;
+ if (i < 0) i = RSTRUCT_LEN(s) + i;
if (i < 0)
rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
- i, RSTRUCT(s)->len);
- if (RSTRUCT(s)->len <= i)
+ i, RSTRUCT_LEN(s));
+ if (RSTRUCT_LEN(s) <= i)
rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
- i, RSTRUCT(s)->len);
- return RSTRUCT(s)->ptr[i];
+ i, RSTRUCT_LEN(s));
+ return RSTRUCT_PTR(s)[i];
}
static VALUE
@@ -580,13 +593,13 @@
members = rb_struct_members(s);
rb_struct_modify(s);
len = RARRAY(members)->len;
- if (RSTRUCT(s)->len != RARRAY(members)->len) {
+ if (RSTRUCT_LEN(s) != RARRAY(members)->len) {
rb_raise(rb_eTypeError, "struct size differs (%ld required %ld given)",
- RARRAY(members)->len, RSTRUCT(s)->len);
+ RARRAY(members)->len, RSTRUCT_LEN(s));
}
for (i=0; i<len; i++) {
if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
- RSTRUCT(s)->ptr[i] = val;
+ RSTRUCT_PTR(s)[i] = val;
return val;
}
}
@@ -624,17 +637,17 @@
}
i = NUM2LONG(idx);
- if (i < 0) i = RSTRUCT(s)->len + i;
+ if (i < 0) i = RSTRUCT_LEN(s) + i;
if (i < 0) {
rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
- i, RSTRUCT(s)->len);
+ i, RSTRUCT_LEN(s));
}
- if (RSTRUCT(s)->len <= i) {
+ if (RSTRUCT_LEN(s) <= i) {
rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
- i, RSTRUCT(s)->len);
+ i, RSTRUCT_LEN(s));
}
rb_struct_modify(s);
- return RSTRUCT(s)->ptr[i] = val;
+ return RSTRUCT_PTR(s)[i] = val;
}
static VALUE
@@ -662,26 +675,20 @@
static VALUE
rb_struct_values_at(int argc, VALUE *argv, VALUE s)
{
- return rb_get_values_at(s, RSTRUCT(s)->len, argc, argv, struct_entry);
+ return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry);
}
/*
* call-seq:
- * struct.select(fixnum, ... ) => array
* struct.select {|i| block } => array
*
- * The first form returns an array containing the elements in
- * <i>struct</i> corresponding to the given indices. The second
- * form invokes the block passing in successive elements from
+ * Invokes the block passing in successive elements from
* <i>struct</i>, returning an array containing those elements
* for which the block returns a true value (equivalent to
* <code>Enumerable#select</code>).
*
* Lots = Struct.new(:a, :b, :c, :d, :e, :f)
* l = Lots.new(11, 22, 33, 44, 55, 66)
- * l.select(1, 3, 5) #=> [22, 44, 66]
- * l.select(0, 2, 4) #=> [11, 33, 55]
- * l.select(-1, -3, -5) #=> [66, 44, 22]
* l.select {|v| (v % 2).zero? } #=> [22, 44, 66]
*/
@@ -695,9 +702,9 @@
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
}
result = rb_ary_new();
- for (i = 0; i < RSTRUCT(s)->len; i++) {
- if (RTEST(rb_yield(RSTRUCT(s)->ptr[i]))) {
- rb_ary_push(result, RSTRUCT(s)->ptr[i]);
+ for (i = 0; i < RSTRUCT_LEN(s); i++) {
+ if (RTEST(rb_yield(RSTRUCT_PTR(s)[i]))) {
+ rb_ary_push(result, RSTRUCT_PTR(s)[i]);
}
}
@@ -729,12 +736,12 @@
if (s == s2) return Qtrue;
if (TYPE(s2) != T_STRUCT) return Qfalse;
if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
- if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {
+ if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
rb_bug("inconsistent struct"); /* should never happen */
}
- for (i=0; i<RSTRUCT(s)->len; i++) {
- if (!rb_equal(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return Qfalse;
+ for (i=0; i<RSTRUCT_LEN(s); i++) {
+ if (!rb_equal(RSTRUCT_PTR(s)[i], RSTRUCT_PTR(s2)[i])) return Qfalse;
}
return Qtrue;
}
@@ -753,9 +760,9 @@
VALUE n;
h = rb_hash(rb_obj_class(s));
- for (i = 0; i < RSTRUCT(s)->len; i++) {
+ for (i = 0; i < RSTRUCT_LEN(s); i++) {
h = (h << 1) | (h<0 ? 1 : 0);
- n = rb_hash(RSTRUCT(s)->ptr[i]);
+ n = rb_hash(RSTRUCT_PTR(s)[i]);
h ^= NUM2LONG(n);
}
return LONG2FIX(h);
@@ -777,12 +784,12 @@
if (s == s2) return Qtrue;
if (TYPE(s2) != T_STRUCT) return Qfalse;
if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
- if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {
+ if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
rb_bug("inconsistent struct"); /* should never happen */
}
- for (i=0; i<RSTRUCT(s)->len; i++) {
- if (!rb_eql(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return Qfalse;
+ for (i=0; i<RSTRUCT_LEN(s); i++) {
+ if (!rb_eql(RSTRUCT_PTR(s)[i], RSTRUCT_PTR(s2)[i])) return Qfalse;
}
return Qtrue;
}
@@ -802,7 +809,7 @@
static VALUE
rb_struct_size(VALUE s)
{
- return LONG2FIX(RSTRUCT(s)->len);
+ return LONG2FIX(RSTRUCT_LEN(s));
}
/*
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml