aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2015-08-15 17:41:28 +0300
committerZyX <kp-pav@yandex.ru>2015-10-08 22:00:45 +0300
commitd1830e143342a1714fa66af727a2cc5c4084b6fe (patch)
tree20f554b1f3db259cb220bad0b89f05b1a4ac8fcb
parentb249529676306760b5cd99a4707e6bf246f8b99b (diff)
downloadrneovim-d1830e143342a1714fa66af727a2cc5c4084b6fe.tar.gz
rneovim-d1830e143342a1714fa66af727a2cc5c4084b6fe.tar.bz2
rneovim-d1830e143342a1714fa66af727a2cc5c4084b6fe.zip
config: Check order and endianess even when cross-compiling
-rw-r--r--config/CMakeLists.txt56
-rw-r--r--src/nvim/shada.c3
2 files changed, 41 insertions, 18 deletions
diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt
index 9334691e2a..b780291264 100644
--- a/config/CMakeLists.txt
+++ b/config/CMakeLists.txt
@@ -3,6 +3,7 @@ include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(CheckCSourceRuns)
+include(CheckCSourceCompiles)
check_type_size("int" SIZEOF_INT)
check_type_size("long" SIZEOF_LONG)
@@ -75,31 +76,50 @@ endif()
set(SI "#include <stdint.h>\n")
set(MS "int main(int argc,char**argv)\n{\n uint64_t i=0x0102030405060708ULL;")
set(ME "}")
-check_c_source_runs("
- ${SI}
- ${MS}
- char *s = (char *) &i;
- return (
- s[0] == 0x01
- && s[1] == 0x02
- && s[2] == 0x03
- && s[3] == 0x04
- && s[4] == 0x05
- && s[5] == 0x06
- && s[6] == 0x07
- && s[7] == 0x08) ? 0 : 1;
- ${ME}"
- ORDER_BIG_ENDIAN)
-check_c_source_runs("
+check_c_source_compiles("
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
${SI}
#include <endian.h>
+ #ifndef be64toh
+ # error No be64toh macros
+ #endif
${MS}
uint64_t j = be64toh(i);
- return (j == 0); // Must not be zero
+ return (j == 0); // j must not be zero
${ME}"
- HAVE_BE64TOH)
+ HAVE_BE64TOH_MACROS)
+if(NOT "${HAVE_BE64TOH_MACROS}")
+ check_function_exists(be64toh HAVE_BE64TOH_FUNC)
+endif()
+if("${HAVE_BE64TOH_MACROS}" OR "${HAVE_BE64TOH_FUNC}")
+ set(HAVE_BE64TOH 1)
+endif()
+if (NOT "${HAVE_BE64TOH}")
+ if (NOT "${CMAKE_CROSSCOMPILING}")
+ # It is safe to make ORDER_BIG_ENDIAN not defined if
+ # - HAVE_BE64TOH is true. In this case be64toh will be used unconditionally in
+ # any case and ORDER_BIG_ENDIAN will not be examined.
+ # - CMAKE_CROSSCOMPILING *and* HAVE_BE64TOH are both false. In this case
+ # be64toh function which uses cycle and arithmetic operations is used which
+ # will work regardless of endianess. Function is sub-optimal though.
+ check_c_source_runs("
+ ${SI}
+ ${MS}
+ char *s = (char *) &i;
+ return (
+ s[0] == 0x01
+ && s[1] == 0x02
+ && s[2] == 0x03
+ && s[3] == 0x04
+ && s[4] == 0x05
+ && s[5] == 0x06
+ && s[6] == 0x07
+ && s[7] == 0x08) ? 0 : 1;
+ ${ME}"
+ ORDER_BIG_ENDIAN)
+ endif()
+endif()
# generate configuration header and update include directories
configure_file (
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 6de3d8b20e..1d4b486823 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -3141,6 +3141,9 @@ static inline uint64_t be64toh(uint64_t big_endian_64_bits)
#ifdef ORDER_BIG_ENDIAN
return big_endian_64_bits;
#else
+ // It may appear that when !defined(ORDER_BIG_ENDIAN) actual order is big
+ // endian. This variant is suboptimal, but it works regardless of actual
+ // order.
uint8_t *buf = (uint8_t *) &big_endian_64_bits;
uint64_t ret = 0;
for (size_t i = 8; i; i--) {