X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/14c81f0a4aa300f7ea23af6130469f97d8b18793..c7dfcd6aaff12a95f7feaf237f8fa219a8752a1e:/netdissect-stdinc.h diff --git a/netdissect-stdinc.h b/netdissect-stdinc.h index 9b88ce9e..d78b6639 100644 --- a/netdissect-stdinc.h +++ b/netdissect-stdinc.h @@ -41,6 +41,10 @@ #include +#include "compiler-tests.h" + +#include "varattrs.h" + /* * Get the C99 types, and the PRI[doux]64 format strings, defined. */ @@ -85,6 +89,11 @@ typedef unsigned long long uint64_t; typedef long long int64_t; #endif + + /* + * We have _strtoi64(). Use that for strtoint64_t(). + */ + #define strtoint64_t _strtoi64 #endif /* @@ -164,12 +173,59 @@ #include #ifdef _MSC_VER -#define stat _stat -#define open _open -#define fstat _fstat -#define read _read -#define close _close -#define O_RDONLY _O_RDONLY + /* + * Compiler is MSVC. + */ + #if _MSC_VER >= 1800 + /* + * VS 2013 or newer; we have strtoll(). Use that for strtoint64_t(). + */ + #define strtoint64_t strtoll + #else + /* + * Earlier VS; we don't have strtoll(), but we do have + * _strtoi64(). Use that for strtoint64_t(). + */ + #define strtoint64_t _strtoi64 + #endif + + /* + * Microsoft's documentation doesn't speak of LL as a valid + * suffix for 64-bit integers, so we'll just use i64. + */ + #define INT64_T_CONSTANT(constant) (constant##i64) +#else + /* + * Non-Microsoft compiler. + * + * XXX - should we use strtoll or should we use _strtoi64()? + */ + #define strtoint64_t strtoll + + /* + * Assume LL works. + */ + #define INT64_T_CONSTANT(constant) (constant##LL) +#endif + +#ifdef _MSC_VER + #define stat _stat + #define strdup _strdup + #define open _open + #define fstat _fstat + #define read _read + #define close _close + #define O_RDONLY _O_RDONLY + + /* + * If has been included, and _DEBUG is defined, and + * __STDC__ is zero, will define strdup() to call + * _strdup_dbg(). So if it's already defined, don't redefine + * it. + */ + #ifndef strdup + #define strdup _strdup + #endif #endif /* _MSC_VER */ /* @@ -179,7 +235,7 @@ #define inline __inline #endif -#ifdef AF_INET6 +#if defined(AF_INET6) && !defined(HAVE_OS_IPV6_SUPPORT) #define HAVE_OS_IPV6_SUPPORT #endif @@ -200,7 +256,6 @@ typedef char* caddr_t; #define MAXHOSTNAMELEN 64 #define snprintf _snprintf #define vsnprintf _vsnprintf -#define RETSIGTYPE void #else /* _WIN32 */ @@ -217,54 +272,53 @@ typedef char* caddr_t; #include #include -#ifdef TIME_WITH_SYS_TIME #include -#endif #include +/* + * Assume all UN*Xes have strtoll(), and use it for strtoint64_t(). + */ +#define strtoint64_t strtoll + +/* + * Assume LL works. + */ +#define INT64_T_CONSTANT(constant) (constant##LL) + #endif /* _WIN32 */ -#ifndef HAVE___ATTRIBUTE__ -#define __attribute__(x) -#endif +/* + * Function attributes, for various compilers. + */ +#include "funcattrs.h" /* - * Used to declare a structure unaligned, so that the C compiler, - * if necessary, generates code that doesn't assume alignment. - * This is required because there is no guarantee that the packet - * data we get from libpcap/WinPcap is properly aligned. + * On Windows, snprintf(), with that name and with C99 behavior - i.e., + * guaranteeing that the formatted string is null-terminated - didn't + * appear until Visual Studio 2015. Prior to that, the C runtime had + * only _snprintf(), which *doesn't* guarantee that the string is + * null-terminated if it is truncated due to the buffer being too + * small. We therefore can't just define snprintf to be _snprintf + * and define vsnprintf to be _vsnprintf, as we're relying on null- + * termination of strings in all cases. * - * This assumes that, for all compilers that support __attribute__: + * We also want to allow this to be built with versions of Visual Studio + * prior to VS 2015, so we can't rely on snprintf() being present. * - * 1) they support __attribute__((packed)); - * - * 2) for all instruction set architectures requiring strict - * alignment, declaring a structure with that attribute - * causes the compiler to generate code that handles - * misaligned 2-byte, 4-byte, and 8-byte integral - * quantities. - * - * It does not (yet) handle compilers where you can get the compiler - * to generate code of that sort by some other means. - * - * This is required in order to, for example, keep the compiler from - * generating, for - * - * if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { - * - * in print-bootp.c, code that loads the first 4-byte word of a - * "struct bootp", masking out the bp_hops field, and comparing the result - * against 0x01010600. - * - * Note: this also requires that padding be put into the structure, - * at least for compilers where it's implemented as __attribute__((packed)). + * And, if there are any UN*Xes out there on which we can run that + * don't have snprintf() or don't have vsnprintf(), we define our + * own as well. */ -#if !(defined(_MSC_VER) && defined(UNALIGNED)) -/* MSVC may have its own macro defined with the same name and purpose. */ -#undef UNALIGNED -#define UNALIGNED __attribute__((packed)) -#endif +#if !defined(HAVE_SNPRINTF) +int snprintf (char *str, size_t sz, FORMAT_STRING(const char *format), ...) + PRINTFLIKE(3, 4); +#endif /* !defined(HAVE_SNPRINTF) */ + +#if !defined(HAVE_VSNPRINTF) +int vsnprintf (char *str, size_t sz, FORMAT_STRING(const char *format), + va_list ap) PRINTFLIKE(3, 0); +#endif /* !defined(HAVE_VSNPRINTF) */ /* * fopen() read and write modes for text files and binary files. @@ -287,8 +341,8 @@ typedef char* caddr_t; * an 80386, so, for example, it avoids the bswap instruction added in * the 80486. * - * (We don't use them on OS X; Apple provides their own, which *doesn't* - * avoid the bswap instruction, as OS X only supports machines that + * (We don't use them on macOS; Apple provides their own, which *doesn't* + * avoid the bswap instruction, as macOS only supports machines that * have it.) */ #if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl) @@ -373,7 +427,20 @@ struct in6_addr { #define DIAG_JOINSTR(x,y) XSTRINGIFY(x ## y) #define DIAG_DO_PRAGMA(x) _Pragma (#x) -#if defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 +/* + * The current clang compilers also define __GNUC__ and __GNUC_MINOR__ + * thus we need to test the clang case before the GCC one + */ +#if defined(__clang__) +# if (__clang_major__ * 100) + __clang_minor__ >= 208 +# define DIAG_PRAGMA(x) DIAG_DO_PRAGMA(clang diagnostic x) +# define DIAG_OFF(x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x)) +# define DIAG_ON(x) DIAG_PRAGMA(pop) +# else +# define DIAG_OFF(x) +# define DIAG_ON(x) +# endif +#elif defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 # define DIAG_PRAGMA(x) DIAG_DO_PRAGMA(GCC diagnostic x) # if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 # define DIAG_OFF(x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x)) @@ -382,15 +449,20 @@ struct in6_addr { # define DIAG_OFF(x) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x)) # define DIAG_ON(x) DIAG_PRAGMA(warning DIAG_JOINSTR(-W,x)) # endif -#elif defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__ >= 208) -# define DIAG_PRAGMA(x) DIAG_DO_PRAGMA(clang diagnostic x) -# define DIAG_OFF(x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x)) -# define DIAG_ON(x) DIAG_PRAGMA(pop) #else # define DIAG_OFF(x) # define DIAG_ON(x) #endif +/* Use for clang specific warnings */ +#ifdef __clang__ +# define DIAG_OFF_CLANG(x) DIAG_OFF(x) +# define DIAG_ON_CLANG(x) DIAG_ON(x) +#else +# define DIAG_OFF_CLANG(x) +# define DIAG_ON_CLANG(x) +#endif + /* * For dealing with APIs which are only deprecated in OSX (like the OpenSSL API) */ @@ -407,21 +479,17 @@ struct in6_addr { */ /* - * Function attributes, for various compilers. + * Statement attributes, for various compilers. + * + * This was introduced sufficiently recently that compilers implementing + * it also implement __has_attribute() (for example, GCC 5.0 and later + * have __has_attribute(), and the "fallthrough" attribute was introduced + * in GCC 7). */ -#include "funcattrs.h" - -#ifndef min -#define min(a,b) ((a)>(b)?(b):(a)) -#endif -#ifndef max -#define max(a,b) ((b)>(a)?(b):(a)) -#endif - -#ifdef __ATTRIBUTE___FALLTHROUGH_OK +#if __has_attribute(fallthrough) # define ND_FALL_THROUGH __attribute__ ((fallthrough)) #else # define ND_FALL_THROUGH -#endif /* __ATTRIBUTE___FALLTHROUGH_OK */ +#endif /* __has_attribute(fallthrough) */ #endif /* netdissect_stdinc_h */