Skip to content

Commit

Permalink
Add KSORT_INIT_STATIC()/etc to facilitate library ksort use
Browse files Browse the repository at this point in the history
Add KSORT_INIT2()/etc that allow specification of a scope to be used
for the functions generated. As the existing KSORT_INIT()/etc produce
shared global functions, also add KSORT_INIT_STATIC()/etc that produce
static functions -- which requires klib_unused, to avoid warnings about
unused static functions. (cf 5ffc4a2.)

`KSORT_INIT2(..., static klib_unused, ...)` would let `klib_unused` leak
into user code, so providing an extra KSORT_INIT_STATIC() is better.

Use this new static ksort in errmod.c and hts.c to avoid polluting
the non-hts_-prefixed namespace.
  • Loading branch information
jmarshall authored and daviesrob committed Apr 10, 2019
1 parent 75be032 commit 7a93ceb
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 14 deletions.
2 changes: 1 addition & 1 deletion errmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ DEALINGS IN THE SOFTWARE. */
#include "htslib/ksort.h"
#include "htslib/hts_os.h" // for drand48

KSORT_INIT_GENERIC(uint16_t)
KSORT_INIT_STATIC_GENERIC(uint16_t)

struct errmod_t {
double depcorr;
Expand Down
4 changes: 2 additions & 2 deletions hts.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,8 +1282,8 @@ int hts_check_EOF(htsFile *fp)

#define pair64_lt(a,b) ((a).u < (b).u)

KSORT_INIT(_off, hts_pair64_t, pair64_lt)
KSORT_INIT(_off_max, hts_pair64_max_t, pair64_lt)
KSORT_INIT_STATIC(_off, hts_pair64_t, pair64_lt)
KSORT_INIT_STATIC(_off_max, hts_pair64_max_t, pair64_lt)

typedef struct {
int32_t m, n;
Expand Down
39 changes: 28 additions & 11 deletions htslib/ksort.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@
#include <stdlib.h>
#include <string.h>

#ifndef klib_unused
#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3)
#define klib_unused __attribute__ ((__unused__))
#else
#define klib_unused
#endif
#endif /* klib_unused */

#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -82,9 +90,12 @@ typedef struct {

#define KSORT_SWAP(type_t, a, b) { register type_t t=(a); (a)=(b); (b)=t; }

#define KSORT_INIT(name, type_t, __sort_lt) KSORT_INIT_(_ ## name, type_t, __sort_lt)
#define KSORT_INIT_(name, type_t, __sort_lt) \
void ks_mergesort##name(size_t n, type_t array[], type_t temp[]) \
#define KSORT_INIT(name, type_t, __sort_lt) KSORT_INIT_(_ ## name, , type_t, __sort_lt)
#define KSORT_INIT_STATIC(name, type_t, __sort_lt) KSORT_INIT_(_ ## name, static klib_unused, type_t, __sort_lt)
#define KSORT_INIT2(name, SCOPE, type_t, __sort_lt) KSORT_INIT_(_ ## name, SCOPE, type_t, __sort_lt)

#define KSORT_INIT_(name, SCOPE, type_t, __sort_lt) \
SCOPE void ks_mergesort##name(size_t n, type_t array[], type_t temp[]) \
{ \
type_t *a2[2], *a, *b; \
int curr, shift; \
Expand Down Expand Up @@ -132,7 +143,7 @@ typedef struct {
} \
if (temp == 0) free(a2[1]); \
} \
void ks_heapadjust##name(size_t i, size_t n, type_t l[]) \
SCOPE void ks_heapadjust##name(size_t i, size_t n, type_t l[]) \
{ \
size_t k = i; \
type_t tmp = l[i]; \
Expand All @@ -143,13 +154,13 @@ typedef struct {
} \
l[i] = tmp; \
} \
void ks_heapmake##name(size_t lsize, type_t l[]) \
SCOPE void ks_heapmake##name(size_t lsize, type_t l[]) \
{ \
size_t i; \
for (i = (lsize >> 1) - 1; i != (size_t)(-1); --i) \
ks_heapadjust##name(i, lsize, l); \
} \
void ks_heapsort##name(size_t lsize, type_t l[]) \
SCOPE void ks_heapsort##name(size_t lsize, type_t l[]) \
{ \
size_t i; \
for (i = lsize - 1; i > 0; --i) { \
Expand All @@ -165,7 +176,7 @@ typedef struct {
swap_tmp = *j; *j = *(j-1); *(j-1) = swap_tmp; \
} \
} \
void ks_combsort##name(size_t n, type_t a[]) \
SCOPE void ks_combsort##name(size_t n, type_t a[]) \
{ \
const double shrink_factor = 1.2473309501039786540366528676643; \
int do_swap; \
Expand All @@ -187,7 +198,7 @@ typedef struct {
} while (do_swap || gap > 2); \
if (gap != 1) __ks_insertsort##name(a, a + n); \
} \
void ks_introsort##name(size_t n, type_t a[]) \
SCOPE void ks_introsort##name(size_t n, type_t a[]) \
{ \
int d; \
ks_isort_stack_t *top, *stack; \
Expand Down Expand Up @@ -240,7 +251,7 @@ typedef struct {
} \
/* This function is adapted from: http://ndevilla.free.fr/median/ */ \
/* 0 <= kk < n */ \
type_t ks_ksmall##name(size_t n, type_t arr[], size_t kk) \
SCOPE type_t ks_ksmall##name(size_t n, type_t arr[], size_t kk) \
{ \
type_t *low, *high, *k, *ll, *hh, *mid; \
low = arr; high = arr + n - 1; k = arr + kk; \
Expand All @@ -267,7 +278,7 @@ typedef struct {
if (hh >= k) high = hh - 1; \
} \
} \
void ks_shuffle##name(size_t n, type_t a[]) \
SCOPE void ks_shuffle##name(size_t n, type_t a[]) \
{ \
int i, j; \
for (i = n; i > 1; --i) { \
Expand All @@ -291,9 +302,15 @@ typedef struct {

typedef const char *ksstr_t;

#define KSORT_INIT_GENERIC(type_t) KSORT_INIT_(_ ## type_t, type_t, ks_lt_generic)
#define KSORT_INIT_GENERIC(type_t) KSORT_INIT_(_ ## type_t, , type_t, ks_lt_generic)
#define KSORT_INIT_STR KSORT_INIT(str, ksstr_t, ks_lt_str)

#define KSORT_INIT_STATIC_GENERIC(type_t) KSORT_INIT_(_ ## type_t, static klib_unused, type_t, ks_lt_generic)
#define KSORT_INIT_STATIC_STR KSORT_INIT_STATIC(str, ksstr_t, ks_lt_str)

#define KSORT_INIT2_GENERIC(type_t, SCOPE) KSORT_INIT_(_ ## type_t, SCOPE, type_t, ks_lt_generic)
#define KSORT_INIT2_STR KSORT_INIT2(str, SCOPE, ksstr_t, ks_lt_str)

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 7a93ceb

Please sign in to comment.