OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib-1.10.0/] [newlib/] [libc/] [stdlib/] [qsort.c] - Diff between revs 1010 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 1010 Rev 1765
/*
/*
FUNCTION
FUNCTION
<<qsort>>---sort an array
<<qsort>>---sort an array
 
 
INDEX
INDEX
        qsort
        qsort
 
 
ANSI_SYNOPSIS
ANSI_SYNOPSIS
        #include <stdlib.h>
        #include <stdlib.h>
        void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
        void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
                   int (*<[compar]>)(const void *, const void *) );
                   int (*<[compar]>)(const void *, const void *) );
 
 
TRAD_SYNOPSIS
TRAD_SYNOPSIS
        #include <stdlib.h>
        #include <stdlib.h>
        qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
        qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
        char *<[base]>;
        char *<[base]>;
        size_t <[nmemb]>;
        size_t <[nmemb]>;
        size_t <[size]>;
        size_t <[size]>;
        int (*<[compar]>)();
        int (*<[compar]>)();
 
 
DESCRIPTION
DESCRIPTION
<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
<[size]> describes the size of each element of the array.
<[size]> describes the size of each element of the array.
 
 
You must supply a pointer to a comparison function, using the argument
You must supply a pointer to a comparison function, using the argument
shown as <[compar]>.  (This permits sorting objects of unknown
shown as <[compar]>.  (This permits sorting objects of unknown
properties.)  Define the comparison function to accept two arguments,
properties.)  Define the comparison function to accept two arguments,
each a pointer to an element of the array starting at <[base]>.  The
each a pointer to an element of the array starting at <[base]>.  The
result of <<(*<[compar]>)>> must be negative if the first argument is
result of <<(*<[compar]>)>> must be negative if the first argument is
less than the second, zero if the two arguments match, and positive if
less than the second, zero if the two arguments match, and positive if
the first argument is greater than the second (where ``less than'' and
the first argument is greater than the second (where ``less than'' and
``greater than'' refer to whatever arbitrary ordering is appropriate).
``greater than'' refer to whatever arbitrary ordering is appropriate).
 
 
The array is sorted in place; that is, when <<qsort>> returns, the
The array is sorted in place; that is, when <<qsort>> returns, the
array elements beginning at <[base]> have been reordered.
array elements beginning at <[base]> have been reordered.
 
 
RETURNS
RETURNS
<<qsort>> does not return a result.
<<qsort>> does not return a result.
 
 
PORTABILITY
PORTABILITY
<<qsort>> is required by ANSI (without specifying the sorting algorithm).
<<qsort>> is required by ANSI (without specifying the sorting algorithm).
*/
*/
 
 
/*-
/*-
 * Copyright (c) 1992, 1993
 * Copyright (c) 1992, 1993
 *      The Regents of the University of California.  All rights reserved.
 *      The Regents of the University of California.  All rights reserved.
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * modification, are permitted provided that the following conditions
 * are met:
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *    without specific prior written permission.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * SUCH DAMAGE.
 */
 */
 
 
#include <_ansi.h>
#include <_ansi.h>
#include <stdlib.h>
#include <stdlib.h>
 
 
#ifndef __GNUC__
#ifndef __GNUC__
#define inline
#define inline
#endif
#endif
 
 
static inline char      *med3 _PARAMS((char *, char *, char *, int (*)()));
static inline char      *med3 _PARAMS((char *, char *, char *, int (*)()));
static inline void       swapfunc _PARAMS((char *, char *, int, int));
static inline void       swapfunc _PARAMS((char *, char *, int, int));
 
 
#define min(a, b)       (a) < (b) ? a : b
#define min(a, b)       (a) < (b) ? a : b
 
 
/*
/*
 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
 */
 */
#define swapcode(TYPE, parmi, parmj, n) {               \
#define swapcode(TYPE, parmi, parmj, n) {               \
        long i = (n) / sizeof (TYPE);                   \
        long i = (n) / sizeof (TYPE);                   \
        register TYPE *pi = (TYPE *) (parmi);           \
        register TYPE *pi = (TYPE *) (parmi);           \
        register TYPE *pj = (TYPE *) (parmj);           \
        register TYPE *pj = (TYPE *) (parmj);           \
        do {                                            \
        do {                                            \
                register TYPE   t = *pi;                \
                register TYPE   t = *pi;                \
                *pi++ = *pj;                            \
                *pi++ = *pj;                            \
                *pj++ = t;                              \
                *pj++ = t;                              \
        } while (--i > 0);                               \
        } while (--i > 0);                               \
}
}
 
 
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
        es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
        es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
 
 
static inline void
static inline void
_DEFUN(swapfunc, (a, b, n, swaptype),
_DEFUN(swapfunc, (a, b, n, swaptype),
        char *a _AND
        char *a _AND
        char *b _AND
        char *b _AND
        int n _AND
        int n _AND
        int swaptype)
        int swaptype)
{
{
        if(swaptype <= 1)
        if(swaptype <= 1)
                swapcode(long, a, b, n)
                swapcode(long, a, b, n)
        else
        else
                swapcode(char, a, b, n)
                swapcode(char, a, b, n)
}
}
 
 
#define swap(a, b)                                      \
#define swap(a, b)                                      \
        if (swaptype == 0) {                             \
        if (swaptype == 0) {                             \
                long t = *(long *)(a);                  \
                long t = *(long *)(a);                  \
                *(long *)(a) = *(long *)(b);            \
                *(long *)(a) = *(long *)(b);            \
                *(long *)(b) = t;                       \
                *(long *)(b) = t;                       \
        } else                                          \
        } else                                          \
                swapfunc(a, b, es, swaptype)
                swapfunc(a, b, es, swaptype)
 
 
#define vecswap(a, b, n)        if ((n) > 0) swapfunc(a, b, n, swaptype)
#define vecswap(a, b, n)        if ((n) > 0) swapfunc(a, b, n, swaptype)
 
 
static inline char *
static inline char *
_DEFUN(med3, (a, b, c, cmp),
_DEFUN(med3, (a, b, c, cmp),
        char *a _AND
        char *a _AND
        char *b _AND
        char *b _AND
        char *c _AND
        char *c _AND
        int (*cmp)())
        int (*cmp)())
{
{
        return cmp(a, b) < 0 ?
        return cmp(a, b) < 0 ?
               (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
               (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
}
}
 
 
void
void
_DEFUN(qsort, (a, n, es, cmp),
_DEFUN(qsort, (a, n, es, cmp),
        void *a _AND
        void *a _AND
        size_t n _AND
        size_t n _AND
        size_t es _AND
        size_t es _AND
        int (*cmp)())
        int (*cmp)())
{
{
        char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
        char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
        int d, r, swaptype, swap_cnt;
        int d, r, swaptype, swap_cnt;
 
 
loop:   SWAPINIT(a, es);
loop:   SWAPINIT(a, es);
        swap_cnt = 0;
        swap_cnt = 0;
        if (n < 7) {
        if (n < 7) {
                for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
                for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
                        for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
                        for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
                             pl -= es)
                             pl -= es)
                                swap(pl, pl - es);
                                swap(pl, pl - es);
                return;
                return;
        }
        }
        pm = (char *) a + (n / 2) * es;
        pm = (char *) a + (n / 2) * es;
        if (n > 7) {
        if (n > 7) {
                pl = a;
                pl = a;
                pn = (char *) a + (n - 1) * es;
                pn = (char *) a + (n - 1) * es;
                if (n > 40) {
                if (n > 40) {
                        d = (n / 8) * es;
                        d = (n / 8) * es;
                        pl = med3(pl, pl + d, pl + 2 * d, cmp);
                        pl = med3(pl, pl + d, pl + 2 * d, cmp);
                        pm = med3(pm - d, pm, pm + d, cmp);
                        pm = med3(pm - d, pm, pm + d, cmp);
                        pn = med3(pn - 2 * d, pn - d, pn, cmp);
                        pn = med3(pn - 2 * d, pn - d, pn, cmp);
                }
                }
                pm = med3(pl, pm, pn, cmp);
                pm = med3(pl, pm, pn, cmp);
        }
        }
        swap(a, pm);
        swap(a, pm);
        pa = pb = (char *) a + es;
        pa = pb = (char *) a + es;
 
 
        pc = pd = (char *) a + (n - 1) * es;
        pc = pd = (char *) a + (n - 1) * es;
        for (;;) {
        for (;;) {
                while (pb <= pc && (r = cmp(pb, a)) <= 0) {
                while (pb <= pc && (r = cmp(pb, a)) <= 0) {
                        if (r == 0) {
                        if (r == 0) {
                                swap_cnt = 1;
                                swap_cnt = 1;
                                swap(pa, pb);
                                swap(pa, pb);
                                pa += es;
                                pa += es;
                        }
                        }
                        pb += es;
                        pb += es;
                }
                }
                while (pb <= pc && (r = cmp(pc, a)) >= 0) {
                while (pb <= pc && (r = cmp(pc, a)) >= 0) {
                        if (r == 0) {
                        if (r == 0) {
                                swap_cnt = 1;
                                swap_cnt = 1;
                                swap(pc, pd);
                                swap(pc, pd);
                                pd -= es;
                                pd -= es;
                        }
                        }
                        pc -= es;
                        pc -= es;
                }
                }
                if (pb > pc)
                if (pb > pc)
                        break;
                        break;
                swap(pb, pc);
                swap(pb, pc);
                swap_cnt = 1;
                swap_cnt = 1;
                pb += es;
                pb += es;
                pc -= es;
                pc -= es;
        }
        }
        if (swap_cnt == 0) {  /* Switch to insertion sort */
        if (swap_cnt == 0) {  /* Switch to insertion sort */
                for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
                for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
                        for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
                        for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
                             pl -= es)
                             pl -= es)
                                swap(pl, pl - es);
                                swap(pl, pl - es);
                return;
                return;
        }
        }
 
 
        pn = (char *) a + n * es;
        pn = (char *) a + n * es;
        r = min(pa - (char *)a, pb - pa);
        r = min(pa - (char *)a, pb - pa);
        vecswap(a, pb - r, r);
        vecswap(a, pb - r, r);
        r = min(pd - pc, pn - pd - es);
        r = min(pd - pc, pn - pd - es);
        vecswap(pb, pn - r, r);
        vecswap(pb, pn - r, r);
        if ((r = pb - pa) > es)
        if ((r = pb - pa) > es)
                qsort(a, r / es, es, cmp);
                qsort(a, r / es, es, cmp);
        if ((r = pd - pc) > es) {
        if ((r = pd - pc) > es) {
                /* Iterate rather than recurse to save stack space */
                /* Iterate rather than recurse to save stack space */
                a = pn - r;
                a = pn - r;
                n = r / es;
                n = r / es;
                goto loop;
                goto loop;
        }
        }
/*              qsort(pn - r, r / es, es, cmp);*/
/*              qsort(pn - r, r / es, es, cmp);*/
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.