endianness.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2008 iptelorg GmbH
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /** @file
  19. * endianness compile and runtime tests
  20. *
  21. * History:
  22. * --------
  23. * 2008-06-13 created by andrei
  24. *
  25. * Defines:
  26. * - __IS_LITTLE_ENDIAN if the system is little endian and
  27. * - __IS_BIG_ENDIAN if it's big endian
  28. * Function/macros:
  29. * - is_big_endian() - runtime test for big endian
  30. * - is_little_endian() - runtime test for little endian
  31. * - endianness_sanity_check() - returns 0 if the compile time
  32. * detected endianness corresponds to
  33. * the runtime detected one and -1 on
  34. * error (recommended action: bail out)
  35. *
  36. * Implementation notes:
  37. * Endian macro names/tests for different OSes:
  38. * linux: __BYTE_ORDER == __LITTLE_ENDIAN | __BIG_ENDIAN
  39. * BYTE_ORDER == LITTLE_ENDIAN | BIG_ENDIAN
  40. * bsd: _BYTE_ORDER == _LITTLE_ENDIAN | _BIG_ENDIAN
  41. * BYTE_ORDER == LITTLE_ENDIAN | BIG_ENDIAN
  42. * solaris: _LITTLE_ENDIAN | _BIG_ENDIAN
  43. *
  44. * Include file for the endian macros:
  45. * linux: <endian.h> (glibc), <sys/param.h>
  46. * bsd: <sys/param.h>, <sys/endian.h>
  47. * solaris: <sys/param.h>
  48. *
  49. * Note: BIG_ENDIAN, LITTLE_ENDIAN, _BIG_ENDIAN, _LITTLE_ENDIAN cannot be
  50. * used always, some OSes define both of them for BYTE_ORDER use
  51. * (e.g. linux defines both BIG_ENDIAN & LITTLE_ENDIAN, bsds define
  52. * _BIG_ENDIAN, _LITTLE_ENDIAN, BIG_ENDIAN, LITTLE_ENDIAN)
  53. *
  54. */
  55. #ifndef _endianness_h
  56. #define _endianness_h
  57. /* use bsd includes: they work everywhere */
  58. #include <sys/types.h>
  59. #include <sys/param.h>
  60. extern int _endian_test_int;
  61. /* returns 1 for little endian, 0 for big endian */
  62. #define endian_test() (*(char*)&_endian_test_int==1)
  63. #define is_big_endian() (!endian_test())
  64. #define is_little_endian() endian_test()
  65. extern int endianness_sanity_check(void);
  66. /* detect compile time endianess */
  67. #if defined __BYTE_ORDER && defined __LITTLE_ENDIAN && defined __BIG_ENDIAN
  68. /* linux */
  69. #if __BYTE_ORDER == __LITTLE_ENDIAN && ! defined __IS_LITTLE_ENDIAN
  70. #define __IS_LITTLE_ENDIAN 0x01020304
  71. #endif
  72. #if __BYTE_ORDER == __BIG_ENDIAN && ! defined __IS_BIG_ENDIAN
  73. #define __IS_BIG_ENDIAN 0x01020304
  74. #endif
  75. #elif defined _BYTE_ORDER && defined _LITTLE_ENDIAN && defined _BIG_ENDIAN
  76. /* bsd */
  77. #if _BYTE_ORDER == _LITTLE_ENDIAN && ! defined __IS_LITTLE_ENDIAN
  78. #define __IS_LITTLE_ENDIAN 0x01020304
  79. #endif
  80. #if _BYTE_ORDER == _BIG_ENDIAN && ! defined __IS_BIG_ENDIAN
  81. #define __IS_BIG_ENDIAN 0x01020304
  82. #endif
  83. #elif defined BYTE_ORDER && defined LITTLE_ENDIAN && defined BIG_ENDIAN
  84. /* bsd old/deprecated */
  85. #if BYTE_ORDER == LITTLE_ENDIAN && ! defined __IS_LITTLE_ENDIAN
  86. #define __IS_LITTLE_ENDIAN 0x01020304
  87. #endif
  88. #if BYTE_ORDER == BIG_ENDIAN && ! defined __IS_BIG_ENDIAN
  89. #define __IS_BIG_ENDIAN 0x01020304
  90. #endif
  91. #elif !(defined _LITTLE_ENDIAN && defined _BIG_ENDIAN) && \
  92. (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
  93. /* OSes that don't define BYTE_ORDER (sanity check above makes sure
  94. * little & big endian are not defined in the same time )*/
  95. /* solaris */
  96. #if defined _LITTLE_ENDIAN && !defined __IS_LITTLE_ENDIAN
  97. #define __IS_LITTLE_ENDIAN 0x01020304
  98. #endif
  99. #if defined _BIG_ENDIAN && !defined __IS_BIG_ENDIAN
  100. #define __IS_BIG_ENDIAN 0x04030201
  101. #endif
  102. #elif !(defined LITTLE_ENDIAN && defined BIG_ENDIAN) && \
  103. (defined LITTLE_ENDIAN || defined BIG_ENDIAN)
  104. /* OSes that don't define BYTE_ORDER (sanity check above makes sure
  105. * little & big endian are not defined in the same time )*/
  106. #if defined LITTLE_ENDIAN && !defined __IS_LITTLE_ENDIAN
  107. #define __IS_LITTLE_ENDIAN 0x01020304
  108. #endif
  109. #if defined BIG_ENDIAN && !defined __IS_BIG_ENDIAN
  110. #define __IS_BIG_ENDIAN 0x04030201
  111. #endif
  112. #else
  113. #error could not detect endianess
  114. #endif
  115. #if !defined __IS_LITTLE_ENDIAN && !defined __IS_BIG_ENDIAN
  116. #error BUG: could not detect endianess
  117. #endif
  118. #if defined __IS_LITTLE_ENDIAN && defined __IS_BIG_ENDIAN
  119. #error BUG: both little & big endian detected in the same time
  120. #endif
  121. #endif /* _endianness_h */