Skip to content

Commit

Permalink
Improve c++ compatibility of htslib header files
Browse files Browse the repository at this point in the history
Allow room in kputuw_dig2r for the nul byte on the end of the
string used to initialize it.  gcc doesn't mind it being dropped
but g++ complains.

Avoid INTx_MIN, INTx_MAX and SIZE_MAX macros from <stdint.h> in
htslib/*.h header files.  Old versions of glibc (before 2.18), and
possibly other libc implementations don't automatically supply them
when compiling as c++.  Easiest solution is to not use them in
these headers.
(See https://sourceware.org/bugzilla/show_bug.cgi?id=15366)

Fixes #771 (kstring.h error: initializer-string for array of chars
is too long)
  • Loading branch information
daviesrob authored and valeriuo committed Sep 28, 2018
1 parent 0a8cdc6 commit e85b599
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 13 deletions.
8 changes: 5 additions & 3 deletions htslib/kstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ static inline char *ks_release(kstring_t *s)

static inline int kputsn(const char *p, size_t l, kstring_t *s)
{
if (l > SIZE_MAX - 2 - s->l || ks_resize(s, s->l + l + 2) < 0)
size_t new_sz = s->l + l + 2;
if (new_sz < s->l || ks_resize(s, new_sz) < 0)
return EOF;
memcpy(s->s + s->l, p, l);
s->l += l;
Expand Down Expand Up @@ -183,7 +184,8 @@ static inline int kputc_(int c, kstring_t *s)

static inline int kputsn_(const void *p, size_t l, kstring_t *s)
{
if (l > SIZE_MAX - s->l || ks_resize(s, s->l + l) < 0)
size_t new_sz = s->l + l;
if (new_sz < s->l || ks_resize(s, new_sz) < 0)
return EOF;
memcpy(s->s + s->l, p, l);
s->l += l;
Expand All @@ -208,7 +210,7 @@ static inline int kputuw(unsigned x, kstring_t *s)
#else
uint64_t m;
#endif
static const char kputuw_dig2r[200] =
static const char kputuw_dig2r[] =
"00010203040506070809"
"10111213141516171819"
"20212223242526272829"
Expand Down
31 changes: 21 additions & 10 deletions htslib/vcf.h
Original file line number Diff line number Diff line change
Expand Up @@ -876,14 +876,25 @@ typedef struct {
enables to handle correctly vectors with different ploidy in presence of
missing values.
*/
#define bcf_int8_vector_end (INT8_MIN+1)
#define bcf_int16_vector_end (INT16_MIN+1)
#define bcf_int32_vector_end (INT32_MIN+1)
#define bcf_int8_vector_end (-127) /* INT8_MIN + 1 */
#define bcf_int16_vector_end (-32767) /* INT16_MIN + 1 */
#define bcf_int32_vector_end (-2147483647) /* INT32_MIN + 1 */
#define bcf_str_vector_end 0
#define bcf_int8_missing INT8_MIN
#define bcf_int16_missing INT16_MIN
#define bcf_int32_missing INT32_MIN
#define bcf_int8_missing (-128) /* INT8_MIN */
#define bcf_int16_missing (-32767-1) /* INT16_MIN */
#define bcf_int32_missing (-2147483647-1) /* INT32_MIN */
#define bcf_str_missing 0x07

// Limits on BCF values stored in given types. Max values are the same
// as for the underlying type. Min values are slightly different as
// the last 8 values for each type were reserved by BCFv2.2.
#define BCF_MAX_BT_INT8 (0x7f) /* INT8_MAX */
#define BCF_MAX_BT_INT16 (0x7fff) /* INT16_MAX */
#define BCF_MAX_BT_INT32 (0x7fffffff) /* INT32_MAX */
#define BCF_MIN_BT_INT8 (-120) /* INT8_MIN + 8 */
#define BCF_MIN_BT_INT16 (-32760) /* INT16_MIN + 8 */
#define BCF_MIN_BT_INT32 (-2147483640) /* INT32_MIN + 8 */

extern uint32_t bcf_float_vector_end;
extern uint32_t bcf_float_missing;
static inline void bcf_float_set(float *ptr, uint32_t value)
Expand Down Expand Up @@ -953,8 +964,8 @@ static inline void bcf_enc_size(kstring_t *s, int size, int type)

static inline int bcf_enc_inttype(long x)
{
if (x <= INT8_MAX && x >= INT8_MIN + 8) return BCF_BT_INT8;
if (x <= INT16_MAX && x >= INT16_MIN + 8) return BCF_BT_INT16;
if (x <= BCF_MAX_BT_INT8 && x >= BCF_MIN_BT_INT8) return BCF_BT_INT8;
if (x <= BCF_MAX_BT_INT16 && x >= BCF_MIN_BT_INT16) return BCF_BT_INT16;
return BCF_BT_INT32;
}

Expand All @@ -966,10 +977,10 @@ static inline void bcf_enc_int1(kstring_t *s, int32_t x)
} else if (x == bcf_int32_missing) {
bcf_enc_size(s, 1, BCF_BT_INT8);
kputc(bcf_int8_missing, s);
} else if (x <= INT8_MAX && x >= INT8_MIN + 8) {
} else if (x <= BCF_MAX_BT_INT8 && x >= BCF_MIN_BT_INT8) {
bcf_enc_size(s, 1, BCF_BT_INT8);
kputc(x, s);
} else if (x <= INT16_MAX && x >= INT16_MIN + 8) {
} else if (x <= BCF_MAX_BT_INT16 && x >= BCF_MIN_BT_INT16) {
int16_t z = x;
bcf_enc_size(s, 1, BCF_BT_INT16);
kputsn((char*)&z, 2, s);
Expand Down

0 comments on commit e85b599

Please sign in to comment.