]> The Tcpdump Group git mirrors - libpcap/blobdiff - pcap/compiler-tests.h
Make sure no read routine process more than INT_MAX packets.
[libpcap] / pcap / compiler-tests.h
index 03ef7b4a897eff9b3b7d55d1b98de24a0f20498a..2d98a707051115ab8bb0f77948c855cb21eb50a4 100644 (file)
 #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 */