mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* array.c (rb_ary_modify): should copy the internal buffer if the
modifying buffer is shared. * array.c (ary_make_shared): make an internal buffer of an array to be shared. * array.c (rb_ary_shift): avoid sliding an internal buffer by using shared buffer. * array.c (rb_ary_subseq): avoid copying the buffer. * parse.y (gettable): should freeze __LINE__ string. * io.c (rb_io_puts): old behavoir restored. rationale: a) if you want to call to_s for arrays, you can just call print a, "\n". b) to_s wastes memory if array (and sum of its contents) is huge. c) now any object that has to_ary is treated as an array, using rb_check_convert_type(). * hash.c (rb_hash_initialize): now accepts a block to calculate the default value. [new] * hash.c (rb_hash_aref): call "default" method to get the value corrensponding to the non existing key. * hash.c (rb_hash_default): get the default value based on the block given to 'new'. Now it takes an optinal "key" argument. "default" became the method to get the value for non existing key. Users may override "default" method to change the hash behavior. * hash.c (rb_hash_set_default): clear the flag if a block is given to 'new' * object.c (Init_Object): undef Data.allocate, left Data.new. * ext/curses/curses.c (window_scrollok): use RTEST(). * ext/curses/curses.c (window_idlok): ditto. * ext/curses/curses.c (window_keypad): ditto. * ext/curses/curses.c (window_idlok): idlok() may return void on some platforms; so don't use return value. * ext/curses/curses.c (window_scrollok): ditto for consistency. * ext/curses/curses.c: replace FIX2INT() by typechecking NUM2INT(). * parse.y (str_extend): should not process immature #$x and #@x interpolation, e.g #@#@ etc. * enum.c (enum_sort_by): sort_by does not have to be stable always. * enum.c (enum_sort_by): call qsort directly to gain performance. * util.c (ruby_qsort): ruby_qsort(qs6) is now native thread safe. * error.c (rb_sys_fail): it must be a bug if it's called when errno == 0. * regex.c (WC2MBC1ST): should not pass through > 0x80 number in UTF-8. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1896 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3493ea5c7a
commit
2f8d3bdc21
19 changed files with 651 additions and 334 deletions
128
ChangeLog
128
ChangeLog
|
@ -1,15 +1,53 @@
|
|||
Sun Dec 9 23:00:54 2001 Keiju Ishitsuka <keiju@ishitsuka.com>
|
||||
* matrix.rb: Vector#* bug. reported from Massimiliano Mirra
|
||||
<info@chromatic-harp.com>.
|
||||
|
||||
Sun Dec 9 22:15:59 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||
Mon Dec 10 02:09:28 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* enum.c (enum_sort_by): should replace with last elements.
|
||||
* array.c (rb_ary_modify): should copy the internal buffer if the
|
||||
modifying buffer is shared.
|
||||
|
||||
* array.c (ary_make_shared): make an internal buffer of an array
|
||||
to be shared.
|
||||
|
||||
* array.c (rb_ary_shift): avoid sliding an internal buffer by
|
||||
using shared buffer.
|
||||
|
||||
* array.c (rb_ary_subseq): avoid copying the buffer.
|
||||
|
||||
Mon Dec 10 01:06:56 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (gettable): should freeze __LINE__ string.
|
||||
|
||||
Sun Dec 9 18:06:26 2001 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* lib/net/protocol.rb: calls on_connect before conn_command
|
||||
|
||||
Sat Dec 8 23:27:44 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* io.c (rb_io_puts): old behavoir restored. rationale: a) if you
|
||||
want to call to_s for arrays, you can just call print a, "\n".
|
||||
b) to_s wastes memory if array (and sum of its contents) is
|
||||
huge. c) now any object that has to_ary is treated as an array,
|
||||
using rb_check_convert_type().
|
||||
|
||||
Sat Dec 8 22:40:38 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* hash.c (rb_hash_initialize): now accepts a block to calculate
|
||||
the default value. [new]
|
||||
|
||||
* hash.c (rb_hash_aref): call "default" method to get the value
|
||||
corrensponding to the non existing key.
|
||||
|
||||
* hash.c (rb_hash_default): get the default value based on the
|
||||
block given to 'new'. Now it takes an optinal "key" argument.
|
||||
"default" became the method to get the value for non existing
|
||||
key. Users may override "default" method to change the hash
|
||||
behavior.
|
||||
|
||||
* hash.c (rb_hash_set_default): clear the flag if a block is given
|
||||
to 'new'
|
||||
|
||||
Sat Dec 8 02:29:54 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* object.c (Init_Object): undef Data.allocate, left Data.new.
|
||||
|
||||
Fri Dec 7 19:12:14 2001 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* lib/net/smtp.rb: SMTP.new requires at least one arg.
|
||||
|
@ -27,12 +65,83 @@ Fri Dec 7 15:49:39 2001 Usaku Nakamura <usa@ruby-lang.org>
|
|||
* ext/extmk.rb.in: ignore adding -Wl,-R to DLDFLAGS when the directory
|
||||
is $topdir.
|
||||
|
||||
Fri Dec 7 13:58:58 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* ext/curses/curses.c (window_scrollok): use RTEST().
|
||||
|
||||
* ext/curses/curses.c (window_idlok): ditto.
|
||||
|
||||
* ext/curses/curses.c (window_keypad): ditto.
|
||||
|
||||
* ext/curses/curses.c (window_idlok): idlok() may return void on
|
||||
some platforms; so don't use return value.
|
||||
|
||||
* ext/curses/curses.c (window_scrollok): ditto for consistency.
|
||||
|
||||
* ext/curses/curses.c: replace FIX2INT() by typechecking NUM2INT().
|
||||
|
||||
Fri Dec 7 09:51:00 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (str_extend): should not process immature #$x and
|
||||
#@x interpolation, e.g #@#@ etc.
|
||||
|
||||
Fri Dec 7 03:21:18 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* enum.c (enum_sort_by): sort_by does not have to be stable always.
|
||||
|
||||
* enum.c (enum_sort_by): call qsort directly to gain performance.
|
||||
|
||||
Thu Dec 6 18:52:28 2001 Usaku Nakamura <usa@ruby-lang.org>
|
||||
|
||||
* ext/extmk.rb.in: add -Wl,-R flags to DLDFLAGS on netbsdelf.
|
||||
|
||||
* lib/mkmf.rb: ditto.
|
||||
|
||||
Thu Dec 6 09:15:14 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* util.c (ruby_qsort): ruby_qsort(qs6) is now native thread safe.
|
||||
|
||||
* error.c (rb_sys_fail): it must be a bug if it's called when
|
||||
errno == 0.
|
||||
|
||||
Wed Dec 5 23:36:56 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* regex.c (WC2MBC1ST): should not pass through > 0x80 number in UTF-8.
|
||||
|
||||
Tue Dec 4 17:43:10 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* ruby.h (DUPSETUP): new SETUP macro for duplication.
|
||||
|
||||
* time.c (time_dup): implement in Time class using DUPSETUP.
|
||||
|
||||
* time.c (time_getlocaltime): new method; probably requires
|
||||
better name than getlocaltime. [new,experimental]
|
||||
|
||||
* time.c (time_getgmtime): ditto.
|
||||
|
||||
* array.c (rb_ary_dup): uses DUPSETUP.
|
||||
|
||||
* string.c (rb_str_dup): uses DUPSETUP. now properly copies
|
||||
instance variables too.
|
||||
|
||||
Tue Dec 4 03:49:06 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* io.c (io_fread): EAGAIN/EWOULDBLOCK should not terminate and
|
||||
throw away the input.
|
||||
|
||||
* time.c (time_new_internal): underflow adjustment must not use
|
||||
negative div/mod.
|
||||
|
||||
* time.c (time_cmp): should consider tv_usec on non Fixnum number
|
||||
comparison.
|
||||
Sun Dec 9 23:00:54 2001 Keiju Ishitsuka <keiju@ishitsuka.com>
|
||||
* matrix.rb: Vector#* bug. reported from Massimiliano Mirra
|
||||
<info@chromatic-harp.com>.
|
||||
|
||||
Sun Dec 9 22:15:59 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||
|
||||
* enum.c (enum_sort_by): should replace with last elements.
|
||||
|
||||
Mon Dec 3 16:06:57 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||
|
||||
* ext/socket/extconf.rb: remove -L/usr/local/lib.
|
||||
|
@ -43,6 +152,13 @@ Mon Dec 3 16:04:16 2001 Usaku Nakamura <usa@ruby-lang.org>
|
|||
|
||||
* configure.in: not use X11BASE, since it's not always set.
|
||||
|
||||
Mon Dec 3 13:53:49 2001 Tanaka Akira <akr@m17n.org>
|
||||
|
||||
* time.c (rb_strftime): buffer length condition was wrong.
|
||||
|
||||
* time.c (time_strftime): should backup buf to the original
|
||||
buffer.
|
||||
|
||||
Mon Dec 3 09:59:08 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* time.c (time_plus): must detect result overflow.
|
||||
|
|
10
ToDo
10
ToDo
|
@ -71,9 +71,11 @@ Standard Libraries
|
|||
- fork_and_kill_other_threads.
|
||||
- signal list (Signal::trap, Signal::list).
|
||||
- move NameError under StandardError.
|
||||
- Integer#to_s(base)
|
||||
- Hash::new{default}
|
||||
- hash etc. should handle self referenceing array/hash
|
||||
* String#scanf(?)
|
||||
* Object#fmt(?)
|
||||
* Integer#{bin,oct,hex,heX}
|
||||
* Time::strptime
|
||||
* Integer[num], Float[num]; Fixnum[num]?
|
||||
* method to retrieve non-number trailer for to_i/to_f.
|
||||
|
@ -86,16 +88,16 @@ Standard Libraries
|
|||
* Array#&, Array#| to allow duplication. ???
|
||||
* way to specify immortal (fork endurance) thread;
|
||||
* or raise ForkException to every thread but fork caller.
|
||||
* Hash::new{default} or recommend Hash#fetch?
|
||||
* new user-defined marshal scheme. _dump(dumper), _load(restorer)
|
||||
* hash etc. should handle self referenceing array/hash
|
||||
* library to load per-user profile seeking .ruby_profile or ruby.ini file.
|
||||
* warning framework (warn, warning for Ruby level)
|
||||
* marshal should not depend on sprintf/strtod (works bad for locale).
|
||||
* marshal should not depend on sprintf/strtod (works bad with locale).
|
||||
* ternary arg pow: a.pow(b,c) == a**b%c
|
||||
* new caller(), e.g. call_stack; needs better name.
|
||||
* remove dependency on MAXPATHLEN.
|
||||
* pointer share mechanism similar to one in String for Array.
|
||||
* Array#select(n1,n2...) works like Array#indexes(n1,n2...)
|
||||
* deprecate Array#indexes, and Array#indices.
|
||||
|
||||
Extension Libraries
|
||||
|
||||
|
|
209
array.c
209
array.c
|
@ -17,7 +17,7 @@
|
|||
#include "st.h"
|
||||
|
||||
VALUE rb_cArray;
|
||||
static ID cmp;
|
||||
static ID id_cmp;
|
||||
|
||||
#define ARY_DEFAULT_SIZE 16
|
||||
|
||||
|
@ -45,7 +45,7 @@ memfill(mem, size, val)
|
|||
#define ARY_TMPLOCK FL_USER1
|
||||
|
||||
static void
|
||||
rb_ary_modify(ary)
|
||||
rb_ary_modify_check(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
if (OBJ_FROZEN(ary)) rb_error_frozen("array");
|
||||
|
@ -55,6 +55,21 @@ rb_ary_modify(ary)
|
|||
rb_raise(rb_eSecurityError, "Insecure: can't modify array");
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ary_modify(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
VALUE *ptr;
|
||||
|
||||
rb_ary_modify_check(ary);
|
||||
if (!FL_TEST(ary, ELTS_SHARED)) return;
|
||||
ptr = ALLOC_N(VALUE, RARRAY(ary)->len);
|
||||
FL_UNSET(ary, ELTS_SHARED);
|
||||
RARRAY(ary)->aux.capa = RARRAY(ary)->len;
|
||||
MEMCPY(ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
|
||||
RARRAY(ary)->ptr = ptr;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_ary_freeze(ary)
|
||||
VALUE ary;
|
||||
|
@ -79,14 +94,14 @@ rb_ary_s_alloc(klass)
|
|||
OBJSETUP(ary, klass, T_ARRAY);
|
||||
|
||||
ary->len = 0;
|
||||
ary->capa = 0;
|
||||
ary->ptr = 0;
|
||||
ary->aux.capa = 0;
|
||||
|
||||
return (VALUE)ary;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_ary_new0(klass, len)
|
||||
static VALUE
|
||||
ary_new(klass, len)
|
||||
VALUE klass;
|
||||
long len;
|
||||
{
|
||||
|
@ -100,7 +115,7 @@ rb_ary_new0(klass, len)
|
|||
}
|
||||
if (len == 0) len++;
|
||||
RARRAY(ary)->ptr = ALLOC_N(VALUE, len);
|
||||
RARRAY(ary)->capa = len;
|
||||
RARRAY(ary)->aux.capa = len;
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
@ -109,7 +124,7 @@ VALUE
|
|||
rb_ary_new2(len)
|
||||
long len;
|
||||
{
|
||||
return rb_ary_new0(rb_cArray, len);
|
||||
return ary_new(rb_cArray, len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -228,9 +243,9 @@ rb_ary_initialize(argc, argv, ary)
|
|||
if (len > 0 && len*sizeof(VALUE) <= 0) {
|
||||
rb_raise(rb_eArgError, "array size too big");
|
||||
}
|
||||
if (len > RARRAY(ary)->capa) {
|
||||
RARRAY(ary)->capa = len;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
if (len > RARRAY(ary)->aux.capa) {
|
||||
RARRAY(ary)->aux.capa = len;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
|
||||
}
|
||||
memfill(RARRAY(ary)->ptr, len, val);
|
||||
RARRAY(ary)->len = len;
|
||||
|
@ -250,7 +265,7 @@ rb_ary_s_create(argc, argv, klass)
|
|||
RARRAY(ary)->ptr = ALLOC_N(VALUE, argc);
|
||||
MEMCPY(RARRAY(ary)->ptr, argv, VALUE, argc);
|
||||
}
|
||||
RARRAY(ary)->len = RARRAY(ary)->capa = argc;
|
||||
RARRAY(ary)->len = RARRAY(ary)->aux.capa = argc;
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
@ -270,13 +285,13 @@ rb_ary_store(ary, idx, val)
|
|||
}
|
||||
}
|
||||
|
||||
if (idx >= RARRAY(ary)->capa) {
|
||||
long capa_inc = RARRAY(ary)->capa / 2;
|
||||
if (idx >= RARRAY(ary)->aux.capa) {
|
||||
long capa_inc = RARRAY(ary)->aux.capa / 2;
|
||||
if (capa_inc < ARY_DEFAULT_SIZE) {
|
||||
capa_inc = ARY_DEFAULT_SIZE;
|
||||
}
|
||||
RARRAY(ary)->capa = idx + capa_inc;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
RARRAY(ary)->aux.capa = idx + capa_inc;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
|
||||
}
|
||||
if (idx > RARRAY(ary)->len) {
|
||||
rb_mem_clear(RARRAY(ary)->ptr+RARRAY(ary)->len,
|
||||
|
@ -319,34 +334,45 @@ VALUE
|
|||
rb_ary_pop(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
rb_ary_modify(ary);
|
||||
rb_ary_modify_check(ary);
|
||||
if (RARRAY(ary)->len == 0) return Qnil;
|
||||
if (RARRAY(ary)->len * 10 < RARRAY(ary)->capa && RARRAY(ary)->capa > ARY_DEFAULT_SIZE) {
|
||||
RARRAY(ary)->capa = RARRAY(ary)->len * 2;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
if (RARRAY(ary)->len * 10 < RARRAY(ary)->aux.capa && RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {
|
||||
RARRAY(ary)->aux.capa = RARRAY(ary)->len * 2;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
|
||||
}
|
||||
return RARRAY(ary)->ptr[--RARRAY(ary)->len];
|
||||
}
|
||||
|
||||
static void
|
||||
ary_make_shared(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
if (FL_TEST(ary, ELTS_SHARED)) return;
|
||||
else {
|
||||
NEWOBJ(shared, struct RArray);
|
||||
OBJSETUP(shared, rb_cArray, T_ARRAY);
|
||||
|
||||
shared->len = RARRAY(ary)->len;
|
||||
shared->ptr = RARRAY(ary)->ptr;
|
||||
shared->aux.capa = RARRAY(ary)->aux.capa;
|
||||
RARRAY(ary)->aux.shared = (VALUE)shared;
|
||||
FL_SET(ary, ELTS_SHARED);
|
||||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_ary_shift(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
VALUE top;
|
||||
|
||||
rb_ary_modify(ary);
|
||||
rb_ary_modify_check(ary);
|
||||
if (RARRAY(ary)->len == 0) return Qnil;
|
||||
|
||||
top = RARRAY(ary)->ptr[0];
|
||||
ary_make_shared(ary);
|
||||
RARRAY(ary)->ptr++; /* shift ptr */
|
||||
RARRAY(ary)->len--;
|
||||
|
||||
/* sliding items */
|
||||
MEMMOVE(RARRAY(ary)->ptr, RARRAY(ary)->ptr+1, VALUE, RARRAY(ary)->len);
|
||||
if (RARRAY(ary)->len * 10 < RARRAY(ary)->capa && RARRAY(ary)->capa > ARY_DEFAULT_SIZE) {
|
||||
RARRAY(ary)->capa = RARRAY(ary)->len * 2;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
}
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
|
@ -355,13 +381,13 @@ rb_ary_unshift(ary, item)
|
|||
VALUE ary, item;
|
||||
{
|
||||
rb_ary_modify(ary);
|
||||
if (RARRAY(ary)->len >= RARRAY(ary)->capa) {
|
||||
long capa_inc = RARRAY(ary)->capa / 2;
|
||||
if (RARRAY(ary)->len >= RARRAY(ary)->aux.capa) {
|
||||
long capa_inc = RARRAY(ary)->aux.capa / 2;
|
||||
if (capa_inc < ARY_DEFAULT_SIZE) {
|
||||
capa_inc = ARY_DEFAULT_SIZE;
|
||||
}
|
||||
RARRAY(ary)->capa+=capa_inc;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
RARRAY(ary)->aux.capa+=capa_inc;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
|
||||
}
|
||||
|
||||
/* sliding items */
|
||||
|
@ -429,11 +455,14 @@ rb_ary_subseq(ary, beg, len)
|
|||
len = 0;
|
||||
}
|
||||
klass = rb_obj_class(ary);
|
||||
if (len == 0) return rb_ary_new0(klass,0);
|
||||
if (len == 0) return ary_new(klass,0);
|
||||
|
||||
ary2 = rb_ary_new0(klass, len);
|
||||
MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr+beg, VALUE, len);
|
||||
ary_make_shared(ary);
|
||||
ary2 = rb_obj_alloc(klass);
|
||||
RARRAY(ary2)->ptr = RARRAY(ary)->ptr+beg;
|
||||
RARRAY(ary2)->len = len;
|
||||
RARRAY(ary2)->aux.shared = RARRAY(ary)->aux.shared;
|
||||
FL_SET(ary2, ELTS_SHARED);
|
||||
|
||||
return ary2;
|
||||
}
|
||||
|
@ -609,9 +638,9 @@ rb_ary_update(ary, beg, len, rpl)
|
|||
rb_ary_modify(ary);
|
||||
if (beg >= RARRAY(ary)->len) {
|
||||
len = beg + rlen;
|
||||
if (len >= RARRAY(ary)->capa) {
|
||||
RARRAY(ary)->capa=len;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
if (len >= RARRAY(ary)->aux.capa) {
|
||||
RARRAY(ary)->aux.capa=len;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
|
||||
}
|
||||
rb_mem_clear(RARRAY(ary)->ptr+RARRAY(ary)->len, beg-RARRAY(ary)->len);
|
||||
MEMCPY(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, rlen);
|
||||
|
@ -625,9 +654,9 @@ rb_ary_update(ary, beg, len, rpl)
|
|||
}
|
||||
|
||||
alen = RARRAY(ary)->len + rlen - len;
|
||||
if (alen >= RARRAY(ary)->capa) {
|
||||
RARRAY(ary)->capa = alen;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
if (alen >= RARRAY(ary)->aux.capa) {
|
||||
RARRAY(ary)->aux.capa = alen;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
|
||||
}
|
||||
|
||||
if (len != rlen) {
|
||||
|
@ -748,33 +777,52 @@ rb_ary_empty_p(ary)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ary_copy(ary, clone)
|
||||
VALUE ary;
|
||||
int clone;
|
||||
{
|
||||
VALUE copy;
|
||||
|
||||
ary_make_shared(ary);
|
||||
copy = rb_obj_alloc(rb_cArray);
|
||||
if (clone) CLONESETUP(copy, ary);
|
||||
else DUPSETUP(copy, ary);
|
||||
RARRAY(copy)->ptr = RARRAY(ary)->ptr;
|
||||
RARRAY(copy)->len = RARRAY(ary)->len;
|
||||
RARRAY(copy)->aux.shared = RARRAY(ary)->aux.shared;
|
||||
FL_SET(copy, ELTS_SHARED);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_clone(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
VALUE clone = rb_ary_new2(RARRAY(ary)->len);
|
||||
|
||||
CLONESETUP(clone, ary);
|
||||
MEMCPY(RARRAY(clone)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
|
||||
RARRAY(clone)->len = RARRAY(ary)->len;
|
||||
return clone;
|
||||
return ary_copy(ary, Qtrue);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_ary_dup(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
return ary_copy(ary, Qfalse);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ary_dup(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
VALUE dup = rb_ary_new2(RARRAY(ary)->len);
|
||||
|
||||
OBJSETUP(dup, rb_obj_class(ary), T_ARRAY);
|
||||
DUPSETUP(dup, ary);
|
||||
MEMCPY(RARRAY(dup)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
|
||||
RARRAY(dup)->len = RARRAY(ary)->len;
|
||||
OBJ_INFECT(dup, ary);
|
||||
return dup;
|
||||
}
|
||||
|
||||
extern VALUE rb_output_fs;
|
||||
extern VALUE rb_default_rs;
|
||||
|
||||
static VALUE
|
||||
inspect_join(ary, arg)
|
||||
|
@ -861,9 +909,6 @@ rb_ary_to_s(ary)
|
|||
|
||||
if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);
|
||||
sep = rb_output_fs;
|
||||
#if 1
|
||||
if (NIL_P(rb_output_fs)) sep = rb_default_rs; /* newline */
|
||||
#endif
|
||||
str = rb_ary_join(ary, sep);
|
||||
return str;
|
||||
}
|
||||
|
@ -1006,7 +1051,7 @@ static VALUE
|
|||
rb_ary_reverse_m(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
return rb_ary_reverse(rb_ary_dup(ary));
|
||||
return rb_ary_reverse(ary_dup(ary));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1018,8 +1063,8 @@ rb_cmpint(cmp)
|
|||
if (RBIGNUM(cmp)->sign) return 1;
|
||||
return -1;
|
||||
}
|
||||
if (rb_funcall(cmp, '>', 1, INT2FIX(0))) return 1;
|
||||
if (rb_funcall(cmp, '<', 1, INT2FIX(0))) return -1;
|
||||
if (rb_funcall(id_cmp, '>', 1, INT2FIX(0))) return 1;
|
||||
if (rb_funcall(id_cmp, '<', 1, INT2FIX(0))) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1044,7 +1089,7 @@ sort_2(a, b)
|
|||
return rb_str_cmp(*a, *b);
|
||||
}
|
||||
|
||||
retval = rb_funcall(*a, cmp, 1, *b);
|
||||
retval = rb_funcall(*a, id_cmp, 1, *b);
|
||||
return rb_cmpint(retval);
|
||||
}
|
||||
|
||||
|
@ -1081,31 +1126,11 @@ VALUE
|
|||
rb_ary_sort(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
ary = rb_ary_dup(ary);
|
||||
ary = ary_dup(ary);
|
||||
rb_ary_sort_bang(ary);
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
sort_inplace(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),sort_2);
|
||||
return ary;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_ary_sort_inplace(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
rb_ary_modify(ary);
|
||||
if (RARRAY(ary)->len <= 1) return ary;
|
||||
|
||||
FL_SET(ary, ARY_TMPLOCK); /* prohibit modification during sort */
|
||||
rb_ensure(sort_inplace, ary, sort_unlock, ary);
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_collect(ary)
|
||||
VALUE ary;
|
||||
|
@ -1269,7 +1294,7 @@ static VALUE
|
|||
rb_ary_reject(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
ary = rb_ary_dup(ary);
|
||||
ary = ary_dup(ary);
|
||||
rb_ary_reject_bang(ary);
|
||||
return ary;
|
||||
}
|
||||
|
@ -1297,9 +1322,9 @@ rb_ary_clear(ary)
|
|||
{
|
||||
rb_ary_modify(ary);
|
||||
RARRAY(ary)->len = 0;
|
||||
if (ARY_DEFAULT_SIZE*3 < RARRAY(ary)->capa) {
|
||||
RARRAY(ary)->capa = ARY_DEFAULT_SIZE * 2;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
if (ARY_DEFAULT_SIZE*3 < RARRAY(ary)->aux.capa) {
|
||||
RARRAY(ary)->aux.capa = ARY_DEFAULT_SIZE * 2;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
@ -1337,9 +1362,9 @@ rb_ary_fill(argc, argv, ary)
|
|||
rb_ary_modify(ary);
|
||||
end = beg + len;
|
||||
if (end > RARRAY(ary)->len) {
|
||||
if (end >= RARRAY(ary)->capa) {
|
||||
RARRAY(ary)->capa = end;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
if (end >= RARRAY(ary)->aux.capa) {
|
||||
RARRAY(ary)->aux.capa = end;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
|
||||
}
|
||||
if (beg > RARRAY(ary)->len) {
|
||||
rb_mem_clear(RARRAY(ary)->ptr+RARRAY(ary)->len,end-RARRAY(ary)->len);
|
||||
|
@ -1397,7 +1422,7 @@ rb_ary_times(ary, times)
|
|||
}
|
||||
len *= RARRAY(ary)->len;
|
||||
|
||||
ary2 = rb_ary_new0(rb_obj_class(ary), len);
|
||||
ary2 = ary_new(rb_obj_class(ary), len);
|
||||
RARRAY(ary2)->len = len;
|
||||
|
||||
for (i=0; i<len; i+=RARRAY(ary)->len) {
|
||||
|
@ -1521,7 +1546,7 @@ rb_ary_cmp(ary, ary2)
|
|||
len = RARRAY(ary2)->len;
|
||||
}
|
||||
for (i=0; i<len; i++) {
|
||||
VALUE v = rb_funcall(RARRAY(ary)->ptr[i],cmp,1,RARRAY(ary2)->ptr[i]);
|
||||
VALUE v = rb_funcall(RARRAY(ary)->ptr[i],id_cmp,1,RARRAY(ary2)->ptr[i]);
|
||||
if (v != INT2FIX(0)) {
|
||||
return v;
|
||||
}
|
||||
|
@ -1646,7 +1671,7 @@ static VALUE
|
|||
rb_ary_uniq(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
ary = rb_ary_dup(ary);
|
||||
ary = ary_dup(ary);
|
||||
rb_ary_uniq_bang(ary);
|
||||
return ary;
|
||||
}
|
||||
|
@ -1667,7 +1692,7 @@ rb_ary_compact_bang(ary)
|
|||
if (RARRAY(ary)->len == (p - RARRAY(ary)->ptr)) {
|
||||
return Qnil;
|
||||
}
|
||||
RARRAY(ary)->len = RARRAY(ary)->capa = (p - RARRAY(ary)->ptr);
|
||||
RARRAY(ary)->len = RARRAY(ary)->aux.capa = (p - RARRAY(ary)->ptr);
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
|
||||
|
||||
return ary;
|
||||
|
@ -1677,7 +1702,7 @@ static VALUE
|
|||
rb_ary_compact(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
ary = rb_ary_dup(ary);
|
||||
ary = ary_dup(ary);
|
||||
rb_ary_compact_bang(ary);
|
||||
return ary;
|
||||
}
|
||||
|
@ -1755,7 +1780,7 @@ static VALUE
|
|||
rb_ary_flatten(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
ary = rb_ary_dup(ary);
|
||||
ary = ary_dup(ary);
|
||||
rb_ary_flatten_bang(ary);
|
||||
return ary;
|
||||
}
|
||||
|
@ -1847,5 +1872,5 @@ Init_Array()
|
|||
rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, 0);
|
||||
rb_define_method(rb_cArray, "nitems", rb_ary_nitems, 0);
|
||||
|
||||
cmp = rb_intern("<=>");
|
||||
id_cmp = rb_intern("<=>");
|
||||
}
|
||||
|
|
3
class.c
3
class.c
|
@ -87,7 +87,8 @@ rb_mod_dup(mod)
|
|||
VALUE mod;
|
||||
{
|
||||
VALUE dup = rb_mod_clone(mod);
|
||||
OBJSETUP(dup, RBASIC(mod)->klass, BUILTIN_TYPE(mod));
|
||||
|
||||
DUPSETUP(dup, mod);
|
||||
if (FL_TEST(mod, FL_SINGLETON)) {
|
||||
FL_SET(dup, FL_SINGLETON);
|
||||
}
|
||||
|
|
47
enum.c
47
enum.c
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "ruby.h"
|
||||
#include "node.h"
|
||||
#include "util.h"
|
||||
|
||||
VALUE rb_mEnumerable;
|
||||
static ID id_each, id_eqq, id_cmp;
|
||||
|
@ -204,53 +205,41 @@ enum_sort(obj)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
sort_by_i(i, memo)
|
||||
VALUE i;
|
||||
NODE *memo;
|
||||
sort_by_i(i, ary)
|
||||
VALUE i, ary;
|
||||
{
|
||||
VALUE v, e;
|
||||
|
||||
v = rb_yield(i);
|
||||
if (TYPE(v) == T_ARRAY) {
|
||||
int j, len = RARRAY(v)->len;
|
||||
|
||||
e = rb_ary_new2(len+2);
|
||||
for (j=0; j<len; j++) {
|
||||
RARRAY(e)->ptr[j] = RARRAY(v)->ptr[j];
|
||||
}
|
||||
RARRAY(e)->ptr[j++] = INT2NUM(memo->u3.cnt);
|
||||
RARRAY(e)->ptr[j] = i;
|
||||
RARRAY(e)->len = len + 2;
|
||||
}
|
||||
else {
|
||||
e = rb_ary_new3(3, v, INT2NUM(memo->u3.cnt), i);
|
||||
}
|
||||
rb_ary_push(memo->u1.value, e);
|
||||
memo->u3.cnt++;
|
||||
e = rb_assoc_new(v, i);
|
||||
rb_ary_push(ary, e);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
sort_by_sort_body(a)
|
||||
VALUE a;
|
||||
static int
|
||||
sort_by_cmp(a, b)
|
||||
VALUE *a, *b;
|
||||
{
|
||||
return rb_ary_cmp(RARRAY(a)->ptr[0], RARRAY(a)->ptr[1]);
|
||||
VALUE retval;
|
||||
|
||||
retval = rb_funcall(RARRAY(*a)->ptr[0], id_cmp, 1, RARRAY(*b)->ptr[0]);
|
||||
return rb_cmpint(retval);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
enum_sort_by(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE ary = rb_ary_new2(2000);
|
||||
NODE *memo = rb_node_newnode(NODE_MEMO, ary, 0, 0);
|
||||
VALUE ary;
|
||||
long i;
|
||||
|
||||
rb_iterate(rb_each, obj, sort_by_i, (VALUE)memo);
|
||||
rb_gc_force_recycle((VALUE)memo);
|
||||
rb_ary_sort_inplace(ary);
|
||||
ary = rb_ary_new2((TYPE(obj) == T_ARRAY) ? RARRAY(obj)->len : 2000);
|
||||
rb_iterate(rb_each, obj, sort_by_i, ary);
|
||||
if (RARRAY(ary)->len <= 1) return ary;
|
||||
qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), sort_by_cmp);
|
||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||
VALUE e = RARRAY(ary)->ptr[i];
|
||||
RARRAY(ary)->ptr[i] = RARRAY(e)->ptr[RARRAY(e)->len - 1];
|
||||
RARRAY(ary)->ptr[i] = RARRAY(e)->ptr[1];
|
||||
}
|
||||
|
||||
return ary;
|
||||
|
|
4
error.c
4
error.c
|
@ -718,6 +718,10 @@ rb_sys_fail(mesg)
|
|||
int n = errno;
|
||||
VALUE ee;
|
||||
|
||||
if (errno == 0) {
|
||||
rb_bug("rb_sys_fail() - errno == 0");
|
||||
}
|
||||
|
||||
err = strerror(errno);
|
||||
if (mesg) {
|
||||
volatile VALUE tmp = rb_str_inspect(rb_str_new2(mesg));
|
||||
|
|
|
@ -460,18 +460,20 @@ static VALUE
|
|||
curses_curs_set(VALUE obj, VALUE visibility)
|
||||
{
|
||||
int n;
|
||||
return (n = curs_set(FIX2INT(visibility)) != ERR) ? INT2FIX(n) : Qnil;
|
||||
return (n = curs_set(NUM2INT(visibility)) != ERR) ? INT2FIX(n) : Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
curses_scrl(VALUE obj, VALUE n)
|
||||
{
|
||||
/* may have to raise exception on ERR */
|
||||
return (scrl(NUM2INT(n)) == OK) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
curses_setscrreg(VALUE obj, VALUE top, VALUE bottom)
|
||||
{
|
||||
/* may have to raise exception on ERR */
|
||||
return (setscrreg(NUM2INT(top), NUM2INT(bottom)) == OK) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
|
@ -479,21 +481,21 @@ static VALUE
|
|||
curses_attroff(VALUE obj, VALUE attrs)
|
||||
{
|
||||
return window_attroff(rb_stdscr,attrs);
|
||||
/* return INT2FIX(attroff(FIX2INT(attrs))); */
|
||||
/* return INT2FIX(attroff(NUM2INT(attrs))); */
|
||||
}
|
||||
|
||||
static VALUE
|
||||
curses_attron(VALUE obj, VALUE attrs)
|
||||
{
|
||||
return window_attron(rb_stdscr,attrs);
|
||||
/* return INT2FIX(attroff(FIX2INT(attrs))); */
|
||||
/* return INT2FIX(attroff(NUM2INT(attrs))); */
|
||||
}
|
||||
|
||||
static VALUE
|
||||
curses_attrset(VALUE obj, VALUE attrs)
|
||||
{
|
||||
return window_attrset(rb_stdscr,attrs);
|
||||
/* return INT2FIX(attroff(FIX2INT(attrs))); */
|
||||
/* return INT2FIX(attroff(NUM2INT(attrs))); */
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -513,20 +515,23 @@ curses_bkgd(VALUE obj, VALUE ch)
|
|||
static VALUE
|
||||
curses_start_color(VALUE obj)
|
||||
{
|
||||
/* may have to raise exception on ERR */
|
||||
return (start_color() == OK) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
curses_init_pair(VALUE obj, VALUE pair, VALUE f, VALUE b)
|
||||
{
|
||||
return (init_pair(FIX2INT(pair),FIX2INT(f),FIX2INT(b)) == OK) ? Qtrue : Qfalse;
|
||||
/* may have to raise exception on ERR */
|
||||
return (init_pair(NUM2INT(pair),NUM2INT(f),NUM2INT(b)) == OK) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
curses_init_color(VALUE obj, VALUE color, VALUE r, VALUE g, VALUE b)
|
||||
{
|
||||
return (init_color(FIX2INT(color),FIX2INT(r),
|
||||
FIX2INT(g),FIX2INT(b)) == OK) ? Qtrue : Qfalse;
|
||||
/* may have to raise exception on ERR */
|
||||
return (init_color(NUM2INT(color),NUM2INT(r),
|
||||
NUM2INT(g),NUM2INT(b)) == OK) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -546,7 +551,7 @@ curses_color_content(VALUE obj, VALUE color)
|
|||
{
|
||||
short r,g,b;
|
||||
|
||||
color_content(FIX2INT(color),&r,&g,&b);
|
||||
color_content(NUM2INT(color),&r,&g,&b);
|
||||
return rb_ary_new3(3,INT2FIX(r),INT2FIX(g),INT2FIX(b));
|
||||
}
|
||||
|
||||
|
@ -555,20 +560,20 @@ curses_pair_content(VALUE obj, VALUE pair)
|
|||
{
|
||||
short f,b;
|
||||
|
||||
pair_content(FIX2INT(pair),&f,&b);
|
||||
pair_content(NUM2INT(pair),&f,&b);
|
||||
return rb_ary_new3(2,INT2FIX(f),INT2FIX(b));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
curses_color_pair(VALUE obj, VALUE attrs)
|
||||
{
|
||||
return INT2FIX(COLOR_PAIR(FIX2INT(attrs)));
|
||||
return INT2FIX(COLOR_PAIR(NUM2INT(attrs)));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
curses_pair_number(VALUE obj, VALUE attrs)
|
||||
{
|
||||
return INT2FIX(PAIR_NUMBER(FIX2INT(attrs)));
|
||||
return INT2FIX(PAIR_NUMBER(NUM2INT(attrs)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -591,7 +596,7 @@ no_mevent()
|
|||
static void
|
||||
curses_mousedata_free(struct mousedata *mdata)
|
||||
{
|
||||
if( mdata->mevent )
|
||||
if (mdata->mevent)
|
||||
free(mdata->mevent);
|
||||
};
|
||||
|
||||
|
@ -604,7 +609,7 @@ curses_getmouse(VALUE obj)
|
|||
val = Data_Make_Struct(cMouseEvent,struct mousedata,
|
||||
0,curses_mousedata_free,mdata);
|
||||
mdata->mevent = (MEVENT*)malloc(sizeof(MEVENT));
|
||||
return ( getmouse(mdata->mevent) == OK ) ? val : Qnil;
|
||||
return (getmouse(mdata->mevent) == OK) ? val : Qnil;
|
||||
};
|
||||
|
||||
static VALUE
|
||||
|
@ -898,8 +903,8 @@ window_box(argc, argv, self)
|
|||
|
||||
c = NUM2CHR(corn);
|
||||
getyx(winp->window, cur_y, cur_x);
|
||||
x = FIX2INT(window_maxx(self)) - 1;
|
||||
y = FIX2INT(window_maxy(self)) - 1;
|
||||
x = NUM2INT(window_maxx(self)) - 1;
|
||||
y = NUM2INT(window_maxy(self)) - 1;
|
||||
wmove(winp->window, 0, 0);
|
||||
waddch(winp->window, c);
|
||||
wmove(winp->window, y, 0);
|
||||
|
@ -1062,11 +1067,10 @@ static VALUE
|
|||
window_scrollok(VALUE obj, VALUE bf)
|
||||
{
|
||||
struct windata *winp;
|
||||
int res;
|
||||
|
||||
GetWINDOW(obj, winp);
|
||||
res = scrollok(winp->window, (bf == Qtrue) ? TRUE : FALSE);
|
||||
return (res == OK) ? Qtrue : Qfalse;
|
||||
scrollok(winp->window, RTEST(bf) ? TRUE : FALSE);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1076,8 +1080,8 @@ window_idlok(VALUE obj, VALUE bf)
|
|||
int res;
|
||||
|
||||
GetWINDOW(obj, winp);
|
||||
res = idlok(winp->window, (bf == Qtrue) ? TRUE : FALSE);
|
||||
return (res == OK) ? Qtrue : Qfalse;
|
||||
idlok(winp->window, RTEST(bf) ? TRUE : FALSE);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1088,6 +1092,7 @@ window_setscrreg(VALUE obj, VALUE top, VALUE bottom)
|
|||
|
||||
GetWINDOW(obj, winp);
|
||||
res = wsetscrreg(winp->window, NUM2INT(top), NUM2INT(bottom));
|
||||
/* may have to raise exception on ERR */
|
||||
return (res == OK) ? Qtrue : Qfalse;
|
||||
};
|
||||
|
||||
|
@ -1097,6 +1102,7 @@ window_scroll(VALUE obj)
|
|||
struct windata *winp;
|
||||
|
||||
GetWINDOW(obj, winp);
|
||||
/* may have to raise exception on ERR */
|
||||
return (scroll(winp->window) == OK) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
|
@ -1106,6 +1112,7 @@ window_scrl(VALUE obj, VALUE n)
|
|||
struct windata *winp;
|
||||
|
||||
GetWINDOW(obj, winp);
|
||||
/* may have to raise exception on ERR */
|
||||
return (wscrl(winp->window,NUM2INT(n)) == OK) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1122,7 @@ window_attroff(VALUE obj, VALUE attrs)
|
|||
struct windata *winp;
|
||||
|
||||
GetWINDOW(obj,winp);
|
||||
return INT2FIX(wattroff(winp->window,FIX2INT(attrs)));
|
||||
return INT2FIX(wattroff(winp->window,NUM2INT(attrs)));
|
||||
};
|
||||
|
||||
static VALUE
|
||||
|
@ -1125,10 +1132,10 @@ window_attron(VALUE obj, VALUE attrs)
|
|||
VALUE val;
|
||||
|
||||
GetWINDOW(obj,winp);
|
||||
val = INT2FIX(wattron(winp->window,FIX2INT(attrs)));
|
||||
val = INT2FIX(wattron(winp->window,NUM2INT(attrs)));
|
||||
if( rb_block_given_p() ){
|
||||
rb_yield(val);
|
||||
wattroff(winp->window,FIX2INT(attrs));
|
||||
wattroff(winp->window,NUM2INT(attrs));
|
||||
return val;
|
||||
}
|
||||
else{
|
||||
|
@ -1142,7 +1149,7 @@ window_attrset(VALUE obj, VALUE attrs)
|
|||
struct windata *winp;
|
||||
|
||||
GetWINDOW(obj,winp);
|
||||
return INT2FIX(wattrset(winp->window,FIX2INT(attrs)));
|
||||
return INT2FIX(wattrset(winp->window,NUM2INT(attrs)));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1182,10 +1189,11 @@ window_keypad(VALUE obj, VALUE val)
|
|||
GetWINDOW(obj,winp);
|
||||
/* keypad() of NetBSD's libcurses returns no value */
|
||||
#if defined(__NetBSD__) && !defined(NCURSES_VERSION)
|
||||
keypad(winp->window,(val == Qtrue ? TRUE : FALSE));
|
||||
keypad(winp->window,(RTEST(val) ? TRUE : FALSE));
|
||||
return Qnil;
|
||||
#else
|
||||
return (keypad(winp->window,(val == Qtrue) ? TRUE : FALSE)) == OK ?
|
||||
/* may have to raise exception on ERR */
|
||||
return (keypad(winp->window,RTEST(val) ? TRUE : FALSE)) == OK ?
|
||||
Qtrue : Qfalse;
|
||||
#endif
|
||||
};
|
||||
|
|
12
gc.c
12
gc.c
|
@ -756,6 +756,8 @@ rb_gc_mark_children(ptr)
|
|||
for (i=0; i < len; i++)
|
||||
rb_gc_mark(*ptr++);
|
||||
}
|
||||
if (FL_TEST(obj, ELTS_SHARED))
|
||||
rb_gc_mark(obj->as.array.aux.shared);
|
||||
break;
|
||||
|
||||
case T_HASH:
|
||||
|
@ -764,8 +766,9 @@ rb_gc_mark_children(ptr)
|
|||
break;
|
||||
|
||||
case T_STRING:
|
||||
if (obj->as.string.orig) {
|
||||
rb_gc_mark((VALUE)obj->as.string.orig);
|
||||
#define STR_ASSOC FL_USER2 /* copied from string.c */
|
||||
if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) {
|
||||
rb_gc_mark(obj->as.string.aux.shared);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -945,13 +948,12 @@ obj_free(obj)
|
|||
}
|
||||
break;
|
||||
case T_STRING:
|
||||
#define STR_NO_ORIG FL_USER2 /* copied from string.c */
|
||||
if (!RANY(obj)->as.string.orig || FL_TEST(obj, STR_NO_ORIG)) {
|
||||
if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) {
|
||||
RUBY_CRITICAL(free(RANY(obj)->as.string.ptr));
|
||||
}
|
||||
break;
|
||||
case T_ARRAY:
|
||||
if (RANY(obj)->as.array.ptr) {
|
||||
if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) {
|
||||
RUBY_CRITICAL(free(RANY(obj)->as.array.ptr));
|
||||
}
|
||||
break;
|
||||
|
|
41
hash.c
41
hash.c
|
@ -18,6 +18,7 @@
|
|||
#include "rubysig.h"
|
||||
|
||||
#define HASH_DELETED FL_USER1
|
||||
#define HASH_PROC_DEFAULT FL_USER2
|
||||
|
||||
static void
|
||||
rb_hash_modify(hash)
|
||||
|
@ -38,13 +39,13 @@ rb_hash_freeze(hash)
|
|||
VALUE rb_cHash;
|
||||
|
||||
static VALUE envtbl;
|
||||
static ID hash;
|
||||
static ID id_hash, id_yield, id_default;
|
||||
|
||||
VALUE
|
||||
rb_hash(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
return rb_funcall(obj, hash, 0);
|
||||
return rb_funcall(obj, id_hash, 0);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -93,7 +94,7 @@ rb_any_hash(a)
|
|||
|
||||
default:
|
||||
DEFER_INTS;
|
||||
hval = rb_funcall(a, hash, 0);
|
||||
hval = rb_funcall(a, id_hash, 0);
|
||||
if (FIXNUM_P(hval)) {
|
||||
hval %= 536870917;
|
||||
}
|
||||
|
@ -198,9 +199,18 @@ rb_hash_initialize(argc, argv, hash)
|
|||
{
|
||||
VALUE ifnone;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &ifnone);
|
||||
rb_hash_modify(hash);
|
||||
RHASH(hash)->ifnone = ifnone;
|
||||
if (rb_block_given_p()) {
|
||||
if (argc > 1) {
|
||||
rb_raise(rb_eArgError, "wrong number of arguments", argc);
|
||||
}
|
||||
RHASH(hash)->ifnone = rb_f_lambda();
|
||||
FL_SET(hash, HASH_PROC_DEFAULT);
|
||||
}
|
||||
else {
|
||||
rb_scan_args(argc, argv, "01", &ifnone);
|
||||
RHASH(hash)->ifnone = ifnone;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
@ -284,7 +294,7 @@ rb_hash_aref(hash, key)
|
|||
VALUE val;
|
||||
|
||||
if (!st_lookup(RHASH(hash)->tbl, key, &val)) {
|
||||
return RHASH(hash)->ifnone;
|
||||
return rb_funcall(hash, id_default, 1, key);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
@ -316,9 +326,17 @@ rb_hash_fetch(argc, argv, hash)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_hash_default(hash)
|
||||
rb_hash_default(argc, argv, hash)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE hash;
|
||||
{
|
||||
VALUE key;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &key);
|
||||
if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
|
||||
return rb_funcall(RHASH(hash)->ifnone, id_yield, 2, hash, key);
|
||||
}
|
||||
return RHASH(hash)->ifnone;
|
||||
}
|
||||
|
||||
|
@ -328,6 +346,7 @@ rb_hash_set_default(hash, ifnone)
|
|||
{
|
||||
rb_hash_modify(hash);
|
||||
RHASH(hash)->ifnone = ifnone;
|
||||
FL_UNSET(hash, HASH_PROC_DEFAULT);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@ -392,7 +411,7 @@ rb_hash_delete(hash, key)
|
|||
if (rb_block_given_p()) {
|
||||
return rb_yield(key);
|
||||
}
|
||||
return RHASH(hash)->ifnone;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
struct shift_var {
|
||||
|
@ -1433,7 +1452,9 @@ env_reject()
|
|||
void
|
||||
Init_Hash()
|
||||
{
|
||||
hash = rb_intern("hash");
|
||||
id_hash = rb_intern("hash");
|
||||
id_yield = rb_intern("yield");
|
||||
id_default = rb_intern("default");
|
||||
|
||||
rb_cHash = rb_define_class("Hash", rb_cObject);
|
||||
|
||||
|
@ -1456,7 +1477,7 @@ Init_Hash()
|
|||
rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1);
|
||||
rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
|
||||
rb_define_method(rb_cHash,"store", rb_hash_aset, 2);
|
||||
rb_define_method(rb_cHash,"default", rb_hash_default, 0);
|
||||
rb_define_method(rb_cHash,"default", rb_hash_default, -1);
|
||||
rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1);
|
||||
rb_define_method(rb_cHash,"index", rb_hash_index, 1);
|
||||
rb_define_method(rb_cHash,"indexes", rb_hash_indexes, -1);
|
||||
|
|
31
io.c
31
io.c
|
@ -513,6 +513,10 @@ io_fread(ptr, len, f)
|
|||
eof:
|
||||
if (ferror(f)) {
|
||||
if (errno == EINTR) continue;
|
||||
if (errno == EAGAIN) return len - n;
|
||||
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||||
if (errno == EWOULDBLOCK) return len - n;
|
||||
#endif
|
||||
rb_sys_fail(0);
|
||||
}
|
||||
*ptr = '\0';
|
||||
|
@ -2187,6 +2191,25 @@ rb_f_putc(recv, ch)
|
|||
return rb_io_putc(rb_defout, ch);
|
||||
}
|
||||
|
||||
static VALUE rb_io_puts _((int, VALUE*, VALUE));
|
||||
|
||||
static VALUE
|
||||
io_puts_ary(ary, out)
|
||||
VALUE ary, out;
|
||||
{
|
||||
VALUE tmp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||
tmp = RARRAY(ary)->ptr[i];
|
||||
if (rb_inspecting_p(tmp)) {
|
||||
tmp = rb_str_new2("[...]");
|
||||
}
|
||||
rb_io_puts(1, &tmp, out);
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_io_puts(argc, argv, out)
|
||||
int argc;
|
||||
|
@ -2206,11 +2229,11 @@ rb_io_puts(argc, argv, out)
|
|||
line = rb_str_new2("nil");
|
||||
}
|
||||
else {
|
||||
#if 0
|
||||
if (TYPE(argv[i]) == T_ARRAY) {
|
||||
rb_warn("puts behavior changed for Array");
|
||||
line = rb_check_convert_type(argv[i], T_ARRAY, "Array", "to_ary");
|
||||
if (!NIL_P(line)) {
|
||||
rb_protect_inspect(io_puts_ary, line, out);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
line = rb_obj_as_string(argv[i]);
|
||||
}
|
||||
rb_io_write(out, line);
|
||||
|
|
3
object.c
3
object.c
|
@ -313,7 +313,6 @@ rb_obj_freeze(obj)
|
|||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(obj)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze object");
|
||||
}
|
||||
|
||||
OBJ_FREEZE(obj);
|
||||
}
|
||||
return obj;
|
||||
|
@ -1292,7 +1291,7 @@ Init_Object()
|
|||
rb_undef_method(rb_cClass, "append_features");
|
||||
|
||||
rb_cData = rb_define_class("Data", rb_cObject);
|
||||
rb_undef_method(CLASS_OF(rb_cData), "new");
|
||||
rb_undef_method(CLASS_OF(rb_cData), "allocate");
|
||||
|
||||
ruby_top_self = rb_obj_alloc(rb_cObject);
|
||||
rb_global_variable(&ruby_top_self);
|
||||
|
|
22
parse.y
22
parse.y
|
@ -3938,6 +3938,10 @@ str_extend(list, term, paren)
|
|||
case '-':
|
||||
tokadd(c);
|
||||
c = nextc();
|
||||
if (!is_identchar(c)) {
|
||||
pushback();
|
||||
goto invalid_interporate;
|
||||
}
|
||||
tokadd(c);
|
||||
goto fetch_id;
|
||||
|
||||
|
@ -3956,9 +3960,14 @@ str_extend(list, term, paren)
|
|||
goto refetch;
|
||||
}
|
||||
if (!is_identchar(c)) {
|
||||
yyerror("bad global variable in string");
|
||||
newtok();
|
||||
return list;
|
||||
invalid_interporate:
|
||||
{
|
||||
VALUE s = rb_str_new2("#");
|
||||
rb_str_cat(s, tok(), toklen());
|
||||
list_append(list, NEW_STR(s));
|
||||
newtok();
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3997,6 +4006,9 @@ str_extend(list, term, paren)
|
|||
c = nextc();
|
||||
}
|
||||
pushback(c);
|
||||
if (toklen() == 1) {
|
||||
goto invalid_interporate;
|
||||
}
|
||||
break;
|
||||
|
||||
case '{':
|
||||
|
@ -4264,7 +4276,9 @@ gettable(id)
|
|||
return NEW_FALSE();
|
||||
}
|
||||
else if (id == k__FILE__) {
|
||||
return NEW_STR(rb_str_new2(ruby_sourcefile));
|
||||
VALUE f = rb_str_new2(ruby_sourcefile);
|
||||
OBJ_FREEZE(f);
|
||||
return NEW_STR(f);
|
||||
}
|
||||
else if (id == k__LINE__) {
|
||||
return NEW_LIT(INT2FIX(ruby_sourceline));
|
||||
|
|
2
regex.c
2
regex.c
|
@ -477,7 +477,7 @@ re_set_syntax(syntax)
|
|||
} while(0)
|
||||
|
||||
#define WC2MBC1ST(c) \
|
||||
((c<0x100)?(c):((current_mbctype != MBCTYPE_UTF8)?(((c)>>8)&0xff):utf8_firstbyte(c)))
|
||||
((current_mbctype != MBCTYPE_UTF8) ? ((c<0x100) ? (c) : (((c)>>8)&0xff)) : utf8_firstbyte(c))
|
||||
|
||||
static unsigned int
|
||||
utf8_firstbyte(c)
|
||||
|
|
17
ruby.h
17
ruby.h
|
@ -247,6 +247,10 @@ VALUE rb_newobj _((void));
|
|||
rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\
|
||||
if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)clone,(VALUE)obj);\
|
||||
} while (0)
|
||||
#define DUPSETUP(dup,obj) do {\
|
||||
OBJSETUP(dup,rb_obj_class(obj),(RBASIC(obj)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT));\
|
||||
if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)dup,(VALUE)obj);\
|
||||
} while (0)
|
||||
|
||||
struct RBasic {
|
||||
unsigned long flags;
|
||||
|
@ -270,16 +274,25 @@ struct RFloat {
|
|||
double value;
|
||||
};
|
||||
|
||||
#define ELTS_SHARED FL_USER2
|
||||
|
||||
struct RString {
|
||||
struct RBasic basic;
|
||||
long len;
|
||||
char *ptr;
|
||||
VALUE orig;
|
||||
union {
|
||||
int capa;
|
||||
VALUE shared;
|
||||
} aux;
|
||||
};
|
||||
|
||||
struct RArray {
|
||||
struct RBasic basic;
|
||||
long len, capa;
|
||||
long len;
|
||||
union {
|
||||
int capa;
|
||||
VALUE shared;
|
||||
} aux;
|
||||
VALUE *ptr;
|
||||
};
|
||||
|
||||
|
|
|
@ -470,6 +470,18 @@ test_ok(($x * 0).join(":") == '')
|
|||
test_ok($x.size == 7)
|
||||
test_ok($x == [1, 2, 3, 4, 5, 6, 7])
|
||||
|
||||
$x = [1,2,3]
|
||||
$x[1,0] = $x
|
||||
test_ok($x == [1,1,2,3,2,3])
|
||||
|
||||
$x = [1,2,3]
|
||||
$x[-1,0] = $x
|
||||
test_ok($x == [1,2,1,2,3,3])
|
||||
|
||||
$x = [1,2,3]
|
||||
$x.concat($x)
|
||||
test_ok($x == [1,2,3,1,2,3])
|
||||
|
||||
test_check "hash"
|
||||
$x = {1=>2, 2=>4, 3=>6}
|
||||
$y = {1, 2, 2, 4, 3, 6}
|
||||
|
@ -505,17 +517,40 @@ $z = [1,2]
|
|||
$y[$z] = 256
|
||||
test_ok($y[$z] == 256)
|
||||
|
||||
$x = [1,2,3]
|
||||
$x[1,0] = $x
|
||||
test_ok($x == [1,1,2,3,2,3])
|
||||
$x = Hash.new(0)
|
||||
$x[1] = 1
|
||||
test_ok($x[1] == 1)
|
||||
test_ok($x[2] == 0)
|
||||
|
||||
$x = [1,2,3]
|
||||
$x[-1,0] = $x
|
||||
test_ok($x == [1,2,1,2,3,3])
|
||||
$x = Hash.new([])
|
||||
test_ok($x[22] == [])
|
||||
test_ok($x[22].equal?($x[22]))
|
||||
|
||||
$x = [1,2,3]
|
||||
$x.concat($x)
|
||||
test_ok($x == [1,2,3,1,2,3])
|
||||
$x = Hash.new{[]}
|
||||
test_ok($x[22] == [])
|
||||
test_ok(!$x[22].equal?($x[22]))
|
||||
|
||||
$x = Hash.new{|h,k| $z = k; h[k] = k*2}
|
||||
$z = 0
|
||||
test_ok($x[22] == 44)
|
||||
test_ok($z == 22)
|
||||
$z = 0
|
||||
test_ok($x[22] == 44)
|
||||
test_ok($z == 0)
|
||||
$x.default = 5
|
||||
test_ok($x[23] == 5)
|
||||
|
||||
$x = Hash.new
|
||||
def $x.default(k)
|
||||
$z = k
|
||||
self[k] = k*2
|
||||
end
|
||||
$z = 0
|
||||
test_ok($x[22] == 44)
|
||||
test_ok($z == 22)
|
||||
$z = 0
|
||||
test_ok($x[22] == 44)
|
||||
test_ok($z == 0)
|
||||
|
||||
test_check "iterator"
|
||||
|
||||
|
|
225
string.c
225
string.c
|
@ -27,7 +27,6 @@
|
|||
|
||||
VALUE rb_cString;
|
||||
|
||||
#define STR_NO_ORIG FL_USER2
|
||||
#define STR_ASSOC FL_USER3
|
||||
|
||||
VALUE rb_fs;
|
||||
|
@ -41,13 +40,13 @@ rb_str_s_alloc(klass)
|
|||
|
||||
str->ptr = 0;
|
||||
str->len = 0;
|
||||
str->orig = 0;
|
||||
str->aux.capa = 0;
|
||||
|
||||
return (VALUE)str;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_new0(klass, ptr, len)
|
||||
static VALUE
|
||||
str_new(klass, ptr, len)
|
||||
VALUE klass;
|
||||
const char *ptr;
|
||||
long len;
|
||||
|
@ -55,6 +54,7 @@ rb_str_new0(klass, ptr, len)
|
|||
VALUE str = rb_obj_alloc(klass);
|
||||
|
||||
RSTRING(str)->len = len;
|
||||
RSTRING(str)->aux.capa = len;
|
||||
RSTRING(str)->ptr = ALLOC_N(char,len+1);
|
||||
if (ptr) {
|
||||
memcpy(RSTRING(str)->ptr, ptr, len);
|
||||
|
@ -68,7 +68,7 @@ rb_str_new(ptr, len)
|
|||
const char *ptr;
|
||||
long len;
|
||||
{
|
||||
return rb_str_new0(rb_cString, ptr, len);
|
||||
return str_new(rb_cString, ptr, len);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -99,51 +99,52 @@ rb_tainted_str_new2(ptr)
|
|||
return str;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_new3(str)
|
||||
VALUE str;
|
||||
static VALUE
|
||||
str_new3(klass, str)
|
||||
VALUE klass, str;
|
||||
{
|
||||
VALUE str2 = rb_obj_alloc(rb_obj_class(str));
|
||||
VALUE str2 = rb_obj_alloc(klass);
|
||||
|
||||
RSTRING(str2)->len = RSTRING(str)->len;
|
||||
RSTRING(str2)->ptr = RSTRING(str)->ptr;
|
||||
RSTRING(str2)->orig = str;
|
||||
RSTRING(str2)->aux.shared = str;
|
||||
FL_SET(str2, ELTS_SHARED);
|
||||
OBJ_INFECT(str2, str);
|
||||
|
||||
return str2;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_new3(str)
|
||||
VALUE str;
|
||||
{
|
||||
return str_new3(rb_obj_class(str), str);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_new4(orig)
|
||||
VALUE orig;
|
||||
{
|
||||
VALUE klass;
|
||||
VALUE klass, str;
|
||||
|
||||
klass = rb_obj_class(orig);
|
||||
if (RSTRING(orig)->orig) {
|
||||
VALUE str;
|
||||
|
||||
if (FL_TEST(orig, STR_NO_ORIG)) {
|
||||
str = rb_str_new0(klass, RSTRING(orig)->ptr, RSTRING(orig)->len);
|
||||
}
|
||||
else {
|
||||
str = rb_str_new3(RSTRING(orig)->orig);
|
||||
RBASIC(str)->klass = klass;
|
||||
}
|
||||
OBJ_FREEZE(str);
|
||||
return str;
|
||||
if (FL_TEST(orig, ELTS_SHARED)) {
|
||||
str = str_new3(klass, RSTRING(orig)->aux.shared);
|
||||
}
|
||||
else if (FL_TEST(orig, STR_ASSOC)) {
|
||||
str = str_new(klass, RSTRING(orig)->ptr, RSTRING(orig)->len);
|
||||
}
|
||||
else {
|
||||
VALUE str = rb_obj_alloc(klass);
|
||||
str = rb_obj_alloc(klass);
|
||||
|
||||
RSTRING(str)->len = RSTRING(orig)->len;
|
||||
RSTRING(str)->ptr = RSTRING(orig)->ptr;
|
||||
RSTRING(orig)->orig = str;
|
||||
OBJ_INFECT(str, orig);
|
||||
OBJ_FREEZE(str);
|
||||
|
||||
return str;
|
||||
RSTRING(orig)->aux.shared = str;
|
||||
FL_SET(orig, ELTS_SHARED);
|
||||
}
|
||||
OBJ_INFECT(str, orig);
|
||||
OBJ_FREEZE(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -152,7 +153,7 @@ rb_str_new5(obj, ptr, len)
|
|||
const char *ptr;
|
||||
long len;
|
||||
{
|
||||
return rb_str_new0(rb_obj_class(obj), ptr, len);
|
||||
return str_new(rb_obj_class(obj), ptr, len);
|
||||
}
|
||||
|
||||
#define STR_BUF_MIN_SIZE 128
|
||||
|
@ -163,12 +164,11 @@ rb_str_buf_new(capa)
|
|||
{
|
||||
VALUE str = rb_obj_alloc(rb_cString);
|
||||
|
||||
FL_SET(str, STR_NO_ORIG);
|
||||
if (capa < STR_BUF_MIN_SIZE)
|
||||
capa = STR_BUF_MIN_SIZE;
|
||||
RSTRING(str)->ptr = 0;
|
||||
RSTRING(str)->len = 0;
|
||||
RSTRING(str)->orig = LONG2FIX(capa);
|
||||
RSTRING(str)->aux.capa = capa;
|
||||
RSTRING(str)->ptr = ALLOC_N(char, capa+1);
|
||||
RSTRING(str)->ptr[0] = '\0';
|
||||
|
||||
|
@ -210,16 +210,23 @@ rb_str_become(str, str2)
|
|||
if (NIL_P(str2)) {
|
||||
RSTRING(str)->ptr = 0;
|
||||
RSTRING(str)->len = 0;
|
||||
RSTRING(str)->orig = 0;
|
||||
RSTRING(str)->aux.capa = 0;
|
||||
return;
|
||||
}
|
||||
if ((!RSTRING(str)->orig||FL_TEST(str,STR_NO_ORIG))&&RSTRING(str)->ptr)
|
||||
free(RSTRING(str)->ptr);
|
||||
if (FL_TEST(str, ELTS_SHARED)) free(RSTRING(str)->ptr);
|
||||
RSTRING(str)->ptr = RSTRING(str2)->ptr;
|
||||
RSTRING(str)->len = RSTRING(str2)->len;
|
||||
RSTRING(str)->orig = RSTRING(str2)->orig;
|
||||
if (FL_TEST(str2, ELTS_SHARED|STR_ASSOC)) {
|
||||
FL_SET(str, RBASIC(str2)->flags & (ELTS_SHARED|STR_ASSOC));
|
||||
RSTRING(str)->aux.shared = RSTRING(str2)->aux.shared;
|
||||
}
|
||||
else {
|
||||
RSTRING(str)->aux.capa = RSTRING(str2)->aux.capa;
|
||||
}
|
||||
RSTRING(str2)->ptr = 0; /* abandon str2 */
|
||||
RSTRING(str2)->len = 0;
|
||||
RSTRING(str2)->aux.capa = 0;
|
||||
FL_UNSET(str, ELTS_SHARED|STR_ASSOC);
|
||||
if (OBJ_TAINTED(str2)) OBJ_TAINT(str);
|
||||
}
|
||||
|
||||
|
@ -227,22 +234,23 @@ void
|
|||
rb_str_associate(str, add)
|
||||
VALUE str, add;
|
||||
{
|
||||
if (FL_TEST(str, STR_NO_ORIG|STR_ASSOC) != (STR_NO_ORIG|STR_ASSOC)) {
|
||||
if (FL_TEST(str, STR_NO_ORIG)) {
|
||||
if (FL_TEST(str, STR_ASSOC)) {
|
||||
/* already associated */
|
||||
rb_ary_concat(RSTRING(str)->aux.shared, add);
|
||||
}
|
||||
else {
|
||||
if (FL_TEST(str, ELTS_SHARED)) {
|
||||
rb_str_modify(str);
|
||||
}
|
||||
else if (RSTRING(str)->aux.shared) {
|
||||
/* str_buf */
|
||||
if (FIX2LONG(RSTRING(str)->orig) != RSTRING(str)->len) {
|
||||
if (RSTRING(str)->aux.capa != RSTRING(str)->len) {
|
||||
REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len + 1);
|
||||
}
|
||||
}
|
||||
else if (RSTRING(str)->orig) {
|
||||
rb_str_modify(str);
|
||||
}
|
||||
RSTRING(str)->orig = add;
|
||||
FL_SET(str, STR_NO_ORIG|STR_ASSOC);
|
||||
}
|
||||
else {
|
||||
/* already associated */
|
||||
rb_ary_concat(RSTRING(str)->orig, add);
|
||||
RSTRING(str)->aux.shared = add;
|
||||
FL_UNSET(str, ELTS_SHARED);
|
||||
FL_SET(str, STR_ASSOC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,10 +258,10 @@ VALUE
|
|||
rb_str_associated(str)
|
||||
VALUE str;
|
||||
{
|
||||
if (FL_TEST(str, STR_NO_ORIG|STR_ASSOC) != (STR_NO_ORIG|STR_ASSOC)) {
|
||||
return Qfalse;
|
||||
if (FL_TEST(str, STR_ASSOC)) {
|
||||
return RSTRING(str)->aux.shared;
|
||||
}
|
||||
return RSTRING(str)->orig;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
static ID id_to_s;
|
||||
|
@ -274,45 +282,53 @@ rb_obj_as_string(obj)
|
|||
return str;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_dup(str)
|
||||
static VALUE
|
||||
str_copy(str, clone)
|
||||
VALUE str;
|
||||
int clone;
|
||||
{
|
||||
VALUE str2;
|
||||
VALUE klass;
|
||||
int flags;
|
||||
|
||||
StringValue(str);
|
||||
klass = rb_obj_class(str);
|
||||
|
||||
if (OBJ_FROZEN(str)) str2 = rb_str_new3(str);
|
||||
else if (FL_TEST(str, STR_NO_ORIG)) {
|
||||
str2 = rb_str_new0(klass, RSTRING(str)->ptr, RSTRING(str)->len);
|
||||
if (FL_TEST(str, ELTS_SHARED)) {
|
||||
str2 = rb_str_new3(RSTRING(str)->aux.shared);
|
||||
}
|
||||
else if (RSTRING(str)->orig) {
|
||||
str2 = rb_str_new3(RSTRING(str)->orig);
|
||||
RBASIC(str2)->klass = klass;
|
||||
FL_UNSET(str2, FL_TAINT);
|
||||
OBJ_INFECT(str2, str);
|
||||
else if (FL_TEST(str, STR_ASSOC)) {
|
||||
str2 = str_new(RSTRING(str)->ptr, RSTRING(str)->len);
|
||||
RSTRING(str2)->aux.shared = RSTRING(str)->aux.shared;
|
||||
}
|
||||
else if (OBJ_FROZEN(str)) {
|
||||
str2 = rb_str_new3(str);
|
||||
}
|
||||
else {
|
||||
str2 = rb_str_new3(rb_str_new4(str));
|
||||
}
|
||||
if (FL_TEST(str, FL_EXIVAR))
|
||||
rb_copy_generic_ivar(str2, str);
|
||||
OBJ_INFECT(str2, str);
|
||||
flags = FL_TEST(str2, ELTS_SHARED|STR_ASSOC);
|
||||
if (clone) {
|
||||
CLONESETUP(str2, str);
|
||||
}
|
||||
else {
|
||||
DUPSETUP(str2, str);
|
||||
}
|
||||
if (flags) FL_SET(str2, flags);
|
||||
return str2;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_dup(str)
|
||||
VALUE str;
|
||||
{
|
||||
return str_copy(str, Qfalse);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_clone(str)
|
||||
VALUE str;
|
||||
{
|
||||
VALUE clone = rb_str_dup(str);
|
||||
if (FL_TEST(str, STR_NO_ORIG))
|
||||
RSTRING(clone)->orig = RSTRING(str)->orig;
|
||||
CLONESETUP(clone, str);
|
||||
|
||||
return clone;
|
||||
return str_copy(str, Qtrue);
|
||||
}
|
||||
|
||||
static VALUE rb_str_replace _((VALUE, VALUE));
|
||||
|
@ -446,9 +462,7 @@ str_independent(str)
|
|||
if (OBJ_FROZEN(str)) rb_error_frozen("string");
|
||||
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
|
||||
if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return 1;
|
||||
if (RBASIC(str)->flags == 0) abort();
|
||||
if (TYPE(RSTRING(str)->orig) != T_STRING) rb_bug("non string str->orig");
|
||||
if (!FL_TEST(str, ELTS_SHARED)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -465,7 +479,8 @@ rb_str_modify(str)
|
|||
}
|
||||
ptr[RSTRING(str)->len] = 0;
|
||||
RSTRING(str)->ptr = ptr;
|
||||
RSTRING(str)->orig = 0;
|
||||
RSTRING(str)->aux.capa = RSTRING(str)->len;
|
||||
FL_UNSET(str, ELTS_SHARED|STR_ASSOC);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -479,9 +494,9 @@ VALUE
|
|||
rb_str_dup_frozen(str)
|
||||
VALUE str;
|
||||
{
|
||||
if (RSTRING(str)->orig && !FL_TEST(str, STR_NO_ORIG)) {
|
||||
OBJ_FREEZE(RSTRING(str)->orig);
|
||||
return RSTRING(str)->orig;
|
||||
if (FL_TEST(str, ELTS_SHARED)) {
|
||||
OBJ_FREEZE(RSTRING(str)->aux.shared);
|
||||
return RSTRING(str)->aux.shared;
|
||||
}
|
||||
if (OBJ_FROZEN(str)) return str;
|
||||
str = rb_str_dup(str);
|
||||
|
@ -516,21 +531,17 @@ rb_str_buf_cat(str, ptr, len)
|
|||
{
|
||||
long i, capa, total;
|
||||
|
||||
if (RSTRING(str)->orig == 0) {
|
||||
capa = RSTRING(str)->len;
|
||||
FL_SET(str, STR_NO_ORIG);
|
||||
if (FL_TEST(str, ELTS_SHARED)) {
|
||||
rb_str_modify(str);
|
||||
}
|
||||
else {
|
||||
capa = FIX2LONG(RSTRING(str)->orig);
|
||||
}
|
||||
|
||||
capa = RSTRING(str)->aux.capa;
|
||||
total = RSTRING(str)->len+len;
|
||||
if (capa <= total) {
|
||||
while (total > capa) {
|
||||
capa = (capa + 1) * 2;
|
||||
}
|
||||
REALLOC_N(RSTRING(str)->ptr, char, capa+1);
|
||||
RSTRING(str)->orig = LONG2FIX(capa);
|
||||
RSTRING(str)->aux.capa = capa;
|
||||
}
|
||||
memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
|
||||
RSTRING(str)->len = total;
|
||||
|
@ -557,8 +568,7 @@ rb_str_cat(str, ptr, len)
|
|||
|
||||
rb_str_modify(str);
|
||||
if (len > 0) {
|
||||
if (RSTRING(str)->orig == 0 ||
|
||||
(FL_TEST(str, STR_NO_ORIG) && !FL_TEST(str, STR_ASSOC))) {
|
||||
if (!FL_TEST(str, ELTS_SHARED) && !FL_TEST(str, STR_ASSOC)) {
|
||||
return rb_str_buf_cat(str, ptr, len);
|
||||
}
|
||||
REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+len+1);
|
||||
|
@ -589,13 +599,10 @@ rb_str_buf_append(str, str2)
|
|||
{
|
||||
long i, capa, len;
|
||||
|
||||
if (RSTRING(str)->orig == 0) {
|
||||
capa = RSTRING(str)->len;
|
||||
FL_SET(str, STR_NO_ORIG);
|
||||
}
|
||||
else {
|
||||
capa = FIX2LONG(RSTRING(str)->orig);
|
||||
if (FL_TEST(str, ELTS_SHARED)) {
|
||||
rb_str_modify(str);
|
||||
}
|
||||
capa = RSTRING(str)->aux.capa;
|
||||
|
||||
len = RSTRING(str)->len+RSTRING(str2)->len;
|
||||
if (capa <= len) {
|
||||
|
@ -603,7 +610,7 @@ rb_str_buf_append(str, str2)
|
|||
capa = (capa + 1) * 2;
|
||||
}
|
||||
REALLOC_N(RSTRING(str)->ptr, char, capa+1);
|
||||
RSTRING(str)->orig = LONG2FIX(capa);
|
||||
RSTRING(str)->aux.capa = capa;
|
||||
}
|
||||
memcpy(RSTRING(str)->ptr + RSTRING(str)->len,
|
||||
RSTRING(str2)->ptr, RSTRING(str2)->len);
|
||||
|
@ -623,11 +630,9 @@ rb_str_append(str, str2)
|
|||
rb_str_modify(str);
|
||||
if (RSTRING(str2)->len > 0) {
|
||||
len = RSTRING(str)->len+RSTRING(str2)->len;
|
||||
if (RSTRING(str)->orig == 0 ||
|
||||
(FL_TEST(str, STR_NO_ORIG) && !FL_TEST(str, STR_ASSOC))) {
|
||||
if (!FL_TEST(str, ELTS_SHARED) && !FL_TEST(str, STR_ASSOC)) {
|
||||
rb_str_buf_append(str, str2);
|
||||
OBJ_INFECT(str, str2);
|
||||
|
||||
return str;
|
||||
}
|
||||
REALLOC_N(RSTRING(str)->ptr, char, len+1);
|
||||
|
@ -810,6 +815,13 @@ rb_str_match2(str)
|
|||
return rb_reg_match2(rb_reg_regcomp(str));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_match_m(str, re)
|
||||
VALUE str, re;
|
||||
{
|
||||
return rb_funcall(re, rb_intern("match"), 1, str);
|
||||
}
|
||||
|
||||
static long
|
||||
rb_str_index(str, sub, offset)
|
||||
VALUE str, sub;
|
||||
|
@ -1529,20 +1541,18 @@ str_gsub(argc, argv, str, bang)
|
|||
if (str_independent(str)) {
|
||||
free(RSTRING(str)->ptr);
|
||||
}
|
||||
else {
|
||||
RSTRING(str)->orig = 0;
|
||||
}
|
||||
FL_UNSET(str, ELTS_SHARED|STR_ASSOC);
|
||||
}
|
||||
else {
|
||||
VALUE dup = rb_obj_alloc(rb_obj_class(str));
|
||||
|
||||
OBJ_INFECT(dup, str);
|
||||
str = dup;
|
||||
RSTRING(dup)->orig = 0;
|
||||
}
|
||||
RSTRING(str)->ptr = buf;
|
||||
RSTRING(str)->len = len = bp - buf;
|
||||
RSTRING(str)->ptr[len] = '\0';
|
||||
RSTRING(str)->aux.capa = len;
|
||||
|
||||
if (tainted) OBJ_TAINT(str);
|
||||
return str;
|
||||
|
@ -1573,13 +1583,19 @@ rb_str_replace(str, str2)
|
|||
if (str == str2) return str;
|
||||
|
||||
StringValue(str2);
|
||||
if (RSTRING(str2)->orig && !FL_TEST(str2, STR_NO_ORIG)) {
|
||||
if (FL_TEST(str2, ELTS_SHARED)) {
|
||||
if (str_independent(str)) {
|
||||
free(RSTRING(str)->ptr);
|
||||
}
|
||||
RSTRING(str)->len = RSTRING(str2)->len;
|
||||
RSTRING(str)->ptr = RSTRING(str2)->ptr;
|
||||
RSTRING(str)->orig = RSTRING(str2)->orig;
|
||||
if (FL_TEST(str2, ELTS_SHARED|STR_ASSOC)) {
|
||||
FL_SET(str, RBASIC(str2)->flags & (ELTS_SHARED|STR_ASSOC));
|
||||
RSTRING(str)->aux.shared = RSTRING(str2)->aux.shared;
|
||||
}
|
||||
else {
|
||||
RSTRING(str)->aux.capa = RSTRING(str2)->aux.capa;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rb_str_modify(str);
|
||||
|
@ -3113,6 +3129,7 @@ Init_String()
|
|||
rb_define_method(rb_cString, "empty?", rb_str_empty, 0);
|
||||
rb_define_method(rb_cString, "=~", rb_str_match, 1);
|
||||
rb_define_method(rb_cString, "~", rb_str_match2, 0);
|
||||
rb_define_method(rb_cString, "match", rb_str_match_m, 1);
|
||||
rb_define_method(rb_cString, "succ", rb_str_succ, 0);
|
||||
rb_define_method(rb_cString, "succ!", rb_str_succ_bang, 0);
|
||||
rb_define_method(rb_cString, "next", rb_str_succ, 0);
|
||||
|
|
55
time.c
55
time.c
|
@ -72,9 +72,9 @@ time_new_internal(klass, sec, usec)
|
|||
sec += usec / 1000000;
|
||||
usec %= 1000000;
|
||||
}
|
||||
if (usec < 0) { /* usec underflow */
|
||||
sec -= (-usec) / 1000000;
|
||||
usec %= 1000000;
|
||||
while (usec < 0) { /* usec underflow */
|
||||
sec--;
|
||||
usec += 1000000;
|
||||
}
|
||||
#ifndef NEGATIVE_TIME_T
|
||||
if (sec < 0 || (sec == 0 && usec < 0))
|
||||
|
@ -643,7 +643,13 @@ time_cmp(time1, time2)
|
|||
return INT2FIX(-1);
|
||||
}
|
||||
i = NUM2LONG(time2);
|
||||
if (tobj1->tv.tv_sec == i) return INT2FIX(0);
|
||||
if (tobj1->tv.tv_sec == i) {
|
||||
if (tobj1->tv.tv_usec == 0)
|
||||
return INT2FIX(0);
|
||||
if (tobj1->tv.tv_usec > 0)
|
||||
return INT2FIX(1);
|
||||
return INT2FIX(-1);
|
||||
}
|
||||
if (tobj1->tv.tv_sec > i) return INT2FIX(1);
|
||||
return INT2FIX(-1);
|
||||
}
|
||||
|
@ -759,6 +765,35 @@ time_gmtime(time)
|
|||
return time;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
time_dup(time)
|
||||
VALUE time;
|
||||
{
|
||||
VALUE clone;
|
||||
struct time_object *tobj, *tclone;
|
||||
|
||||
GetTimeval(time, tobj);
|
||||
clone = Data_Make_Struct(0, struct time_object, 0, free, tclone);
|
||||
DUPSETUP(clone, time);
|
||||
MEMCPY(tclone, tobj, struct time_object, 1);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
time_getlocaltime(time)
|
||||
VALUE time;
|
||||
{
|
||||
return time_localtime(time_dup(time));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
time_getgmtime(time)
|
||||
VALUE time;
|
||||
{
|
||||
return time_gmtime(time_dup(time));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
time_get_tm(time, gmt)
|
||||
VALUE time;
|
||||
|
@ -1071,7 +1106,7 @@ rb_strftime(buf, format, time)
|
|||
* if the buffer is 1024 times bigger than the length of the
|
||||
* format string, it's not failing for lack of room.
|
||||
*/
|
||||
if (len > 0 || len >= 1024 * flen) return len;
|
||||
if (len > 0 || size >= 1024 * flen) return len;
|
||||
free(*buf);
|
||||
}
|
||||
/* not reached */
|
||||
|
@ -1109,7 +1144,10 @@ time_strftime(time, format)
|
|||
p += strlen(p) + 1;
|
||||
if (p <= pe)
|
||||
rb_str_cat(str, "\0", 1);
|
||||
if (len > SMALLBUF) free(buf);
|
||||
if (buf != buffer) {
|
||||
free(buf);
|
||||
buf = buffer;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
@ -1231,10 +1269,15 @@ Init_Time()
|
|||
rb_define_method(rb_cTime, "eql?", time_eql, 1);
|
||||
rb_define_method(rb_cTime, "hash", time_hash, 0);
|
||||
rb_define_method(rb_cTime, "clone", time_clone, 0);
|
||||
rb_define_method(rb_cTime, "dup", time_dup, 0);
|
||||
|
||||
rb_define_method(rb_cTime, "localtime", time_localtime, 0);
|
||||
rb_define_method(rb_cTime, "gmtime", time_gmtime, 0);
|
||||
rb_define_method(rb_cTime, "utc", time_gmtime, 0);
|
||||
rb_define_method(rb_cTime, "getlocal", time_getlocaltime, 0);
|
||||
rb_define_method(rb_cTime, "getgm", time_getgmtime, 0);
|
||||
rb_define_method(rb_cTime, "getutc", time_getgmtime, 0);
|
||||
|
||||
rb_define_method(rb_cTime, "ctime", time_asctime, 0);
|
||||
rb_define_method(rb_cTime, "asctime", time_asctime, 0);
|
||||
rb_define_method(rb_cTime, "to_s", time_to_s, 0);
|
||||
|
|
59
util.c
59
util.c
|
@ -384,31 +384,25 @@ __crt0_glob_function(char *path)
|
|||
|
||||
/* mm.c */
|
||||
|
||||
static int mmkind, mmsize, high, low;
|
||||
|
||||
#define A ((int*)a)
|
||||
#define B ((int*)b)
|
||||
#define C ((int*)c)
|
||||
#define D ((int*)d)
|
||||
|
||||
static void mmprepare(base, size) void *base; int size;
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (sizeof(int) != 4) die("sizeof(int) != 4");
|
||||
if (size <= 0) die("mmsize <= 0");
|
||||
#endif
|
||||
#define mmprepare(base, size) do {\
|
||||
if (((long)base & (0x3)) == 0)\
|
||||
if (size >= 16) mmkind = 1;\
|
||||
else mmkind = 0;\
|
||||
else mmkind = -1;\
|
||||
high = (size & (~0xf));\
|
||||
low = (size & 0x0c);\
|
||||
} while (0)\
|
||||
|
||||
if (((long)base & (4-1)) == 0 && ((long)base & (4-1)) == 0)
|
||||
if (size >= 16) mmkind = 1;
|
||||
else mmkind = 0;
|
||||
else mmkind = -1;
|
||||
|
||||
mmsize = size;
|
||||
high = (size & (-16));
|
||||
low = (size & 0x0c);
|
||||
}
|
||||
#define mmarg mmkind, size, high, low
|
||||
|
||||
static void mmswap(a, b) register char *a, *b;
|
||||
static void mmswap_(a, b, mmarg)
|
||||
register char *a, *b;
|
||||
int mmarg;
|
||||
{
|
||||
register int s;
|
||||
if (a == b) return;
|
||||
|
@ -427,12 +421,15 @@ static void mmswap(a, b) register char *a, *b;
|
|||
if (low == 12) {s = A[2]; A[2] = B[2]; B[2] = s;}}}
|
||||
}
|
||||
else {
|
||||
register char *t = a + mmsize;
|
||||
register char *t = a + size;
|
||||
do {s = *a; *a++ = *b; *b++ = s;} while (a < t);
|
||||
}
|
||||
}
|
||||
#define mmswap(a,b) mmswap_((a),(b),mmarg)
|
||||
|
||||
static void mmrot3(a, b, c) register char *a, *b, *c;
|
||||
static void mmrot3_(a, b, c, mmarg)
|
||||
register char *a, *b, *c;
|
||||
int mmarg;
|
||||
{
|
||||
register int s;
|
||||
if (mmkind >= 0) {
|
||||
|
@ -450,10 +447,11 @@ static void mmrot3(a, b, c) register char *a, *b, *c;
|
|||
if (low == 12) {s = A[2]; A[2] = B[2]; B[2] = C[2]; C[2] = s;}}}
|
||||
}
|
||||
else {
|
||||
register char *t = a + mmsize;
|
||||
register char *t = a + size;
|
||||
do {s = *a; *a++ = *b; *b++ = *c; *c++ = s;} while (a < t);
|
||||
}
|
||||
}
|
||||
#define mmrot3(a,b,c) mmrot3_((a),(b),(c),mmarg)
|
||||
|
||||
/* qs6.c */
|
||||
/*****************************************************/
|
||||
|
@ -472,14 +470,19 @@ typedef struct { char *LL, *RR; } stack_node; /* Stack structure for L,l,R,r */
|
|||
((*cmp)(b,c)<0 ? b : ((*cmp)(a,c)<0 ? c : a)) : \
|
||||
((*cmp)(b,c)>0 ? b : ((*cmp)(a,c)<0 ? a : c)))
|
||||
|
||||
void ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp)();
|
||||
void ruby_qsort (base, nel, size, cmp)
|
||||
void* base;
|
||||
const int nel;
|
||||
const int size;
|
||||
int (*cmp)();
|
||||
{
|
||||
register char *l, *r, *m; /* l,r:left,right group m:median point */
|
||||
register int t, eq_l, eq_r; /* eq_l: all items in left group are equal to S */
|
||||
char *L = base; /* left end of curren region */
|
||||
char *R = (char*)base + size*(nel-1); /* right end of current region */
|
||||
int chklim = 63; /* threshold of ordering element check */
|
||||
stack_node stack[32], *top = stack; /* 32 is enough for 32bit CPU */
|
||||
char *R = (char*)base + size*(nel-1); /* right end of current region */
|
||||
int chklim = 63; /* threshold of ordering element check */
|
||||
stack_node stack[32], *top = stack; /* 32 is enough for 32bit CPU */
|
||||
int mmkind, high, low;
|
||||
|
||||
if (nel <= 1) return; /* need not to sort */
|
||||
mmprepare(base, size);
|
||||
|
@ -491,7 +494,9 @@ void ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp)
|
|||
|
||||
for (;;) {
|
||||
start:
|
||||
if (L + size == R) {if ((*cmp)(L,R) > 0) mmswap(L,R); goto nxt;}/* 2 elements */
|
||||
if (L + size == R) { /* 2 elements */
|
||||
if ((*cmp)(L,R) > 0) mmswap(L,R); goto nxt;
|
||||
}
|
||||
|
||||
l = L; r = R;
|
||||
t = (r - l + size) / size; /* number of elements */
|
||||
|
@ -559,7 +564,7 @@ void ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp)
|
|||
if ((t = (*cmp)(m,r)) < 0) {goto loopA;} /*5-5-7*/
|
||||
if (t > 0) {mmswap(l,r); goto loopB;} /*5-5-3*/
|
||||
|
||||
/* deteming splitting type in case 5-5-5 */ /*5-5-5*/
|
||||
/* determining splitting type in case 5-5-5 */ /*5-5-5*/
|
||||
for (;;) {
|
||||
if ((l += size) == r) goto nxt; /*5-5-5*/
|
||||
if (l == m) continue;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define RUBY_VERSION "1.7.2"
|
||||
#define RUBY_RELEASE_DATE "2001-12-09"
|
||||
#define RUBY_RELEASE_DATE "2001-12-10"
|
||||
#define RUBY_VERSION_CODE 172
|
||||
#define RUBY_RELEASE_CODE 20011209
|
||||
#define RUBY_RELEASE_CODE 20011210
|
||||
|
|
Loading…
Reference in a new issue