1
0
Fork 0
forked from nuttx/nuttx-update

Make coding style more conformant, take description from OpenGroup.org, rename formal parameters to match names used on OpenGroup.org

This commit is contained in:
Gregory Nutt 2015-10-02 12:58:40 -06:00
parent 2ba224eca2
commit 38e6142ae8
4 changed files with 109 additions and 49 deletions

View file

@ -11008,3 +11008,6 @@
* libc/stdlib/lib_bsearch.c and include/stdlib.h: Add the bsearch() * libc/stdlib/lib_bsearch.c and include/stdlib.h: Add the bsearch()
function from NetBSD (2015-10-02). function from NetBSD (2015-10-02).
* libc/stdlib/lib_qsort.c and include/stdlib.h: Make coding style
more conformant, take description from OpenGroup.org, rename formal
parameters to match names used on OpenGroup.org (2015-10-02).

View file

@ -229,7 +229,7 @@ int mkstemp(FAR char *path_template);
/* Sorting */ /* Sorting */
void qsort(FAR void *base, size_t nmemb, size_t size, void qsort(FAR void *base, size_t nel, size_t width,
int (*compar)(FAR const void *, FAR const void *)); int (*compar)(FAR const void *, FAR const void *));
/* Binary search */ /* Binary search */

View file

@ -49,8 +49,6 @@
* Name: bsearch * Name: bsearch
* *
* Description: * Description:
* Per OpenGroup.org:
*
* The bsearch() function will search an array of nel objects, the initial * The bsearch() function will search an array of nel objects, the initial
* element of which is pointed to by 'base', for an element that matches * element of which is pointed to by 'base', for an element that matches
* the object pointed to by 'key'. The size of each element in the array * the object pointed to by 'key'. The size of each element in the array
@ -83,6 +81,8 @@
* equal to, and all the elements that compare greater than the key * equal to, and all the elements that compare greater than the key
* object, in that order. * object, in that order.
* *
* (Based on description from OpenGroup.org).
*
* Returned Value: * Returned Value:
* The bsearch() function will return a pointer to a matching member of * The bsearch() function will return a pointer to a matching member of
* the array, or a null pointer if no match is found. If two or more * the array, or a null pointer if no match is found. If two or more

View file

@ -58,8 +58,8 @@
#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; \
@ -67,9 +67,9 @@
} while (--i > 0); \ } while (--i > 0); \
} }
#define SWAPINIT(a, size) \ #define SWAPINIT(a, width) \
swaptype = ((char *)a - (char *)0) % sizeof(long) || \ swaptype = ((FAR char *)a - (FAR char *)0) % sizeof(long) || \
size % sizeof(long) ? 2 : size == sizeof(long)? 0 : 1; width % sizeof(long) ? 2 : width == sizeof(long)? 0 : 1;
#define swap(a, b) \ #define swap(a, b) \
if (swaptype == 0) \ if (swaptype == 0) \
@ -80,7 +80,7 @@
} \ } \
else \ else \
{ \ { \
swapfunc(a, b, size, swaptype); \ swapfunc(a, b, width, 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)
@ -89,15 +89,16 @@
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
static inline void swapfunc(char *a, char *b, int n, int swaptype); static inline void swapfunc(FAR char *a, FAR char *b, int n, int swaptype);
static inline char *med3(char *a, char *b, char *c, static inline FAR char *med3(FAR char *a, FAR char *b, FAR char *c,
int (*compar)(const void *, const void *)); CODE int (*compar)(FAR const void *,
FAR const void *));
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
static inline void swapfunc(char *a, char *b, int n, int swaptype) static inline void swapfunc(FAR char *a, FAR char *b, int n, int swaptype)
{ {
if (swaptype <= 1) if (swaptype <= 1)
{ {
@ -109,8 +110,9 @@ static inline void swapfunc(char *a, char *b, int n, int swaptype)
} }
} }
static inline char *med3(char *a, char *b, char *c, static inline FAR char *med3(FAR char *a, FAR char *b, FAR char *c,
int (*compar)(const void *, const void *)) CODE int (*compar)(FAR const void *,
FAR const void *))
{ {
return compar(a, b) < 0 ? return compar(a, b) < 0 ?
(compar(b, c) < 0 ? b : (compar(a, c) < 0 ? c : a )) (compar(b, c) < 0 ? b : (compar(a, c) < 0 ? c : a ))
@ -125,49 +127,97 @@ static inline char *med3(char *a, char *b, char *c,
* Name: qsort * Name: qsort
* *
* Description: * Description:
* The qsort() function will sort an array of 'nel' objects, the initial
* element of which is pointed to by 'base'. The size of each object, in
* bytes, is specified by the 'width" argument. If the 'nel' argument has
* the value zero, the comparison function pointed to by 'compar' will not
* be called and no rearrangement will take place.
*
* The application will ensure that the comparison function pointed to by
* 'compar' does not alter the contents of the array. The implementation
* may reorder elements of the array between calls to the comparison
* function, but will not alter the contents of any individual element.
*
* When the same objects (consisting of 'width" bytes, irrespective of
* their current positions in the array) are passed more than once to
* the comparison function, the results will be consistent with one
* another. That is, they will define a total ordering on the array.
*
* The contents of the array will be sorted in ascending order according
* to a comparison function. The 'compar' argument is a pointer to the
* comparison function, which is called with two arguments that point to
* the elements being compared. The application will ensure that the
* function returns an integer less than, equal to, or greater than 0,
* if the first argument is considered respectively less than, equal to,
* or greater than the second. If two members compare as equal, their
* order in the sorted array is unspecified.
*
* (Based on description from OpenGroup.org).
*
* Returned Value:
* The qsort() function will not return a value.
*
* Notes from the original BSD version:
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
* *
****************************************************************************/ ****************************************************************************/
void qsort(void *base, size_t nmemb, size_t size, void qsort(FAR void *base, size_t nel, size_t width,
int(*compar)(const void *, const void *)) CODE int(*compar)(FAR const void *, FAR const void *))
{ {
char *pa, *pb, *pc, *pd, *pl, *pm, *pn; FAR char *pa;
int d, r, swaptype, swap_cnt; FAR char *pb;
FAR char *pc;
FAR char *pd;
FAR char *pl;
FAR char *pm;
FAR char *pn;
int swaptype;
int swap_cnt;
int d;
int r;
loop: loop:
SWAPINIT(base, size); SWAPINIT(base, width);
swap_cnt = 0; swap_cnt = 0;
if (nmemb < 7)
if (nel < 7)
{ {
for (pm = (char *) base + size; pm < (char *) base + nmemb * size; pm += size) for (pm = (FAR char *)base + width;
pm < (FAR char *)base + nel * width;
pm += width)
{ {
for (pl = pm; pl > (char *) base && compar(pl - size, pl) > 0; pl -= size) for (pl = pm;
pl > (FAR char *)base && compar(pl - width, pl) > 0;
pl -= width)
{ {
swap(pl, pl - size); swap(pl, pl - width);
} }
} }
return; return;
} }
pm = (char *) base + (nmemb / 2) * size; pm = (FAR char *)base + (nel / 2) * width;
if (nmemb > 7) if (nel > 7)
{ {
pl = base; pl = base;
pn = (char *) base + (nmemb - 1) * size; pn = (FAR char *)base + (nel - 1) * width;
if (nmemb > 40) if (nel > 40)
{ {
d = (nmemb / 8) * size; d = (nel / 8) * width;
pl = med3(pl, pl + d, pl + 2 * d, compar); pl = med3(pl, pl + d, pl + 2 * d, compar);
pm = med3(pm - d, pm, pm + d, compar); pm = med3(pm - d, pm, pm + d, compar);
pn = med3(pn - 2 * d, pn - d, pn, compar); pn = med3(pn - 2 * d, pn - d, pn, compar);
} }
pm = med3(pl, pm, pn, compar); pm = med3(pl, pm, pn, compar);
} }
swap(base, pm);
pa = pb = (char *) base + size;
pc = pd = (char *) base + (nmemb - 1) * size; swap(base, pm);
pa = pb = (FAR char *)base + width;
pc = pd = (FAR char *)base + (nel - 1) * width;
for (;;) for (;;)
{ {
while (pb <= pc && (r = compar(pb, base)) <= 0) while (pb <= pc && (r = compar(pb, base)) <= 0)
@ -176,19 +226,22 @@ loop:
{ {
swap_cnt = 1; swap_cnt = 1;
swap(pa, pb); swap(pa, pb);
pa += size; pa += width;
} }
pb += size;
pb += width;
} }
while (pb <= pc && (r = compar(pc, base)) >= 0) while (pb <= pc && (r = compar(pc, base)) >= 0)
{ {
if (r == 0) if (r == 0)
{ {
swap_cnt = 1; swap_cnt = 1;
swap(pc, pd); swap(pc, pd);
pd -= size; pd -= width;
} }
pc -= size;
pc -= width;
} }
if (pb > pc) if (pb > pc)
@ -198,43 +251,47 @@ loop:
swap(pb, pc); swap(pb, pc);
swap_cnt = 1; swap_cnt = 1;
pb += size; pb += width;
pc -= size; pc -= width;
} }
if (swap_cnt == 0) if (swap_cnt == 0)
{ {
/* Switch to insertion sort */ /* Switch to insertion sort */
for (pm = (char *) base + size; pm < (char *) base + nmemb * size; pm += size) for (pm = (FAR char *)base + width;
pm < (FAR char *)base + nel * width;
pm += width)
{ {
for (pl = pm; pl > (char *) base && compar(pl - size, pl) > 0; pl -= size) for (pl = pm;
pl > (FAR char *)base && compar(pl - width, pl) > 0;
pl -= width)
{ {
swap(pl, pl - size); swap(pl, pl - width);
} }
} }
return; return;
} }
pn = (char *) base + nmemb * size; pn = (FAR char *)base + nel * width;
r = min(pa - (char *)base, pb - pa); r = min(pa - (FAR char *)base, pb - pa);
vecswap(base, pb - r, r); vecswap(base, pb - r, r);
r = min(pd - pc, pn - pd - size);
r = min(pd - pc, pn - pd - width);
vecswap(pb, pn - r, r); vecswap(pb, pn - r, r);
if ((r = pb - pa) > size) if ((r = pb - pa) > width)
{ {
qsort(base, r / size, size, compar); qsort(base, r / width, width, compar);
} }
if ((r = pd - pc) > size) if ((r = pd - pc) > width)
{ {
/* Iterate rather than recurse to save stack space */ /* Iterate rather than recurse to save stack space */
base = pn - r; base = pn - r;
nmemb = r / size; nel = r / width;
goto loop; goto loop;
} }
} }