diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-09-21 03:08:33 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-09-21 03:08:33 +0000 |
commit | bfabc05a4375b84fa128af89337b1195248bd6da (patch) | |
tree | ae0c8f703dca2b6ae94a5b5518c736d373bca377 | |
parent | 90ae99b0f0505f66a6fc1dfb7d7c631bf4bf76cc (diff) |
* 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/trunk@6939 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 41 | ||||
-rw-r--r-- | array.c | 94 | ||||
-rw-r--r-- | configure.in | 18 | ||||
-rw-r--r-- | dir.c | 51 | ||||
-rw-r--r-- | enum.c | 17 | ||||
-rw-r--r-- | eval.c | 35 | ||||
-rw-r--r-- | gc.c | 21 | ||||
-rw-r--r-- | hash.c | 6 | ||||
-rw-r--r-- | lib/delegate.rb | 1 | ||||
-rw-r--r-- | util.c | 37 | ||||
-rw-r--r-- | util.h | 4 |
11 files changed, 232 insertions, 93 deletions
@@ -99,6 +99,47 @@ Mon Sep 20 03:37:59 2004 Tanaka Akira <[email protected]> * ext/zlib/zlib.c (gzfile_read_raw): call readpartial at first. (Zlib::GzipReader#readpartial): new method. +Mon Sep 20 00:24:19 2004 Yukihiro Matsumoto <[email protected]> + + * 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 <[email protected]> + + * array.c (rb_ary_equal): element size might change during + comparison. [ruby-dev:24254] + + * array.c (rb_ary_diff): ditto. [ruby-dev:24274] + + * array.c (rb_ary_select): ditto. [ruby-dev:24278] + + * array.c (rb_ary_delete): ditto. [ruby-dev:24283] + + * array.c (rb_ary_rindex): ditto. [ruby-dev:24275] + + * array.c (rb_ary_initialize): element size might change during + initializing block. [ruby-dev:24284] + +Sat Sep 18 14:10:23 2004 Yukihiro Matsumoto <[email protected]> + + * dir.c (dir_s_chdir): avoid memory leak and unnecessary chdir to + the original directory when exception has caused in changing + direcotry or within block. thanks to Johan Holmberg + <[email protected]> [ruby-core:03446] + Fri Sep 17 20:29:33 2004 NAKAMURA Usaku <[email protected]> * parse.y: add prototypes for Microsoft compiler. @@ -393,7 +393,7 @@ rb_ary_initialize(argc, argv, ary) rb_warn("block supersedes default value argument"); } for (i=0; i<len; i++) { - RARRAY(ary)->ptr[i] = rb_yield(LONG2NUM(i)); + rb_ary_store(ary, i, rb_yield(LONG2NUM(i))); RARRAY(ary)->len = i + 1; } } @@ -715,23 +715,30 @@ rb_ary_unshift_m(argc, argv, ary) return ary; } -VALUE -rb_ary_entry(ary, offset) +/* 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) { - offset += RARRAY(ary)->len; - } if (offset < 0 || RARRAY(ary)->len <= offset) { return Qnil; } - return RARRAY(ary)->ptr[offset]; } +VALUE +rb_ary_entry(ary, offset) + VALUE ary; + long offset; +{ + if (offset < 0) { + offset += RARRAY(ary)->len; + } + return rb_ary_elt(ary, offset); +} + static VALUE rb_ary_subseq(ary, beg, len) VALUE ary; @@ -1011,6 +1018,10 @@ rb_ary_rindex(ary, val) long i = RARRAY(ary)->len; while (i--) { + if (i > RARRAY(ary)->len) { + i = RARRAY(ary)->len; + continue; + } if (rb_equal(RARRAY(ary)->ptr[i], val)) return LONG2NUM(i); } @@ -1641,17 +1652,36 @@ rb_ary_reverse_m(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 -sort_1(a, b) +sort_1(a, b, data) VALUE *a, *b; + struct ary_sort_data *data; { VALUE retval = rb_yield_values(2, *a, *b); + + ary_sort_check(data); return rb_cmpint(retval, *a, *b); } static int -sort_2(ap, bp) +sort_2(ap, bp, data) VALUE *ap, *bp; + struct ary_sort_data *data; { VALUE retval; long a = (long)*ap, b = (long)*bp; @@ -1666,6 +1696,7 @@ sort_2(ap, bp) } retval = rb_funcall(a, id_cmp, 1, b); + ary_sort_check(data); return rb_cmpint(retval, a, b); } @@ -1673,8 +1704,12 @@ static VALUE sort_internal(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), - rb_block_given_p()?sort_1:sort_2); + rb_block_given_p()?sort_1:sort_2, &data); return ary; } @@ -1878,7 +1913,7 @@ rb_ary_select(ary) result = rb_ary_new2(RARRAY(ary)->len); for (i = 0; i < RARRAY(ary)->len; i++) { if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) { - rb_ary_push(result, RARRAY(ary)->ptr[i]); + rb_ary_push(result, rb_ary_elt(ary, i)); } } return result; @@ -1910,9 +1945,12 @@ rb_ary_delete(ary, item) rb_ary_modify(ary); for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { - if (rb_equal(RARRAY(ary)->ptr[i1], item)) continue; + VALUE e = RARRAY(ary)->ptr[i1]; + + if (rb_equal(e, item)) continue; if (i1 != i2) { - RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1]; + if (RARRAY(ary)->len < i2) break; + RARRAY(ary)->ptr[i2] = e; } i2++; } @@ -2138,9 +2176,9 @@ rb_ary_zip(argc, argv, ary) for (i=0; i<RARRAY(ary)->len; i++) { 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++) { - rb_ary_push(tmp, rb_ary_entry(argv[j], i)); + rb_ary_push(tmp, rb_ary_elt(argv[j], i)); } rb_yield(tmp); } @@ -2151,9 +2189,9 @@ rb_ary_zip(argc, argv, ary) for (i=0; i<len; i++) { 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++) { - 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); } @@ -2181,7 +2219,7 @@ rb_ary_transpose(ary) alen = RARRAY(ary)->len; if (alen == 0) return rb_ary_dup(ary); for (i=0; i<alen; i++) { - tmp = to_ary(RARRAY(ary)->ptr[i]); + tmp = to_ary(rb_ary_elt(ary, i)); if (elen < 0) { /* first element */ elen = RARRAY(tmp)->len; result = rb_ary_new2(elen); @@ -2194,7 +2232,7 @@ rb_ary_transpose(ary) RARRAY(tmp)->len, elen); } for (j=0; j<elen; j++) { - rb_ary_store(RARRAY(result)->ptr[j], i, RARRAY(tmp)->ptr[j]); + rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j)); } } return result; @@ -2541,7 +2579,7 @@ rb_ary_equal(ary1, ary2) } if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse; for (i=0; i<RARRAY(ary1)->len; i++) { - 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 Qtrue; @@ -2709,7 +2747,7 @@ rb_ary_diff(ary1, ary2) for (i=0; i<RARRAY(ary1)->len; i++) { if (st_lookup(RHASH(hash)->tbl, RARRAY(ary1)->ptr[i], 0)) continue; - rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); + rb_ary_push(ary3, rb_ary_elt(ary1, i)); } return ary3; } @@ -2738,9 +2776,9 @@ rb_ary_and(ary1, ary2) hash = ary_make_hash(ary2, 0); for (i=0; i<RARRAY(ary1)->len; i++) { - VALUE v = RARRAY(ary1)->ptr[i]; + VALUE v = rb_ary_elt(ary1, i); if (st_delete(RHASH(hash)->tbl, (st_data_t*)&v, 0)) { - rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); + rb_ary_push(ary3, v); } } @@ -2771,15 +2809,15 @@ rb_ary_or(ary1, ary2) hash = ary_make_hash(ary1, ary2); 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)) { - rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); + rb_ary_push(ary3, v); } } 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)) { - rb_ary_push(ary3, RARRAY(ary2)->ptr[i]); + rb_ary_push(ary3, v); } } return ary3; diff --git a/configure.in b/configure.in index b82c6b19bd..ca3e2714a3 100644 --- a/configure.in +++ b/configure.in @@ -380,7 +380,7 @@ AC_CHECK_HEADERS(stdlib.h string.h unistd.h limits.h sys/file.h sys/ioctl.h\ fcntl.h sys/fcntl.h sys/select.h sys/time.h sys/times.h sys/param.h\ syscall.h pwd.h grp.h a.out.h utime.h memory.h direct.h sys/resource.h \ sys/mkdev.h sys/utime.h netinet/in_systm.h float.h ieeefp.h pthread.h \ - ucontext.h intrinsics.h) + ucontext.h intrinsics.h unwind.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_UID_T @@ -522,6 +522,22 @@ AC_C_CHAR_UNSIGNED AC_C_INLINE AC_C_VOLATILE +if test x"$target_cpu" = xia64; then + if test x"$ac_cv_header_unwind_h" = xyes; then + LIBS="-lunwind $LIBS" + else + AC_CACHE_CHECK(IA64 backing store member in mcontext_t, rb_cv_ia64_bspstore, + [rb_cv_ia64_bspstore=no; + for mem in mc_special.bspstore sc_ar_bsp; do + AC_TRY_COMPILE([#include <ucontext.h> +],[ucontext_t ctx; ctx.uc_mcontext.$mem = 0;], [rb_cv_ia64_bspstore=$mem; break]) + done]) + if test "$rb_cv_ia64_bspstore" != no; then + AC_DEFINE_UNQUOTED(IA64_BSPSTORE, $rb_cv_ia64_bspstore) + fi + fi +fi + AC_CACHE_CHECK(whether right shift preserve sign bit, rb_cv_rshift_sign, [AC_TRY_RUN([ int @@ -677,36 +677,42 @@ dir_close(dir) static void dir_chdir(path) - const char *path; + VALUE path; { - if (chdir(path) < 0) - rb_sys_fail(path); + if (chdir(RSTRING(path)->ptr) < 0) + rb_sys_fail(RSTRING(path)->ptr); } static int chdir_blocking = 0; static VALUE chdir_thread = Qnil; struct chdir_data { - char *dist; - VALUE path; + VALUE old_path, new_path; + int done; }; static VALUE chdir_yield(args) struct chdir_data *args; { - dir_chdir(args->dist); - return rb_yield(args->path); + dir_chdir(args->new_path); + args->done = Qtrue; + chdir_blocking++; + if (chdir_thread == Qnil) + chdir_thread = rb_thread_current(); + return rb_yield(args->new_path); } static VALUE -chdir_restore(path) - char *path; +chdir_restore(args) + struct chdir_data *args; { - chdir_blocking--; - if (chdir_blocking == 0) - chdir_thread = Qnil; - dir_chdir(path); + if (args->done) { + chdir_blocking--; + if (chdir_blocking == 0) + chdir_thread = Qnil; + dir_chdir(args->old_path); + } return Qnil; } @@ -756,19 +762,18 @@ dir_s_chdir(argc, argv, obj) VALUE obj; { VALUE path = Qnil; - char *dist = ""; rb_secure(2); if (rb_scan_args(argc, argv, "01", &path) == 1) { FilePathValue(path); - dist = RSTRING(path)->ptr; } else { - dist = getenv("HOME"); + const char *dist = getenv("HOME"); if (!dist) { dist = getenv("LOGDIR"); if (!dist) rb_raise(rb_eArgError, "HOME/LOGDIR not set"); } + path = rb_str_new2(dist); } if (chdir_blocking > 0) { @@ -777,17 +782,15 @@ dir_s_chdir(argc, argv, obj) } if (rb_block_given_p()) { - char *cwd = my_getcwd(); struct chdir_data args; + char *cwd = my_getcwd(); - chdir_blocking++; - if (chdir_thread == Qnil) - chdir_thread = rb_thread_current(); - args.dist = dist; - args.path = path; - return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)cwd); + args.old_path = rb_tainted_str_new2(cwd); free(cwd); + args.new_path = path; + args.done = Qfalse; + return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args); } - dir_chdir(dist); + dir_chdir(path); return INT2FIX(0); } @@ -397,14 +397,17 @@ sort_by_i(i, ary) return Qnil; } -static int -sort_by_cmp(a, b) - VALUE *a, *b; +static VALUE +sort_by_cmp(values, ary) + 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]); - return rb_cmpint(retval, *a, *b); + /* pedantic check; they must be arrays */ + 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); 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++) { VALUE e = RARRAY(ary)->ptr[i]; @@ -9316,10 +9316,14 @@ Init_Binding() */ #define __libc_ia64_register_backing_store_base (4ULL<<61) #else +#ifdef HAVE_UNWIND_H +#include <unwind.h> +#else #pragma weak __libc_ia64_register_backing_store_base extern unsigned long __libc_ia64_register_backing_store_base; #endif #endif +#endif /* Windows SEH refers data on the stack. */ #undef SAVE_WIN32_EXCEPTION_LIST @@ -9779,19 +9783,24 @@ rb_thread_save_context(th) MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len); #ifdef __ia64__ { - ucontext_t ctx; VALUE *top, *bot; +#ifdef HAVE_UNWIND_H + _Unwind_Context *unwctx = _UNW_createContextForSelf(); + + _UNW_currentContext(unwctx); + bot = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSP); + top = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSPSTORE); + _UNW_destroyContext(unwctx); +#else + ucontext_t ctx; getcontext(&ctx); bot = (VALUE*)__libc_ia64_register_backing_store_base; -#if defined(__FreeBSD__) - top = (VALUE*)ctx.uc_mcontext.mc_special.bspstore; -#else - top = (VALUE*)ctx.uc_mcontext.sc_ar_bsp; + top = (VALUE*)ctx.uc_mcontext.IA64_BSPSTORE; #endif th->bstr_len = top - bot; REALLOC_N(th->bstr_ptr, VALUE, th->bstr_len); - MEMCPY(th->bstr_ptr, (VALUE*)__libc_ia64_register_backing_store_base, VALUE, th->bstr_len); + MEMCPY(th->bstr_ptr, bot, VALUE, th->bstr_len); } #endif #ifdef SAVE_WIN32_EXCEPTION_LIST @@ -9934,7 +9943,19 @@ rb_thread_restore_context(th, exit) FLUSH_REGISTER_WINDOWS; MEMCPY(tmp->stk_pos, tmp->stk_ptr, VALUE, tmp->stk_len); #ifdef __ia64__ - MEMCPY((VALUE*)__libc_ia64_register_backing_store_base, tmp->bstr_ptr, VALUE, tmp->bstr_len); + { + VALUE *base; +#ifdef HAVE_UNWIND_H + _Unwind_Context *unwctx = _UNW_createContextForSelf(); + + _UNW_currentContext(unwctx); + base = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSP); + _UNW_destroyContext(unwctx); +#else + base = (VALUE*)__libc_ia64_register_backing_store_base; +#endif + MEMCPY(base, tmp->bstr_ptr, VALUE, tmp->bstr_len); + } #endif tval = rb_lastline_get(); @@ -39,10 +39,14 @@ */ #define __libc_ia64_register_backing_store_base (4ULL<<61) #else +#ifdef HAVE_UNWIND_H +#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> @@ -610,6 +614,8 @@ mark_locations_array(x, n) register VALUE *x; register long n; { + VALUE tmp; + while (n--) { if (is_pointer_to_heap((void *)*x)) { gc_mark(*x, 0); @@ -1345,14 +1351,21 @@ rb_gc() { ucontext_t ctx; VALUE *top, *bot; +#ifdef HAVE_UNWIND_H + _Unwind_Context *unwctx = _UNW_createContextForSelf(); +#endif + getcontext(&ctx); mark_locations_array((VALUE*)&ctx.uc_mcontext, ((size_t)(sizeof(VALUE)-1 + sizeof ctx.uc_mcontext)/sizeof(VALUE))); - bot = (VALUE*)__libc_ia64_register_backing_store_base; -#if defined(__FreeBSD__) - top = (VALUE*)ctx.uc_mcontext.mc_special.bspstore; +#ifdef HAVE_UNWIND_H + _UNW_currentContext(unwctx); + bot = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSP); + top = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSPSTORE); + _UNW_destroyContext(unwctx); #else - top = (VALUE*)ctx.uc_mcontext.sc_ar_bsp; + bot = (VALUE*)__libc_ia64_register_backing_store_base; + top = (VALUE*)ctx.uc_mcontext.IA64_BSPSTORE; #endif rb_gc_mark_locations(bot, top); } @@ -131,9 +131,13 @@ rb_hash_foreach_iter(key, value, arg) if (key == Qundef) return ST_CONTINUE; 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"); } + if (RHASH(arg->hash)->iter_lev == 0) { + rb_raise(rb_eArgError, "block re-entered"); + } return status; } diff --git a/lib/delegate.rb b/lib/delegate.rb index 60d3afe151..5a97393239 100644 --- a/lib/delegate.rb +++ b/lib/delegate.rb @@ -92,7 +92,6 @@ def DelegateClass(superclass) @_dc_obj = obj end def method_missing(m, *args) - p [m, *args] unless @_dc_obj.respond_to?(m) super(m, *args) end @@ -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 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 ? \ - ((*cmp)(b,c)<0 ? b : ((*cmp)(a,c)<0 ? c : a)) : \ - ((*cmp)(b,c)>0 ? b : ((*cmp)(a,c)<0 ? a : c))) +#define med3(a,b,c) ((*cmp)(a,b,d)<0 ? \ + ((*cmp)(b,c,d)<0 ? b : ((*cmp)(a,c,d)<0 ? c : a)) : \ + ((*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; const int nel; const int size; int (*cmp)(); + void *d; { 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 */ @@ -495,7 +496,7 @@ void ruby_qsort (base, nel, size, cmp) for (;;) { start: 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; @@ -526,49 +527,49 @@ void ruby_qsort (base, nel, size, cmp) m = med3(m1, m, m3); } - if ((t = (*cmp)(l,m)) < 0) { /*3-5-?*/ - if ((t = (*cmp)(m,r)) < 0) { /*3-5-7*/ + if ((t = (*cmp)(l,m,d)) < 0) { /*3-5-?*/ + if ((t = (*cmp)(m,r,d)) < 0) { /*3-5-7*/ if (chklim && nel >= chklim) { /* check if already ascending order */ char *p; 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; } fail: goto loopA; /*3-5-7*/ } 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*/ } goto loopB; /*3-5-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 */ char *p; 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 */ goto nxt; } fail2: mmswap(l,r); goto loopA; /*7-5-3*/ } 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*/ } 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*/ /* 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; - 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*/ } @@ -578,14 +579,14 @@ void ruby_qsort (base, nel, size, cmp) if ((l += size) == r) {l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;} 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; } for (;;) { if (l == (r -= size)) {l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;} 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; } mmswap(l,r); /* swap left and right */ @@ -597,14 +598,14 @@ void ruby_qsort (base, nel, size, cmp) if (l == (r -= size)) {r += size; if (r != m) mmswap(r,m); r += size; goto fin;} 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; } for (;;) { if ((l += size) == r) {r += size; if (r != m) mmswap(r,m); r += size; goto fin;} 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; } mmswap(l,r); /* swap left and right */ @@ -43,8 +43,8 @@ unsigned long scan_hex _((const char*, int, int*)); void ruby_add_suffix(); #endif -void ruby_qsort _((void*, const int, const int, int (*)())); -#define qsort(b,n,s,c) ruby_qsort(b,n,s,c) +void ruby_qsort _((void*, const int, const int, int (*)(), void*)); +#define qsort(b,n,s,c,d) ruby_qsort(b,n,s,c,d) void ruby_setenv _((const char*, const char*)); void ruby_unsetenv _((const char*)); |