gpsd-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gpsd-dev] [PATCH] RTCM V2: use scons to determine the location of <endi


From: Beat Bolli
Subject: [gpsd-dev] [PATCH] RTCM V2: use scons to determine the location of <endian.h>.
Date: Fri, 8 Nov 2013 23:43:33 +0100

There are three cases to consider:

- The compiler has built-in endianness macros. In this case, endian.h is
  not needed at all. The predefined symols are called
  __ORDER_BIG_ENDIAN_, __ORDER_LITTLE_ENDIAN__ and __BYTE_ORDER__.

- <endian.h> exists.

- <sys/endian.h> exists.

This commit covers all three cases at configure time, as Greg Troxel
wanted it.

Relevant discussion can be found on the GCC mailing list:
http://gcc.gnu.org/ml/gcc-help/2007-07/msg00342.html

Of course, the optimal solution would get rid of the bit field
structures and use bits.h to extract the values from the buffer in an
endianess-independent way.

Signed-off-by: Beat Bolli <address@hidden>
---
 SConstruct     | 23 +++++++++++++++++++++++
 driver_rtcm2.c | 32 +++++++++++++++++++-------------
 2 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/SConstruct b/SConstruct
index dfa2c22..cf1688f 100644
--- a/SConstruct
+++ b/SConstruct
@@ -574,6 +574,29 @@ else:
     announce("You do not have kernel CANbus available.")
     env["nmea2000"] = False
 
+# endian.h is required for rtcm104v2 unless the compiler defines
+# __ORDER_BIG_ENDIAN__, __ORDER_LITTLE_ENDIAN__ and __BYTE_ORDER__
+if config.CheckHeaderDefines("/dev/null", "__ORDER_BIG_ENDIAN__") \
+and config.CheckHeaderDefines("/dev/null", "__ORDER_LITTLE_ENDIAN__") \
+and config.CheckHeaderDefines("/dev/null", "__BYTE_ORDER__"):
+    confdefs.append("#define HAVE_BUILTIN_ENDIANNESS 1\n")
+    confdefs.append("/* #undef HAVE_ENDIAN_H */\n")
+    confdefs.append("/* #undef HAVE_SYS_ENDIAN_H */\n")
+    announce("Your compiler has built-in endianness support.")
+else:
+    confdefs.append("/* #undef HAVE_BUILTIN_ENDIANNESS\n */")
+    if config.CheckHeader("endian.h"):
+        confdefs.append("#define HAVE_ENDIAN_H 1\n")
+        confdefs.append("/* #undef HAVE_SYS_ENDIAN_H */\n")
+    elif config.CheckHeader("sys/endian.h"):
+        confdefs.append("/* #undef HAVE_ENDIAN_H */\n")
+        confdefs.append("#define HAVE_SYS_ENDIAN_H 1\n")
+    else:
+        confdefs.append("/* #undef HAVE_ENDIAN_H */\n")
+        confdefs.append("/* #undef HAVE_SYS_ENDIAN_H */\n")
+        announce("You do not have the endian.h header file. RTCM V2 support 
disabled.")
+        env["rtcm104v2"] = False
+
 # check function after libraries, because some function require library
 # for example clock_gettime() require librt on Linux
 for f in ("daemon", "strlcpy", "strlcat", "clock_gettime"):
diff --git a/driver_rtcm2.c b/driver_rtcm2.c
index 91a6686..c3ab6a7 100644
--- a/driver_rtcm2.c
+++ b/driver_rtcm2.c
@@ -62,32 +62,38 @@ BSD terms apply: see the file COPYING in the distribution 
root for details.
 #include "gpsd.h"
 
 /*
-   __BIG_ENDIAN__ and __LITTLE_ENDIAN__ are define in some gcc versions
-  only, probably depending on the architecture. Try to use endian.h if
-  the gcc way fails - endian.h also doesn not seem to be available on all
-  platforms.
+  __BYTE_ORDER__, __ORDER_BIG_ENDIAN__ and __ORDER_LITTLE_ENDIAN__ are
+  defined in some gcc versions only, probably depending on the
+  architecture. Try to use endian.h if the gcc way fails - endian.h also
+  does not seem to be available on all platforms.
 */
-#ifdef __BIG_ENDIAN__
+
+#if HAVE_BUILTIN_ENDIANNESS
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 #define WORDS_BIGENDIAN 1
-#else /* __BIG_ENDIAN__ */
-#ifdef __LITTLE_ENDIAN__
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 #undef WORDS_BIGENDIAN
 #else
-#ifdef __linux__
+#error Unknown endianness!
+#endif
+
+#else /* HAVE_BUILTIN_ENDIANNESS */
+
+#if defined(HAVE_ENDIAN_H)
 #include <endian.h>
-#else
-/* usual BSD location */
+#elif defined(HAVE_SYS_ENDIAN_H)
 #include <sys/endian.h>
 #endif
+
 #if __BYTE_ORDER == __BIG_ENDIAN
 #define WORDS_BIGENDIAN 1
 #elif __BYTE_ORDER == __LITTLE_ENDIAN
 #undef WORDS_BIGENDIAN
 #else
-#error "unable to determine endianess!"
+#error Unknown endianness!
 #endif /* __BYTE_ORDER */
-#endif /* __LITTLE_ENDIAN__ */
-#endif /* __BIG_ENDIAN__ */
+
+#endif /* HAVE_BUILTIN_ENDIANNESS */
 
 /*
  * Structures for interpreting words in an RTCM-104 2.x message (after
-- 
1.8.4.rc3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]