From cd9f5aac1aa9703833850b808165e315467c50a4 Mon Sep 17 00:00:00 2001 From: John Marshall Date: Tue, 11 Jan 2022 12:11:22 +0000 Subject: [PATCH] Provide a definition of ssize_t when compiling with MSVC Define `ssize_t` within the public headers that use it, enabling them to be compiled with MSVC, which does not provide this type definition in its or any other headers. Having `ssize_t` as a macro may confuse other headers, so be sure to do this only after all other #includes and to undefine it again at the end of each header. User code or other libraries may also have workarounds for this issue, so checking its not already #defined and removing our `ssize_t` macro afterwards also avoids conflicting with other workarounds. Under MSVC, including //etc also causes to be included, which defines `size_t` and `intptr_t` as unsigned/signed versions of the same type. So we define `ssize_t` as that, if it is not already defined (by some other workaround) and if `_INTPTR_T_DEFINED` has indeed been defined by (to avoid confusing error messages). We also check `_SSIZE_T_DEFINED`, which MSVC will likely define if it's ever fixed to supply this typedef. Also define it (permanently) in , unless suppressed by defining `HTS_NO_SSIZE_T` before including the header. --- htslib/bgzf.h | 12 ++++++++++++ htslib/hfile.h | 12 ++++++++++++ htslib/hts_os.h | 6 ++++++ htslib/knetfile.h | 12 ++++++++++++ htslib/kstring.h | 12 ++++++++++++ htslib/sam.h | 12 ++++++++++++ 6 files changed, 66 insertions(+) diff --git a/htslib/bgzf.h b/htslib/bgzf.h index 8e6b9b17e..24d787bdf 100644 --- a/htslib/bgzf.h +++ b/htslib/bgzf.h @@ -35,6 +35,13 @@ #include "hts_defs.h" +// Ensure ssize_t exists within this header. All #includes must precede this, +// and ssize_t must be undefined again at the end of this header. +#if defined _MSC_VER && defined _INTPTR_T_DEFINED && !defined _SSIZE_T_DEFINED && !defined ssize_t +#define HTSLIB_SSIZE_T +#define ssize_t intptr_t +#endif + #ifdef __cplusplus extern "C" { #endif @@ -450,4 +457,9 @@ typedef struct BGZF BGZF; } #endif +#ifdef HTSLIB_SSIZE_T +#undef HTSLIB_SSIZE_T +#undef ssize_t +#endif + #endif diff --git a/htslib/hfile.h b/htslib/hfile.h index 987acb7c8..038591cbc 100644 --- a/htslib/hfile.h +++ b/htslib/hfile.h @@ -32,6 +32,13 @@ DEALINGS IN THE SOFTWARE. */ #include "hts_defs.h" +// Ensure ssize_t exists within this header. All #includes must precede this, +// and ssize_t must be undefined again at the end of this header. +#if defined _MSC_VER && defined _INTPTR_T_DEFINED && !defined _SSIZE_T_DEFINED && !defined ssize_t +#define HTSLIB_SSIZE_T +#define ssize_t intptr_t +#endif + #ifdef __cplusplus extern "C" { #endif @@ -368,4 +375,9 @@ int hfile_has_plugin(const char *name); } #endif +#ifdef HTSLIB_SSIZE_T +#undef HTSLIB_SSIZE_T +#undef ssize_t +#endif + #endif diff --git a/htslib/hts_os.h b/htslib/hts_os.h index b71cb89e7..c715b0612 100644 --- a/htslib/hts_os.h +++ b/htslib/hts_os.h @@ -77,4 +77,10 @@ extern int is_cygpty(int fd); #define random rand #endif +/* MSVC does not provide ssize_t in its . This ensures the type + is available (unless suppressed by defining HTS_NO_SSIZE_T first). */ +#if defined _MSC_VER && defined _INTPTR_T_DEFINED && !defined _SSIZE_T_DEFINED && !defined HTS_NO_SSIZE_T && !defined ssize_t +#define ssize_t intptr_t +#endif + #endif // HTSLIB_HTS_OS_H diff --git a/htslib/knetfile.h b/htslib/knetfile.h index da9cdc5e8..cfddd6b67 100644 --- a/htslib/knetfile.h +++ b/htslib/knetfile.h @@ -44,6 +44,13 @@ #define netclose(fd) closesocket(fd) #endif +// Ensure ssize_t exists within this header. All #includes must precede this, +// and ssize_t must be undefined again at the end of this header. +#if defined _MSC_VER && defined _INTPTR_T_DEFINED && !defined _SSIZE_T_DEFINED && !defined ssize_t +#define HTSLIB_SSIZE_T +#define ssize_t intptr_t +#endif + // FIXME: currently I/O is unbuffered #define KNF_TYPE_LOCAL 1 @@ -102,4 +109,9 @@ extern "C" { } #endif +#ifdef HTSLIB_SSIZE_T +#undef HTSLIB_SSIZE_T +#undef ssize_t +#endif + #endif diff --git a/htslib/kstring.h b/htslib/kstring.h index 150757ca6..09bc9e3d9 100644 --- a/htslib/kstring.h +++ b/htslib/kstring.h @@ -55,6 +55,13 @@ #endif #endif +// Ensure ssize_t exists within this header. All #includes must precede this, +// and ssize_t must be undefined again at the end of this header. +#if defined _MSC_VER && defined _INTPTR_T_DEFINED && !defined _SSIZE_T_DEFINED && !defined ssize_t +#define HTSLIB_SSIZE_T +#define ssize_t intptr_t +#endif + /* kstring_t is a simple non-opaque type whose fields are likely to be * used directly by user code (but see also ks_str() and ks_len() below). * A kstring_t object is initialised by either of @@ -396,4 +403,9 @@ static inline int *ksplit(kstring_t *s, int delimiter, int *n) return offsets; } +#ifdef HTSLIB_SSIZE_T +#undef HTSLIB_SSIZE_T +#undef ssize_t +#endif + #endif diff --git a/htslib/sam.h b/htslib/sam.h index 79ac26e4b..e61b9a779 100644 --- a/htslib/sam.h +++ b/htslib/sam.h @@ -33,6 +33,13 @@ DEALINGS IN THE SOFTWARE. */ #include "hts.h" #include "hts_endian.h" +// Ensure ssize_t exists within this header. All #includes must precede this, +// and ssize_t must be undefined again at the end of this header. +#if defined _MSC_VER && defined _INTPTR_T_DEFINED && !defined _SSIZE_T_DEFINED && !defined ssize_t +#define HTSLIB_SSIZE_T +#define ssize_t intptr_t +#endif + #ifdef __cplusplus extern "C" { #endif @@ -2266,4 +2273,9 @@ int bam_mods_at_qpos(const bam1_t *b, int qpos, hts_base_mod_state *state, } #endif +#ifdef HTSLIB_SSIZE_T +#undef HTSLIB_SSIZE_T +#undef ssize_t +#endif + #endif