#ifndef lib_pcap_compiler_tests_h
#define lib_pcap_compiler_tests_h
-
/*
* This was introduced by Clang:
*
- * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
+ * https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
*
* in some version (which version?); it has been picked up by GCC 5.0.
*/
#define __has_attribute(x) 0
#endif
+/*
+ * Note that the C90 spec's "6.8.1 Conditional inclusion" and the
+ * C99 spec's and C11 spec's "6.10.1 Conditional inclusion" say:
+ *
+ * Prior to evaluation, macro invocations in the list of preprocessing
+ * tokens that will become the controlling constant expression are
+ * replaced (except for those macro names modified by the defined unary
+ * operator), just as in normal text. If the token "defined" is
+ * generated as a result of this replacement process or use of the
+ * "defined" unary operator does not match one of the two specified
+ * forms prior to macro replacement, the behavior is undefined.
+ *
+ * so you shouldn't use defined() in a #define that's used in #if or
+ * #elif. Some versions of Clang, for example, will warn about this.
+ *
+ * Instead, we check whether the pre-defined macros for particular
+ * compilers are defined and, if not, define the "is this version XXX
+ * or a later version of this compiler" macros as 0.
+ */
+
/*
* Check whether this is GCC major.minor or a later release, or some
* compiler that claims to be "just like GCC" of that version or a
* later release.
*/
-#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 3))
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_2_3 1
-#else
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_2_3 0
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_2_5 1
-#else
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_2_5 0
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_3_1 1
+#if ! defined(__GNUC__)
+ /* Not GCC and not "just like GCC" */
+ #define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) 0
#else
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_3_1 0
+ /* GCC or "just like GCC" */
+ #define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) \
+ (__GNUC__ > (major) || \
+ (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#endif
-#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_3_4 1
-#else
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_3_4 0
-#endif
+/*
+ * Check whether this is Clang major.minor or a later release.
+ */
-#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_4_5 1
+#if !defined(__clang__)
+ /* Not Clang */
+ #define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) 0
#else
-#define PCAP_IS_AT_LEAST_GNUC_VERSION_4_5 0
+ /* Clang */
+ #define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) \
+ (__clang_major__ > (major) || \
+ (__clang_major__ == (major) && __clang_minor__ >= (minor)))
#endif
/*
- * Check wehether this is Sun C/SunPro C/Oracle Studio major.minor
+ * Check whether this is Sun C/SunPro C/Oracle Studio major.minor
* or a later release.
*
* The version number in __SUNPRO_C is encoded in hex BCD, with the
* for a partial mapping, which we assume continues for later
* 12.x product releases.
*/
-#define PCAP_SUNPRO_VERSION_TO_BCD(major, minor) \
+
+#if ! defined(__SUNPRO_C)
+ /* Not Sun/Oracle C */
+ #define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) 0
+#else
+ /* Sun/Oracle C */
+ #define PCAP_SUNPRO_VERSION_TO_BCD(major, minor) \
(((minor) >= 10) ? \
(((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \
(((major) << 8) | ((minor) << 4)))
-
-#if defined(__SUNPRO_C) && __SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD(5, 5)
-#define PCAP_IS_AT_LEAST_SUNC_VERSION_5_5 1
-#else
-#define PCAP_IS_AT_LEAST_SUNC_VERSION_5_5 0
-#endif
-
-#if defined(__SUNPRO_C) && __SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD(5, 9)
-#define PCAP_IS_AT_LEAST_SUNC_VERSION_5_9 1
-#else
-#define PCAP_IS_AT_LEAST_SUNC_VERSION_5_9 0
-#endif
-
-#if defined(__SUNPRO_C) && __SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD(5, 13)
-#define PCAP_IS_AT_LEAST_SUNC_VERSION_5_13 1
-#else
-#define PCAP_IS_AT_LEAST_SUNC_VERSION_5_13 0
+ #define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) \
+ (__SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD((major), (minor)))
#endif
/*
- * Check wehether this is IBM XL C major.minor or a later release.
+ * Check whether this is IBM XL C major.minor or a later release.
*
* The version number in __xlC__ has the major version in the
* upper 8 bits and the minor version in the lower 8 bits.
+ * On AIX __xlC__ is always defined, __ibmxl__ becomes defined in XL C 16.1.
+ * On Linux since XL C 13.1.6 __xlC__ is not defined by default anymore, but
+ * __ibmxl__ is defined since at least XL C 13.1.1.
*/
-#if defined(__xlC__) && __xlC__ >= ((10 << 8) | 1)
-#define PCAP_IS_AT_LEAST_XL_C_VERSION_10_1 1
+#if ! defined(__xlC__) && ! defined(__ibmxl__)
+ /* Not XL C */
+ #define PCAP_IS_AT_LEAST_XL_C_VERSION(major,minor) 0
#else
-#define PCAP_IS_AT_LEAST_XL_C_VERSION_10_1 0
-#endif
-
-#if defined(__xlC__) && __xlC__ >= ((12 << 8) | 0)
-#define PCAP_IS_AT_LEAST_XL_C_VERSION_12_0 1
-#else
-#define PCAP_IS_AT_LEAST_XL_C_VERSION_12_0 0
+ /* XL C */
+ #if defined(__ibmxl__)
+ /*
+ * Later Linux version of XL C; use __ibmxl_version__ to test
+ * the version.
+ */
+ #define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \
+ (__ibmxl_version__ > (major) || \
+ (__ibmxl_version__ == (major) && __ibmxl_release__ >= (minor)))
+ #else /* __ibmxl__ */
+ /*
+ * __ibmxl__ not defined; use __xlC__ to test the version.
+ */
+ #define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \
+ (__xlC__ >= (((major) << 8) | (minor)))
+ #endif /* __ibmxl__ */
#endif
/*
- * Check wehether this is Sun C/SunPro C/Oracle Studio major.minor
- * or a later release.
+ * Check whether this is HP aC++/HP C major.minor or a later release.
*
* The version number in __HP_aCC is encoded in zero-padded decimal BCD,
* with the "A." stripped off, the uppermost two decimal digits being
* number, and add two digits of patch.)
*/
-#if defined(__HP_aCC) && (__HP_aCC >= (6*10000 + 10*100))
-#define PCAP_IS_AT_LEAST_HP_C_VERSION_6_10 1
+#if ! defined(__HP_aCC)
+ /* Not HP C */
+ #define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) 0
#else
-#define PCAP_IS_AT_LEAST_HP_C_VERSION_6_10 0
+ /* HP C */
+ #define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) \
+ (__HP_aCC >= ((major)*10000 + (minor)*100))
#endif
-#endif /* lib_pcap_funcattrs_h */
+#endif /* lib_pcap_compiler_tests_h */