2007-03-07 23:13:04 +00:00
|
|
|
/* Copyright (C) 1999,2000,2001,2002, 2004, 2006, 2007 Free Software Foundation, Inc.
|
2003-04-05 19:15:35 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
1999-01-10 07:57:58 +00:00
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
1999-01-10 07:57:58 +00:00
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2005-05-23 19:57:22 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2003-04-05 19:15:35 +00:00
|
|
|
*/
|
1999-01-10 07:57:58 +00:00
|
|
|
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* Written in December 1998 by Roland Orre <orre@nada.kth.se>
|
|
|
|
|
* This implements the same sort interface as slib/sort.scm
|
|
|
|
|
* for lists and vectors where slib defines:
|
|
|
|
|
* sorted?, merge, merge!, sort, sort!
|
1999-08-20 00:19:01 +00:00
|
|
|
* For scsh compatibility sort-list and sort-list! are also defined.
|
1999-01-10 07:57:58 +00:00
|
|
|
* In cases where a stable-sort is required use stable-sort or
|
1999-08-20 00:19:01 +00:00
|
|
|
* stable-sort!. An additional feature is
|
1999-01-10 07:57:58 +00:00
|
|
|
* (restricted-vector-sort! vector less? startpos endpos)
|
1999-08-20 00:19:01 +00:00
|
|
|
* which allows you to sort part of a vector.
|
1999-01-10 07:57:58 +00:00
|
|
|
* Thanks to Aubrey Jaffer for the slib/sort.scm library.
|
|
|
|
|
* Thanks to Richard A. O'Keefe (based on Prolog code by D.H.D.Warren)
|
|
|
|
|
* for the merge sort inspiration.
|
|
|
|
|
* Thanks to Douglas C. Schmidt (schmidt@ics.uci.edu) for the
|
|
|
|
|
* quicksort code.
|
|
|
|
|
*/
|
|
|
|
|
|
2000-04-21 14:16:44 +00:00
|
|
|
#include "libguile/_scm.h"
|
|
|
|
|
#include "libguile/eval.h"
|
|
|
|
|
#include "libguile/unif.h"
|
|
|
|
|
#include "libguile/ramap.h"
|
|
|
|
|
#include "libguile/feature.h"
|
|
|
|
|
#include "libguile/vectors.h"
|
2002-01-22 23:31:39 +00:00
|
|
|
#include "libguile/lang.h"
|
2004-10-22 13:17:04 +00:00
|
|
|
#include "libguile/async.h"
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
#include "libguile/dynwind.h"
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2000-04-21 14:16:44 +00:00
|
|
|
#include "libguile/validate.h"
|
|
|
|
|
#include "libguile/sort.h"
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
/* We have two quicksort variants: one for contigous vectors and one
|
|
|
|
|
for vectors with arbitrary increments between elements. Note that
|
|
|
|
|
increments can be negative.
|
|
|
|
|
*/
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
#define NAME quicksort1
|
|
|
|
|
#define INC_PARAM /* empty */
|
|
|
|
|
#define INC 1
|
|
|
|
|
#include "libguile/quicksort.i.c"
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
#define NAME quicksort
|
|
|
|
|
#define INC_PARAM ssize_t inc,
|
|
|
|
|
#define INC inc
|
|
|
|
|
#include "libguile/quicksort.i.c"
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
static scm_t_trampoline_2
|
|
|
|
|
compare_function (SCM less, unsigned int arg_nr, const char* fname)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = scm_trampoline_2 (less);
|
|
|
|
|
SCM_ASSERT_TYPE (cmp != NULL, less, arg_nr, fname, "less predicate");
|
|
|
|
|
return cmp;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_restricted_vector_sort_x, "restricted-vector-sort!", 4, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM vec, SCM less, SCM startpos, SCM endpos),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the vector @var{vec}, using @var{less} for comparing\n"
|
2004-10-19 15:58:49 +00:00
|
|
|
"the vector elements. @var{startpos} (inclusively) and\n"
|
|
|
|
|
"@var{endpos} (exclusively) delimit\n"
|
2001-01-30 14:53:20 +00:00
|
|
|
"the range of the vector which gets sorted. The return value\n"
|
|
|
|
|
"is not specified.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_restricted_vector_sort_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
size_t vlen, spos, len;
|
|
|
|
|
ssize_t vinc;
|
|
|
|
|
scm_t_array_handle handle;
|
|
|
|
|
SCM *velts;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
velts = scm_vector_writable_elements (vec, &handle, &vlen, &vinc);
|
* validate.h, deprecated.h (SCM_VALIDATE_INUM, SCM_VALIDATE_INUM_COPY,
SCM_VALIDATE_BIGINT, SCM_VALIDATE_INUM_MIN,
SCM_VALIDATE_INUM_MIN_COPY,
SCM_VALIDATE_INUM_MIN_DEF_COPY,SCM_VALIDATE_INUM_DEF,
SCM_VALIDATE_INUM_DEF_COPY, SCM_VALIDATE_INUM_RANGE,
SCM_VALIDATE_INUM_RANGE_COPY): Deprecated because they make the
fixnum/bignum distinction visible. Changed all uses to scm_to_size_t
or similar.
2004-07-10 14:35:36 +00:00
|
|
|
spos = scm_to_unsigned_integer (startpos, 0, vlen);
|
2004-10-19 15:58:49 +00:00
|
|
|
len = scm_to_unsigned_integer (endpos, spos, vlen) - spos;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
if (vinc == 1)
|
|
|
|
|
quicksort1 (velts + spos*vinc, len, cmp, less);
|
|
|
|
|
else
|
|
|
|
|
quicksort (velts + spos*vinc, len, vinc, cmp, less);
|
|
|
|
|
|
2005-01-06 18:56:34 +00:00
|
|
|
scm_array_handle_release (&handle);
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return SCM_UNSPECIFIED;
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* (sorted? sequence less?)
|
|
|
|
|
* is true when sequence is a list (x0 x1 ... xm) or a vector #(x0 ... xm)
|
|
|
|
|
* such that for all 1 <= i <= m,
|
|
|
|
|
* (not (less? (list-ref list i) (list-ref list (- i 1)))). */
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sorted_p, "sorted?", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Return @code{#t} iff @var{items} is a list or a vector such that\n"
|
|
|
|
|
"for all 1 <= i <= m, the predicate @var{less} returns true when\n"
|
|
|
|
|
"applied to all elements i - 1 and i")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sorted_p
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len, j; /* list/vector length, temp j */
|
1999-01-10 07:57:58 +00:00
|
|
|
SCM item, rest; /* rest of items loop variable */
|
|
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
1999-01-10 07:57:58 +00:00
|
|
|
return SCM_BOOL_T;
|
1999-12-12 02:36:16 +00:00
|
|
|
|
2004-09-22 17:41:37 +00:00
|
|
|
if (scm_is_pair (items))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
len = scm_ilength (items); /* also checks that it's a pure list */
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_ASSERT_RANGE (1, items, len >= 0);
|
1999-01-10 07:57:58 +00:00
|
|
|
if (len <= 1)
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
|
|
|
|
item = SCM_CAR (items);
|
|
|
|
|
rest = SCM_CDR (items);
|
|
|
|
|
j = len - 1;
|
|
|
|
|
while (j > 0)
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (rest), item)))
|
1999-01-10 07:57:58 +00:00
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
item = SCM_CAR (rest);
|
|
|
|
|
rest = SCM_CDR (rest);
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
scm_t_array_handle handle;
|
|
|
|
|
size_t i, len;
|
|
|
|
|
ssize_t inc;
|
|
|
|
|
const SCM *elts;
|
|
|
|
|
SCM result = SCM_BOOL_T;
|
2000-10-10 09:22:31 +00:00
|
|
|
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
elts = scm_vector_elements (items, &handle, &len, &inc);
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < len; i++, elts += inc)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, elts[inc], elts[0])))
|
2000-10-10 09:22:31 +00:00
|
|
|
{
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
result = SCM_BOOL_F;
|
|
|
|
|
break;
|
2000-10-10 09:22:31 +00:00
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
|
2005-01-06 18:56:34 +00:00
|
|
|
scm_array_handle_release (&handle);
|
|
|
|
|
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
return result;
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
2000-10-10 09:22:31 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
return SCM_BOOL_F;
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* (merge a b less?)
|
|
|
|
|
takes two lists a and b such that (sorted? a less?) and (sorted? b less?)
|
|
|
|
|
and returns a new list in which the elements of a and b have been stably
|
|
|
|
|
interleaved so that (sorted? (merge a b less?) less?).
|
|
|
|
|
Note: this does _not_ accept vectors. */
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_merge, "merge", 3, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM alist, SCM blist, SCM less),
|
2001-11-16 15:04:17 +00:00
|
|
|
"Merge two already sorted lists into one.\n"
|
|
|
|
|
"Given two lists @var{alist} and @var{blist}, such that\n"
|
|
|
|
|
"@code{(sorted? alist less?)} and @code{(sorted? blist less?)},\n"
|
|
|
|
|
"return a new list in which the elements of @var{alist} and\n"
|
2001-01-30 14:53:20 +00:00
|
|
|
"@var{blist} have been stably interleaved so that\n"
|
|
|
|
|
"@code{(sorted? (merge alist blist less?) less?)}.\n"
|
|
|
|
|
"Note: this does _not_ accept vectors.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_merge
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
SCM build;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (alist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return blist;
|
2002-01-22 23:31:39 +00:00
|
|
|
else if (SCM_NULL_OR_NIL_P (blist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return alist;
|
|
|
|
|
else
|
|
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 3, FUNC_NAME);
|
|
|
|
|
long alen, blen; /* list lengths */
|
|
|
|
|
SCM last;
|
|
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_NONEMPTYLIST_COPYLEN (1, alist, alen);
|
|
|
|
|
SCM_VALIDATE_NONEMPTYLIST_COPYLEN (2, blist, blen);
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (blist), SCM_CAR (alist))))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
build = scm_cons (SCM_CAR (blist), SCM_EOL);
|
|
|
|
|
blist = SCM_CDR (blist);
|
|
|
|
|
blen--;
|
|
|
|
|
}
|
1999-01-11 11:34:33 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
build = scm_cons (SCM_CAR (alist), SCM_EOL);
|
|
|
|
|
alist = SCM_CDR (alist);
|
|
|
|
|
alen--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
last = build;
|
|
|
|
|
while ((alen > 0) && (blen > 0))
|
|
|
|
|
{
|
2004-10-22 13:17:04 +00:00
|
|
|
SCM_TICK;
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (blist), SCM_CAR (alist))))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
SCM_SETCDR (last, scm_cons (SCM_CAR (blist), SCM_EOL));
|
|
|
|
|
blist = SCM_CDR (blist);
|
|
|
|
|
blen--;
|
|
|
|
|
}
|
1999-01-11 11:34:33 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SCM_SETCDR (last, scm_cons (SCM_CAR (alist), SCM_EOL));
|
|
|
|
|
alist = SCM_CDR (alist);
|
|
|
|
|
alen--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
last = SCM_CDR (last);
|
|
|
|
|
}
|
|
|
|
|
if ((alen > 0) && (blen == 0))
|
|
|
|
|
SCM_SETCDR (last, alist);
|
|
|
|
|
else if ((alen == 0) && (blen > 0))
|
|
|
|
|
SCM_SETCDR (last, blist);
|
|
|
|
|
}
|
|
|
|
|
return build;
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
scm_merge_list_x (SCM alist, SCM blist,
|
|
|
|
|
long alen, long blen,
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_t_trampoline_2 cmp, SCM less)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
SCM build, last;
|
|
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (alist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return blist;
|
2002-01-22 23:31:39 +00:00
|
|
|
else if (SCM_NULL_OR_NIL_P (blist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return alist;
|
|
|
|
|
else
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (blist), SCM_CAR (alist))))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
build = blist;
|
|
|
|
|
blist = SCM_CDR (blist);
|
|
|
|
|
blen--;
|
|
|
|
|
}
|
1999-01-11 11:34:33 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
build = alist;
|
|
|
|
|
alist = SCM_CDR (alist);
|
|
|
|
|
alen--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
last = build;
|
|
|
|
|
while ((alen > 0) && (blen > 0))
|
|
|
|
|
{
|
2004-10-22 13:17:04 +00:00
|
|
|
SCM_TICK;
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (blist), SCM_CAR (alist))))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
SCM_SETCDR (last, blist);
|
|
|
|
|
blist = SCM_CDR (blist);
|
|
|
|
|
blen--;
|
|
|
|
|
}
|
1999-01-11 11:34:33 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SCM_SETCDR (last, alist);
|
|
|
|
|
alist = SCM_CDR (alist);
|
|
|
|
|
alen--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
last = SCM_CDR (last);
|
|
|
|
|
}
|
|
|
|
|
if ((alen > 0) && (blen == 0))
|
|
|
|
|
SCM_SETCDR (last, alist);
|
|
|
|
|
else if ((alen == 0) && (blen > 0))
|
|
|
|
|
SCM_SETCDR (last, blist);
|
|
|
|
|
}
|
|
|
|
|
return build;
|
|
|
|
|
} /* scm_merge_list_x */
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_merge_x, "merge!", 3, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM alist, SCM blist, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Takes two lists @var{alist} and @var{blist} such that\n"
|
|
|
|
|
"@code{(sorted? alist less?)} and @code{(sorted? blist less?)} and\n"
|
|
|
|
|
"returns a new list in which the elements of @var{alist} and\n"
|
|
|
|
|
"@var{blist} have been stably interleaved so that\n"
|
|
|
|
|
" @code{(sorted? (merge alist blist less?) less?)}.\n"
|
|
|
|
|
"This is the destructive variant of @code{merge}\n"
|
|
|
|
|
"Note: this does _not_ accept vectors.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_merge_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (alist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return blist;
|
2002-01-22 23:31:39 +00:00
|
|
|
else if (SCM_NULL_OR_NIL_P (blist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return alist;
|
|
|
|
|
else
|
|
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 3, FUNC_NAME);
|
|
|
|
|
long alen, blen; /* list lengths */
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_NONEMPTYLIST_COPYLEN (1, alist, alen);
|
|
|
|
|
SCM_VALIDATE_NONEMPTYLIST_COPYLEN (2, blist, blen);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_x (alist, blist, alen, blen, cmp, less);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* This merge sort algorithm is same as slib's by Richard A. O'Keefe.
|
|
|
|
|
The algorithm is stable. We also tried to use the algorithm used by
|
|
|
|
|
scsh's merge-sort but that algorithm showed to not be stable, even
|
|
|
|
|
though it claimed to be.
|
|
|
|
|
*/
|
|
|
|
|
static SCM
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_merge_list_step (SCM * seq, scm_t_trampoline_2 cmp, SCM less, long n)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
1999-01-11 11:34:33 +00:00
|
|
|
SCM a, b;
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
if (n > 2)
|
|
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
long mid = n / 2;
|
2004-10-22 13:17:04 +00:00
|
|
|
SCM_TICK;
|
1999-01-11 11:34:33 +00:00
|
|
|
a = scm_merge_list_step (seq, cmp, less, mid);
|
|
|
|
|
b = scm_merge_list_step (seq, cmp, less, n - mid);
|
|
|
|
|
return scm_merge_list_x (a, b, mid, n - mid, cmp, less);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
else if (n == 2)
|
|
|
|
|
{
|
|
|
|
|
SCM p = *seq;
|
|
|
|
|
SCM rest = SCM_CDR (*seq);
|
|
|
|
|
SCM x = SCM_CAR (*seq);
|
|
|
|
|
SCM y = SCM_CAR (SCM_CDR (*seq));
|
|
|
|
|
*seq = SCM_CDR (rest);
|
|
|
|
|
SCM_SETCDR (rest, SCM_EOL);
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, y, x)))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2000-06-05 12:09:35 +00:00
|
|
|
SCM_SETCAR (p, y);
|
|
|
|
|
SCM_SETCAR (rest, x);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
else if (n == 1)
|
|
|
|
|
{
|
|
|
|
|
SCM p = *seq;
|
|
|
|
|
*seq = SCM_CDR (p);
|
|
|
|
|
SCM_SETCDR (p, SCM_EOL);
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return SCM_EOL;
|
|
|
|
|
} /* scm_merge_list_step */
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sort_x, "sort!", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the sequence @var{items}, which may be a list or a\n"
|
|
|
|
|
"vector. @var{less} is used for comparing the sequence\n"
|
|
|
|
|
"elements. The sorting is destructive, that means that the\n"
|
|
|
|
|
"input sequence is modified to produce the sorted result.\n"
|
|
|
|
|
"This is not a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sort_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
long len; /* list/vector length */
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
|
|
|
|
return items;
|
2000-10-10 09:22:31 +00:00
|
|
|
|
2004-09-22 17:41:37 +00:00
|
|
|
if (scm_is_pair (items))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
else if (scm_is_vector (items))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
scm_restricted_vector_sort_x (items,
|
|
|
|
|
less,
|
2004-07-23 15:43:02 +00:00
|
|
|
scm_from_int (0),
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
scm_vector_length (items));
|
1999-01-10 07:57:58 +00:00
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
else
|
2001-03-04 22:48:13 +00:00
|
|
|
SCM_WRONG_TYPE_ARG (1, items);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
1999-12-12 02:36:16 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sort, "sort", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the sequence @var{items}, which may be a list or a\n"
|
|
|
|
|
"vector. @var{less} is used for comparing the sequence\n"
|
|
|
|
|
"elements. This is not a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sort
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
|
|
|
|
return items;
|
2000-10-10 09:22:31 +00:00
|
|
|
|
2004-09-22 17:41:37 +00:00
|
|
|
if (scm_is_pair (items))
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
return scm_sort_x (scm_list_copy (items), less);
|
|
|
|
|
else if (scm_is_vector (items))
|
|
|
|
|
return scm_sort_x (scm_vector_copy (items), less);
|
1999-01-10 07:57:58 +00:00
|
|
|
else
|
2001-03-04 22:48:13 +00:00
|
|
|
SCM_WRONG_TYPE_ARG (1, items);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
static void
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
scm_merge_vector_x (SCM *vec,
|
|
|
|
|
SCM *temp,
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_t_trampoline_2 cmp,
|
1999-01-10 07:57:58 +00:00
|
|
|
SCM less,
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
size_t low,
|
|
|
|
|
size_t mid,
|
|
|
|
|
size_t high,
|
|
|
|
|
ssize_t inc)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
size_t it; /* Index for temp vector */
|
|
|
|
|
size_t i1 = low; /* Index for lower vector segment */
|
|
|
|
|
size_t i2 = mid + 1; /* Index for upper vector segment */
|
|
|
|
|
|
|
|
|
|
#define VEC(i) vec[(i)*inc]
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
/* Copy while both segments contain more characters */
|
|
|
|
|
for (it = low; (i1 <= mid) && (i2 <= high); ++it)
|
2002-07-21 17:46:23 +00:00
|
|
|
{
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, VEC(i2), VEC(i1))))
|
|
|
|
|
temp[it] = VEC(i2++);
|
2002-07-21 17:46:23 +00:00
|
|
|
else
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
temp[it] = VEC(i1++);
|
2002-07-21 17:46:23 +00:00
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2002-07-21 17:46:23 +00:00
|
|
|
{
|
|
|
|
|
/* Copy while first segment contains more characters */
|
|
|
|
|
while (i1 <= mid)
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
temp[it++] = VEC(i1++);
|
2002-07-21 17:46:23 +00:00
|
|
|
|
|
|
|
|
/* Copy while second segment contains more characters */
|
|
|
|
|
while (i2 <= high)
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
temp[it++] = VEC(i2++);
|
2002-07-21 17:46:23 +00:00
|
|
|
|
|
|
|
|
/* Copy back from temp to vp */
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
for (it = low; it <= high; it++)
|
|
|
|
|
VEC(it) = temp[it];
|
2002-07-21 17:46:23 +00:00
|
|
|
}
|
|
|
|
|
} /* scm_merge_vector_x */
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
static void
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
scm_merge_vector_step (SCM *vec,
|
|
|
|
|
SCM *temp,
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_t_trampoline_2 cmp,
|
1999-01-10 07:57:58 +00:00
|
|
|
SCM less,
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
size_t low,
|
|
|
|
|
size_t high,
|
|
|
|
|
ssize_t inc)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
if (high > low)
|
|
|
|
|
{
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
size_t mid = (low + high) / 2;
|
2004-10-22 13:17:04 +00:00
|
|
|
SCM_TICK;
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
scm_merge_vector_step (vec, temp, cmp, less, low, mid, inc);
|
|
|
|
|
scm_merge_vector_step (vec, temp, cmp, less, mid+1, high, inc);
|
|
|
|
|
scm_merge_vector_x (vec, temp, cmp, less, low, mid, high, inc);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
} /* scm_merge_vector_step */
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_stable_sort_x, "stable-sort!", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the sequence @var{items}, which may be a list or a\n"
|
|
|
|
|
"vector. @var{less} is used for comparing the sequence elements.\n"
|
|
|
|
|
"The sorting is destructive, that means that the input sequence\n"
|
|
|
|
|
"is modified to produce the sorted result.\n"
|
|
|
|
|
"This is a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_stable_sort_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len; /* list/vector length */
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
|
|
|
|
return items;
|
2000-10-10 09:22:31 +00:00
|
|
|
|
2004-09-22 17:41:37 +00:00
|
|
|
if (scm_is_pair (items))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
else if (scm_is_vector (items))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
scm_t_array_handle temp_handle, vec_handle;
|
|
|
|
|
SCM temp, *temp_elts, *vec_elts;
|
|
|
|
|
size_t len;
|
|
|
|
|
ssize_t inc;
|
|
|
|
|
|
|
|
|
|
vec_elts = scm_vector_writable_elements (items, &vec_handle,
|
|
|
|
|
&len, &inc);
|
|
|
|
|
temp = scm_c_make_vector (len, SCM_UNDEFINED);
|
|
|
|
|
temp_elts = scm_vector_writable_elements (temp, &temp_handle,
|
|
|
|
|
NULL, NULL);
|
2002-07-20 14:08:34 +00:00
|
|
|
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
scm_merge_vector_step (vec_elts, temp_elts, cmp, less, 0, len-1, inc);
|
2002-07-20 14:08:34 +00:00
|
|
|
|
2005-01-06 18:56:34 +00:00
|
|
|
scm_array_handle_release (&temp_handle);
|
|
|
|
|
scm_array_handle_release (&vec_handle);
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
else
|
2001-03-04 22:48:13 +00:00
|
|
|
SCM_WRONG_TYPE_ARG (1, items);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_stable_sort, "stable-sort", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the sequence @var{items}, which may be a list or a\n"
|
|
|
|
|
"vector. @var{less} is used for comparing the sequence elements.\n"
|
|
|
|
|
"This is a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_stable_sort
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2007-03-07 23:12:36 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
|
|
|
|
return SCM_EOL;
|
|
|
|
|
|
2004-09-22 17:41:37 +00:00
|
|
|
if (scm_is_pair (items))
|
* sort.c (quicksort): Added INC parameter for non-contigous
vectors.
(quicksort1): New, for contigous vectors. Both functions are
generated from the same code by including "quicksort.i.c".
(scm_restricted_vector_sort_x): Call one of quicksort and
quicksort1, depending on increment of vector.
(scm_sort): Simply call scm_sort_x on a copy of the list or
vector.
(scm_merge_vector_x, scm_merge_vector_step): Changed indices to
size_t, added inc parameter.
(scm_stable_sort_x): Allocate temporary storage as Scheme vector
so that it doesn't leak.
(scm_stable_sort): Simply call scm_stable_sort_x on a copy of the
list or vector.
* tags.h, weaks.c, vports.c, hashtab.c, convert.c, sort.c: Use new
vector elements API or simple vector API, as appropriate. Removed
SCM_HAVE_ARRAYS ifdefery. Replaced all uses of
SCM_HASHTABLE_BUCKETS with SCM_HASHTABLE_BUCKET.
2005-01-02 20:45:07 +00:00
|
|
|
return scm_stable_sort_x (scm_list_copy (items), less);
|
|
|
|
|
else if (scm_is_vector (items))
|
|
|
|
|
return scm_stable_sort_x (scm_vector_copy (items), less);
|
1999-01-10 07:57:58 +00:00
|
|
|
else
|
2001-03-04 22:48:13 +00:00
|
|
|
SCM_WRONG_TYPE_ARG (1, items);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sort_list_x, "sort-list!", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the list @var{items}, using @var{less} for comparing the\n"
|
|
|
|
|
"list elements. The sorting is destructive, that means that the\n"
|
|
|
|
|
"input list is modified to produce the sorted result.\n"
|
|
|
|
|
"This is a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sort_list_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len;
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sort_list, "sort-list", 2, 0, 0,
|
2001-01-30 14:53:20 +00:00
|
|
|
(SCM items, SCM less),
|
|
|
|
|
"Sort the list @var{items}, using @var{less} for comparing the\n"
|
|
|
|
|
"list elements. This is a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sort_list
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len;
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
items = scm_list_copy (items);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
void
|
|
|
|
|
scm_init_sort ()
|
|
|
|
|
{
|
2000-04-21 14:16:44 +00:00
|
|
|
#include "libguile/sort.x"
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
scm_add_feature ("sort");
|
|
|
|
|
}
|
2000-03-19 19:01:16 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Local Variables:
|
|
|
|
|
c-file-style: "gnu"
|
|
|
|
|
End:
|
|
|
|
|
*/
|