Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/publish-sdist-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
matrix:
# macos-13 is an intel runner, macos-14 is apple silicon
os: [ubuntu-24.04, windows-2022, macos-13, macos-14]
os: [ubuntu-24.04]

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -58,7 +58,13 @@ jobs:
mkdir -p /host/home/runner/work/src-cache
ln -s /host/home/runner/work/src-cache /opt/hdf5-static
bash ci/hdf5-build.sh /opt/hdf5-static

CIBW_BEFORE_TEST: |
# there are no h5py wheels for musllinux
# h5py needs hdf5-dev to compile from source
apk update || true
apk add hdf5-dev 2>/dev/null || true
apk add gcompat || true
pip install -r {project}/tests/requirement_tests.txt
run: |
# used by setup.py to decide if to set `FindHDF5` to use static hdf5 libraries
export STATIC_HDF5=True
Expand Down
27 changes: 27 additions & 0 deletions CMake/CompilerFlags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,30 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
else()
message(WARNING "Unexpected compiler type ${CMAKE_CXX_COMPILER_ID}")
endif()

if (LINUX)
# Let preprocessor know if there is support for GNU locale extensions (e.g. strtol_l)
# For linux distros that use alternatives to libc (e.g. musl) that do not support them
include(CheckCXXSourceCompiles)
check_cxx_source_compiles(
"#include <locale.h>
#include <stdlib.h>
int main() {
locale_t loc = newlocale(LC_NUMERIC_MASK, \"C\", nullptr);
strtol_l(\"123\", nullptr, 10, loc);
freelocale(loc);
return 0;
}"
HAS_LOCALE_EXTENSIONS
)
if(HAS_LOCALE_EXTENSIONS)
set(FLAGS "${FLAGS} -DHAS_LOCALE_EXTENSIONS")
message("Locale support: Available (Linux)")
else()
message("Locale support: Not available (Linux)")
endif()
else()
# most windows and apple versions we target support locales
set(FLAGS "${FLAGS} -DHAS_LOCALE_EXTENSIONS")
message("Locale support: Available (${CMAKE_SYSTEM_NAME})")
endif()
65 changes: 56 additions & 9 deletions src/readers/utils.cpp
Original file line number Diff line number Diff line change
@@ -1,46 +1,86 @@
#include "./utils.h"

namespace morphio {

#ifdef HAS_LOCALE_EXTENSIONS

#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
#define freelocale _free_locale
#define strtol_l _strtol_l
#define str_to_long _strtol_l

#ifdef MORPHIO_USE_DOUBLE
#define strto_float _strtod_l
#define str_to_float _strtod_l
#else
#define strto_float _strtof_l
#define str_to_float _strtof_l
#endif

#else // not WIN32
#define str_to_long strtol_l

#ifdef MORPHIO_USE_DOUBLE
#define str_to_float strtod_l
#else
#define str_to_float strtof_l
#endif

#endif

#else // not HAS_LOCALE_EXTENSIONS

#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
#define str_to_long _strtol

#ifdef MORPHIO_USE_DOUBLE
#define str_to_float _strtod
#else
#define str_to_float _strtof
#endif

#else // not WIN32
#define str_to_long strtol

#ifdef MORPHIO_USE_DOUBLE
#define strto_float strtod_l
#define str_to_float strtod
#else
#define strto_float strtof_l
#define str_to_float strtof
#endif

#endif

#endif // HAS_LOCALE_EXTENSIONS

// Only create the `locale` to facilitate number handling once
StringToNumber::StringToNumber()
#ifdef HAS_LOCALE_EXTENSIONS
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
// On windows, use their locale handling for their runtime
: locale(_create_locale(LC_ALL, "C")){}
#else
// On other platforms, use the POSIX version
: locale(newlocale(LC_NUMERIC_MASK, "POSIX", nullptr)) {
}
#endif
#else
{
}
#endif

StringToNumber::~StringToNumber() {
#ifdef HAS_LOCALE_EXTENSIONS
freelocale(locale);
#endif
}

std::tuple<int64_t, size_t> StringToNumber::toInt(const std::string& s, size_t offset) const {
const size_t base = 10;
const char* pos = &s[offset];
const char* endpos = &s[s.size()];
int64_t ret = strtol_l(pos, const_cast<char**>(&endpos), base, locale);

#ifdef HAS_LOCALE_EXTENSIONS
int64_t ret = str_to_long(pos, const_cast<char**>(&endpos), base, locale);
#else
int64_t ret = str_to_long(pos, const_cast<char**>(&endpos), base);
#endif

auto new_offset = static_cast<size_t>(endpos - s.data());

Expand All @@ -54,7 +94,12 @@ std::tuple<int64_t, size_t> StringToNumber::toInt(const std::string& s, size_t o
std::tuple<floatType, size_t> StringToNumber::toFloat(const std::string& s, size_t offset) const {
const char* pos = &s[offset];
const char* endpos = &s[s.size()];
floatType ret = strto_float(pos, const_cast<char**>(&endpos), locale);

#ifdef HAS_LOCALE_EXTENSIONS
floatType ret = str_to_float(pos, const_cast<char**>(&endpos), locale);
#else
floatType ret = str_to_float(pos, const_cast<char**>(&endpos));
#endif

auto new_offset = static_cast<size_t>(endpos - s.data());

Expand All @@ -70,11 +115,13 @@ StringToNumber& getStringToNumber() {
return stn;
}

#ifdef HAS_LOCALE_EXTENSIONS
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
#undef freelocale
#undef strtol_l
#endif
#endif

#undef strto_float
#undef str_to_long
#undef str_to_float

} // namespace morphio
2 changes: 2 additions & 0 deletions src/readers/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
namespace morphio {

struct StringToNumber {
#ifdef HAS_LOCALE_EXTENSIONS
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
_locale_t locale;
#else
locale_t locale;
#endif
#endif

StringToNumber();
Expand Down
Loading