mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* array.c (rb_ary_uniq_bang): element size might change during
comparison. [ruby-dev:24298] * enum.c (enum_sort_by): do not use qsort directly. use rb_ary_sort_bang() instead. [ruby-dev:24291] * enum.c (enum_sort_by): pedantic type check added. [ruby-dev:24291] * hash.c (rb_hash_foreach_iter): check iter_lev after each iteration. [ruby-dev:24289] * array.c (rb_ary_and): element size might change during comparison. [ruby-dev:24290] * array.c (rb_ary_or): ditto. [ruby-dev:24292] * array.c (rb_ary_equal): wrong fix. [ruby-dev:24286] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6940 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
de5a85496a
commit
ba19ba779c
8 changed files with 124 additions and 61 deletions
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
Tue Sep 21 18:29:49 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* array.c (rb_ary_uniq_bang): element size might change during
|
||||||
|
comparison. [ruby-dev:24298]
|
||||||
|
|
||||||
|
Mon Sep 20 00:24:19 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* enum.c (enum_sort_by): do not use qsort directly. use
|
||||||
|
rb_ary_sort_bang() instead. [ruby-dev:24291]
|
||||||
|
|
||||||
|
* enum.c (enum_sort_by): pedantic type check added.
|
||||||
|
[ruby-dev:24291]
|
||||||
|
|
||||||
|
* hash.c (rb_hash_foreach_iter): check iter_lev after each
|
||||||
|
iteration. [ruby-dev:24289]
|
||||||
|
|
||||||
|
* array.c (rb_ary_and): element size might change during
|
||||||
|
comparison. [ruby-dev:24290]
|
||||||
|
|
||||||
|
* array.c (rb_ary_or): ditto. [ruby-dev:24292]
|
||||||
|
|
||||||
|
* array.c (rb_ary_equal): wrong fix. [ruby-dev:24286]
|
||||||
|
|
||||||
Sat Sep 18 15:02:22 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Sat Sep 18 15:02:22 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* array.c (rb_ary_equal): element size might change during
|
* array.c (rb_ary_equal): element size might change during
|
||||||
|
|
94
array.c
94
array.c
|
@ -561,21 +561,28 @@ rb_ary_unshift_m(argc, argv, ary)
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* faster version - use this if you don't need to treat negative offset */
|
||||||
|
static inline VALUE
|
||||||
|
rb_ary_elt(ary, offset)
|
||||||
|
VALUE ary;
|
||||||
|
long offset;
|
||||||
|
{
|
||||||
|
if (RARRAY(ary)->len == 0) return Qnil;
|
||||||
|
if (offset < 0 || RARRAY(ary)->len <= offset) {
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
return RARRAY(ary)->ptr[offset];
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_ary_entry(ary, offset)
|
rb_ary_entry(ary, offset)
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
long offset;
|
long offset;
|
||||||
{
|
{
|
||||||
if (RARRAY(ary)->len == 0) return Qnil;
|
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
offset += RARRAY(ary)->len;
|
offset += RARRAY(ary)->len;
|
||||||
}
|
}
|
||||||
if (offset < 0 || RARRAY(ary)->len <= offset) {
|
return rb_ary_elt(ary, offset);
|
||||||
return Qnil;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RARRAY(ary)->ptr[offset];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -857,6 +864,10 @@ rb_ary_index(ary, val)
|
||||||
* array.rindex(obj) -> int or nil
|
* array.rindex(obj) -> int or nil
|
||||||
*
|
*
|
||||||
* Returns the index of the last object in <i>array</i>
|
* Returns the index of the last object in <i>array</i>
|
||||||
|
if (i > RARRAY(ary)->len) {
|
||||||
|
i = RARRAY(ary)->len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
* <code>==</code> to <i>obj</i>. Returns <code>nil</code> if
|
* <code>==</code> to <i>obj</i>. Returns <code>nil</code> if
|
||||||
* no match is found.
|
* no match is found.
|
||||||
*
|
*
|
||||||
|
@ -1533,17 +1544,36 @@ rb_ary_reverse_m(ary)
|
||||||
return rb_ary_reverse(rb_ary_dup(ary));
|
return rb_ary_reverse(rb_ary_dup(ary));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ary_sort_data {
|
||||||
|
VALUE ary;
|
||||||
|
VALUE *ptr;
|
||||||
|
long len;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
ary_sort_check(data)
|
||||||
|
struct ary_sort_data *data;
|
||||||
|
{
|
||||||
|
if (RARRAY(data->ary)->ptr != data->ptr || RARRAY(data->ary)->len != data->len) {
|
||||||
|
rb_raise(rb_eArgError, "array modified during sort");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sort_1(a, b)
|
sort_1(a, b, data)
|
||||||
VALUE *a, *b;
|
VALUE *a, *b;
|
||||||
|
struct ary_sort_data *data;
|
||||||
{
|
{
|
||||||
VALUE retval = rb_yield_values(2, *a, *b);
|
VALUE retval = rb_yield_values(2, *a, *b);
|
||||||
|
|
||||||
|
ary_sort_check(data);
|
||||||
return rb_cmpint(retval, *a, *b);
|
return rb_cmpint(retval, *a, *b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sort_2(ap, bp)
|
sort_2(ap, bp, data)
|
||||||
VALUE *ap, *bp;
|
VALUE *ap, *bp;
|
||||||
|
struct ary_sort_data *data;
|
||||||
{
|
{
|
||||||
VALUE retval;
|
VALUE retval;
|
||||||
long a = (long)*ap, b = (long)*bp;
|
long a = (long)*ap, b = (long)*bp;
|
||||||
|
@ -1558,6 +1588,7 @@ sort_2(ap, bp)
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = rb_funcall(a, id_cmp, 1, b);
|
retval = rb_funcall(a, id_cmp, 1, b);
|
||||||
|
ary_sort_check(data);
|
||||||
return rb_cmpint(retval, a, b);
|
return rb_cmpint(retval, a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1565,8 +1596,12 @@ static VALUE
|
||||||
sort_internal(ary)
|
sort_internal(ary)
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
{
|
{
|
||||||
|
struct ary_sort_data data;
|
||||||
|
|
||||||
|
data.ary = ary;
|
||||||
|
data.ptr = RARRAY(ary)->ptr; data.len = RARRAY(ary)->len;
|
||||||
qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),
|
qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),
|
||||||
rb_block_given_p()?sort_1:sort_2);
|
rb_block_given_p()?sort_1:sort_2, &data);
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1775,7 +1810,7 @@ rb_ary_select(argc, argv, ary)
|
||||||
result = rb_ary_new2(RARRAY(ary)->len);
|
result = rb_ary_new2(RARRAY(ary)->len);
|
||||||
for (i = 0; i < RARRAY(ary)->len; i++) {
|
for (i = 0; i < RARRAY(ary)->len; i++) {
|
||||||
if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {
|
if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {
|
||||||
rb_ary_push(result, rb_ary_entry(ary, i));
|
rb_ary_push(result, rb_ary_elt(ary, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -2038,9 +2073,9 @@ rb_ary_zip(argc, argv, ary)
|
||||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||||
VALUE tmp = rb_ary_new2(argc+1);
|
VALUE tmp = rb_ary_new2(argc+1);
|
||||||
|
|
||||||
rb_ary_push(tmp, rb_ary_entry(ary, i));
|
rb_ary_push(tmp, rb_ary_elt(ary, i));
|
||||||
for (j=0; j<argc; j++) {
|
for (j=0; j<argc; j++) {
|
||||||
rb_ary_push(tmp, rb_ary_entry(argv[j], i));
|
rb_ary_push(tmp, rb_ary_elt(argv[j], i));
|
||||||
}
|
}
|
||||||
rb_yield(tmp);
|
rb_yield(tmp);
|
||||||
}
|
}
|
||||||
|
@ -2051,9 +2086,9 @@ rb_ary_zip(argc, argv, ary)
|
||||||
for (i=0; i<len; i++) {
|
for (i=0; i<len; i++) {
|
||||||
VALUE tmp = rb_ary_new2(argc+1);
|
VALUE tmp = rb_ary_new2(argc+1);
|
||||||
|
|
||||||
rb_ary_push(tmp, rb_ary_entry(ary, i));
|
rb_ary_push(tmp, rb_ary_elt(ary, i));
|
||||||
for (j=0; j<argc; j++) {
|
for (j=0; j<argc; j++) {
|
||||||
rb_ary_push(tmp, rb_ary_entry(argv[j], i));
|
rb_ary_push(tmp, rb_ary_elt(argv[j], i));
|
||||||
}
|
}
|
||||||
rb_ary_push(result, tmp);
|
rb_ary_push(result, tmp);
|
||||||
}
|
}
|
||||||
|
@ -2081,7 +2116,7 @@ rb_ary_transpose(ary)
|
||||||
alen = RARRAY(ary)->len;
|
alen = RARRAY(ary)->len;
|
||||||
if (alen == 0) return rb_ary_dup(ary);
|
if (alen == 0) return rb_ary_dup(ary);
|
||||||
for (i=0; i<alen; i++) {
|
for (i=0; i<alen; i++) {
|
||||||
tmp = to_ary(rb_ary_entry(ary, i));
|
tmp = to_ary(rb_ary_elt(ary, i));
|
||||||
if (elen < 0) { /* first element */
|
if (elen < 0) { /* first element */
|
||||||
elen = RARRAY(tmp)->len;
|
elen = RARRAY(tmp)->len;
|
||||||
result = rb_ary_new2(elen);
|
result = rb_ary_new2(elen);
|
||||||
|
@ -2094,7 +2129,7 @@ rb_ary_transpose(ary)
|
||||||
RARRAY(tmp)->len, elen);
|
RARRAY(tmp)->len, elen);
|
||||||
}
|
}
|
||||||
for (j=0; j<elen; j++) {
|
for (j=0; j<elen; j++) {
|
||||||
rb_ary_store(rb_ary_entry(result, j), i, rb_ary_entry(tmp, j));
|
rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -2441,7 +2476,7 @@ rb_ary_equal(ary1, ary2)
|
||||||
}
|
}
|
||||||
for (i=0; i<RARRAY(ary1)->len; i++) {
|
for (i=0; i<RARRAY(ary1)->len; i++) {
|
||||||
if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
|
if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
|
||||||
if (!rb_equal(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i]))
|
if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
|
@ -2640,7 +2675,7 @@ rb_ary_and(ary1, ary2)
|
||||||
for (i=0; i<RARRAY(ary1)->len; i++) {
|
for (i=0; i<RARRAY(ary1)->len; i++) {
|
||||||
VALUE v = RARRAY(ary1)->ptr[i];
|
VALUE v = RARRAY(ary1)->ptr[i];
|
||||||
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) {
|
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) {
|
||||||
rb_ary_push(ary3, RARRAY(ary1)->ptr[i]);
|
rb_ary_push(ary3, rb_ary_elt(ary1, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2671,15 +2706,15 @@ rb_ary_or(ary1, ary2)
|
||||||
hash = ary_make_hash(ary1, ary2);
|
hash = ary_make_hash(ary1, ary2);
|
||||||
|
|
||||||
for (i=0; i<RARRAY(ary1)->len; i++) {
|
for (i=0; i<RARRAY(ary1)->len; i++) {
|
||||||
v = RARRAY(ary1)->ptr[i];
|
v = rb_ary_elt(ary1, i);
|
||||||
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) {
|
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) {
|
||||||
rb_ary_push(ary3, RARRAY(ary1)->ptr[i]);
|
rb_ary_push(ary3, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i=0; i<RARRAY(ary2)->len; i++) {
|
for (i=0; i<RARRAY(ary2)->len; i++) {
|
||||||
v = RARRAY(ary2)->ptr[i];
|
v = rb_ary_elt(ary2, i);
|
||||||
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) {
|
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) {
|
||||||
rb_ary_push(ary3, RARRAY(ary2)->ptr[i]);
|
rb_ary_push(ary3, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ary3;
|
return ary3;
|
||||||
|
@ -2704,7 +2739,7 @@ rb_ary_uniq_bang(ary)
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
{
|
{
|
||||||
VALUE hash;
|
VALUE hash;
|
||||||
VALUE *p, *q, *end;
|
long i, j;
|
||||||
|
|
||||||
rb_ary_modify(ary);
|
rb_ary_modify(ary);
|
||||||
|
|
||||||
|
@ -2713,16 +2748,13 @@ rb_ary_uniq_bang(ary)
|
||||||
if (RARRAY(ary)->len == RHASH(hash)->tbl->num_entries) {
|
if (RARRAY(ary)->len == RHASH(hash)->tbl->num_entries) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
p = q = RARRAY(ary)->ptr;
|
for (i=j=0; i<RARRAY(ary)->len; i++) {
|
||||||
end = p + RARRAY(ary)->len;
|
VALUE v = rb_ary_elt(ary, i);
|
||||||
while (p < end) {
|
|
||||||
VALUE v = *p;
|
|
||||||
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) {
|
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) {
|
||||||
*q++ = *p;
|
rb_ary_store(ary, j++, v);
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
RARRAY(ary)->len = (q - RARRAY(ary)->ptr);
|
RARRAY(ary)->len = j;
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
3
dir.c
3
dir.c
|
@ -648,8 +648,9 @@ dir_s_chdir(argc, argv, obj)
|
||||||
|
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
struct chdir_data args;
|
struct chdir_data args;
|
||||||
|
char *cwd = my_getcwd();
|
||||||
|
|
||||||
args.old_path = rb_str_new2(my_getcwd());
|
args.old_path = rb_tainted_str_new2(cwd); free(cwd);
|
||||||
args.new_path = path;
|
args.new_path = path;
|
||||||
args.done = Qfalse;
|
args.done = Qfalse;
|
||||||
return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
|
return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
|
||||||
|
|
17
enum.c
17
enum.c
|
@ -397,14 +397,17 @@ sort_by_i(i, ary)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static VALUE
|
||||||
sort_by_cmp(a, b)
|
sort_by_cmp(values, ary)
|
||||||
VALUE *a, *b;
|
VALUE values;
|
||||||
{
|
{
|
||||||
VALUE retval;
|
VALUE a = RARRAY(values)->ptr[0];
|
||||||
|
VALUE b = RARRAY(values)->ptr[1];
|
||||||
|
|
||||||
retval = rb_funcall(RARRAY(*a)->ptr[0], id_cmp, 1, RARRAY(*b)->ptr[0]);
|
/* pedantic check; they must be arrays */
|
||||||
return rb_cmpint(retval, *a, *b);
|
Check_Type(a, T_ARRAY);
|
||||||
|
Check_Type(b, T_ARRAY);
|
||||||
|
return rb_funcall(RARRAY(a)->ptr[0], id_cmp, 1, RARRAY(b)->ptr[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -491,7 +494,7 @@ enum_sort_by(obj)
|
||||||
}
|
}
|
||||||
rb_iterate(rb_each, obj, sort_by_i, ary);
|
rb_iterate(rb_each, obj, sort_by_i, ary);
|
||||||
if (RARRAY(ary)->len > 1) {
|
if (RARRAY(ary)->len > 1) {
|
||||||
qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), sort_by_cmp);
|
rb_iterate(rb_ary_sort_bang, ary, sort_by_cmp, ary);
|
||||||
}
|
}
|
||||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||||
VALUE e = RARRAY(ary)->ptr[i];
|
VALUE e = RARRAY(ary)->ptr[i];
|
||||||
|
|
6
hash.c
6
hash.c
|
@ -131,9 +131,13 @@ rb_hash_foreach_iter(key, value, arg)
|
||||||
|
|
||||||
if (key == Qundef) return ST_CONTINUE;
|
if (key == Qundef) return ST_CONTINUE;
|
||||||
status = (*arg->func)(key, value, arg->arg);
|
status = (*arg->func)(key, value, arg->arg);
|
||||||
if (RHASH(arg->hash)->tbl != tbl || RHASH(arg->hash)->tbl->bins != bins){
|
if (RHASH(arg->hash)->tbl != tbl ||
|
||||||
|
RHASH(arg->hash)->tbl->bins != bins) {
|
||||||
rb_raise(rb_eIndexError, "rehash occurred during iteration");
|
rb_raise(rb_eIndexError, "rehash occurred during iteration");
|
||||||
}
|
}
|
||||||
|
if (RHASH(arg->hash)->iter_lev == 0) {
|
||||||
|
rb_raise(rb_eArgError, "block re-entered");
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,6 @@ def DelegateClass(superclass)
|
||||||
@_dc_obj = obj
|
@_dc_obj = obj
|
||||||
end
|
end
|
||||||
def method_missing(m, *args)
|
def method_missing(m, *args)
|
||||||
p [m, *args]
|
|
||||||
unless @_dc_obj.respond_to?(m)
|
unless @_dc_obj.respond_to?(m)
|
||||||
super(m, *args)
|
super(m, *args)
|
||||||
end
|
end
|
||||||
|
|
37
util.c
37
util.c
|
@ -466,15 +466,16 @@ typedef struct { char *LL, *RR; } stack_node; /* Stack structure for L,l,R,r */
|
||||||
#define PUSH(ll,rr) do { top->LL = (ll); top->RR = (rr); ++top; } while (0) /* Push L,l,R,r */
|
#define PUSH(ll,rr) do { top->LL = (ll); top->RR = (rr); ++top; } while (0) /* Push L,l,R,r */
|
||||||
#define POP(ll,rr) do { --top; ll = top->LL; rr = top->RR; } while (0) /* Pop L,l,R,r */
|
#define POP(ll,rr) do { --top; ll = top->LL; rr = top->RR; } while (0) /* Pop L,l,R,r */
|
||||||
|
|
||||||
#define med3(a,b,c) ((*cmp)(a,b)<0 ? \
|
#define med3(a,b,c) ((*cmp)(a,b,d)<0 ? \
|
||||||
((*cmp)(b,c)<0 ? b : ((*cmp)(a,c)<0 ? c : a)) : \
|
((*cmp)(b,c,d)<0 ? b : ((*cmp)(a,c,d)<0 ? c : a)) : \
|
||||||
((*cmp)(b,c)>0 ? b : ((*cmp)(a,c)<0 ? a : c)))
|
((*cmp)(b,c,d)>0 ? b : ((*cmp)(a,c,d)<0 ? a : c)))
|
||||||
|
|
||||||
void ruby_qsort (base, nel, size, cmp)
|
void ruby_qsort (base, nel, size, cmp, d)
|
||||||
void* base;
|
void* base;
|
||||||
const int nel;
|
const int nel;
|
||||||
const int size;
|
const int size;
|
||||||
int (*cmp)();
|
int (*cmp)();
|
||||||
|
void *d;
|
||||||
{
|
{
|
||||||
register char *l, *r, *m; /* l,r:left,right group m:median point */
|
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 */
|
register int t, eq_l, eq_r; /* eq_l: all items in left group are equal to S */
|
||||||
|
@ -495,7 +496,7 @@ void ruby_qsort (base, nel, size, cmp)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
start:
|
start:
|
||||||
if (L + size == R) { /* 2 elements */
|
if (L + size == R) { /* 2 elements */
|
||||||
if ((*cmp)(L,R) > 0) mmswap(L,R); goto nxt;
|
if ((*cmp)(L,R,d) > 0) mmswap(L,R); goto nxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
l = L; r = R;
|
l = L; r = R;
|
||||||
|
@ -526,49 +527,49 @@ void ruby_qsort (base, nel, size, cmp)
|
||||||
m = med3(m1, m, m3);
|
m = med3(m1, m, m3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((t = (*cmp)(l,m)) < 0) { /*3-5-?*/
|
if ((t = (*cmp)(l,m,d)) < 0) { /*3-5-?*/
|
||||||
if ((t = (*cmp)(m,r)) < 0) { /*3-5-7*/
|
if ((t = (*cmp)(m,r,d)) < 0) { /*3-5-7*/
|
||||||
if (chklim && nel >= chklim) { /* check if already ascending order */
|
if (chklim && nel >= chklim) { /* check if already ascending order */
|
||||||
char *p;
|
char *p;
|
||||||
chklim = 0;
|
chklim = 0;
|
||||||
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) > 0) goto fail;
|
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size,d) > 0) goto fail;
|
||||||
goto nxt;
|
goto nxt;
|
||||||
}
|
}
|
||||||
fail: goto loopA; /*3-5-7*/
|
fail: goto loopA; /*3-5-7*/
|
||||||
}
|
}
|
||||||
if (t > 0) {
|
if (t > 0) {
|
||||||
if ((*cmp)(l,r) <= 0) {mmswap(m,r); goto loopA;} /*3-5-4*/
|
if ((*cmp)(l,r,d) <= 0) {mmswap(m,r); goto loopA;} /*3-5-4*/
|
||||||
mmrot3(r,m,l); goto loopA; /*3-5-2*/
|
mmrot3(r,m,l); goto loopA; /*3-5-2*/
|
||||||
}
|
}
|
||||||
goto loopB; /*3-5-5*/
|
goto loopB; /*3-5-5*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t > 0) { /*7-5-?*/
|
if (t > 0) { /*7-5-?*/
|
||||||
if ((t = (*cmp)(m,r)) > 0) { /*7-5-3*/
|
if ((t = (*cmp)(m,r,d)) > 0) { /*7-5-3*/
|
||||||
if (chklim && nel >= chklim) { /* check if already ascending order */
|
if (chklim && nel >= chklim) { /* check if already ascending order */
|
||||||
char *p;
|
char *p;
|
||||||
chklim = 0;
|
chklim = 0;
|
||||||
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) < 0) goto fail2;
|
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size,d) < 0) goto fail2;
|
||||||
while (l<r) {mmswap(l,r); l+=size; r-=size;} /* reverse region */
|
while (l<r) {mmswap(l,r); l+=size; r-=size;} /* reverse region */
|
||||||
goto nxt;
|
goto nxt;
|
||||||
}
|
}
|
||||||
fail2: mmswap(l,r); goto loopA; /*7-5-3*/
|
fail2: mmswap(l,r); goto loopA; /*7-5-3*/
|
||||||
}
|
}
|
||||||
if (t < 0) {
|
if (t < 0) {
|
||||||
if ((*cmp)(l,r) <= 0) {mmswap(l,m); goto loopB;} /*7-5-8*/
|
if ((*cmp)(l,r,d) <= 0) {mmswap(l,m); goto loopB;} /*7-5-8*/
|
||||||
mmrot3(l,m,r); goto loopA; /*7-5-6*/
|
mmrot3(l,m,r); goto loopA; /*7-5-6*/
|
||||||
}
|
}
|
||||||
mmswap(l,r); goto loopA; /*7-5-5*/
|
mmswap(l,r); goto loopA; /*7-5-5*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((t = (*cmp)(m,r)) < 0) {goto loopA;} /*5-5-7*/
|
if ((t = (*cmp)(m,r,d)) < 0) {goto loopA;} /*5-5-7*/
|
||||||
if (t > 0) {mmswap(l,r); goto loopB;} /*5-5-3*/
|
if (t > 0) {mmswap(l,r); goto loopB;} /*5-5-3*/
|
||||||
|
|
||||||
/* determining splitting type in case 5-5-5 */ /*5-5-5*/
|
/* determining splitting type in case 5-5-5 */ /*5-5-5*/
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((l += size) == r) goto nxt; /*5-5-5*/
|
if ((l += size) == r) goto nxt; /*5-5-5*/
|
||||||
if (l == m) continue;
|
if (l == m) continue;
|
||||||
if ((t = (*cmp)(l,m)) > 0) {mmswap(l,r); l = L; goto loopA;} /*575-5*/
|
if ((t = (*cmp)(l,m,d)) > 0) {mmswap(l,r); l = L; goto loopA;}/*575-5*/
|
||||||
if (t < 0) {mmswap(L,l); l = L; goto loopB;} /*535-5*/
|
if (t < 0) {mmswap(L,l); l = L; goto loopB;} /*535-5*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,14 +579,14 @@ void ruby_qsort (base, nel, size, cmp)
|
||||||
if ((l += size) == r)
|
if ((l += size) == r)
|
||||||
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
|
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
|
||||||
if (l == m) continue;
|
if (l == m) continue;
|
||||||
if ((t = (*cmp)(l,m)) > 0) {eq_r = 0; break;}
|
if ((t = (*cmp)(l,m,d)) > 0) {eq_r = 0; break;}
|
||||||
if (t < 0) eq_l = 0;
|
if (t < 0) eq_l = 0;
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (l == (r -= size))
|
if (l == (r -= size))
|
||||||
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
|
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
|
||||||
if (r == m) {m = l; break;}
|
if (r == m) {m = l; break;}
|
||||||
if ((t = (*cmp)(r,m)) < 0) {eq_l = 0; break;}
|
if ((t = (*cmp)(r,m,d)) < 0) {eq_l = 0; break;}
|
||||||
if (t == 0) break;
|
if (t == 0) break;
|
||||||
}
|
}
|
||||||
mmswap(l,r); /* swap left and right */
|
mmswap(l,r); /* swap left and right */
|
||||||
|
@ -597,14 +598,14 @@ void ruby_qsort (base, nel, size, cmp)
|
||||||
if (l == (r -= size))
|
if (l == (r -= size))
|
||||||
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
|
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
|
||||||
if (r == m) continue;
|
if (r == m) continue;
|
||||||
if ((t = (*cmp)(r,m)) < 0) {eq_l = 0; break;}
|
if ((t = (*cmp)(r,m,d)) < 0) {eq_l = 0; break;}
|
||||||
if (t > 0) eq_r = 0;
|
if (t > 0) eq_r = 0;
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((l += size) == r)
|
if ((l += size) == r)
|
||||||
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
|
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
|
||||||
if (l == m) {m = r; break;}
|
if (l == m) {m = r; break;}
|
||||||
if ((t = (*cmp)(l,m)) > 0) {eq_r = 0; break;}
|
if ((t = (*cmp)(l,m,d)) > 0) {eq_r = 0; break;}
|
||||||
if (t == 0) break;
|
if (t == 0) break;
|
||||||
}
|
}
|
||||||
mmswap(l,r); /* swap left and right */
|
mmswap(l,r); /* swap left and right */
|
||||||
|
|
4
util.h
4
util.h
|
@ -43,8 +43,8 @@ unsigned long scan_hex _((const char*, int, int*));
|
||||||
void ruby_add_suffix();
|
void ruby_add_suffix();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ruby_qsort _((void*, const int, const int, int (*)()));
|
void ruby_qsort _((void*, const int, const int, int (*)(), void*));
|
||||||
#define qsort(b,n,s,c) ruby_qsort(b,n,s,c)
|
#define qsort(b,n,s,c,d) ruby_qsort(b,n,s,c,d)
|
||||||
|
|
||||||
void ruby_setenv _((const char*, const char*));
|
void ruby_setenv _((const char*, const char*));
|
||||||
void ruby_unsetenv _((const char*));
|
void ruby_unsetenv _((const char*));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue