1 /* 2 * Portability macros used in include files. 3 * 4 * The canonical version of this file is maintained in the rra-c-util package, 5 * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>. 6 * 7 * Written by Russ Allbery <eagle@eyrie.org> 8 * Copyright 2015 Russ Allbery <eagle@eyrie.org> 9 * Copyright 2008, 2011-2012 10 * The Board of Trustees of the Leland Stanford Junior University 11 * 12 * Copying and distribution of this file, with or without modification, are 13 * permitted in any medium without royalty provided the copyright notice and 14 * this notice are preserved. This file is offered as-is, without any 15 * warranty. 16 * 17 * SPDX-License-Identifier: FSFAP 18 */ 19 20 #ifndef PORTABLE_MACROS_H 21 #define PORTABLE_MACROS_H 1 22 23 /* 24 * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7 25 * could you use the __format__ form of the attributes, which is what we use 26 * (to avoid confusion with other macros). 27 */ 28 #ifndef __attribute__ 29 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) 30 # define __attribute__(spec) /* empty */ 31 # endif 32 #endif 33 34 /* 35 * We use __alloc_size__, but it was only available in fairly recent versions 36 * of GCC. Suppress warnings about the unknown attribute if GCC is too old. 37 * We know that we're GCC at this point, so we can use the GCC variadic macro 38 * extension, which will still work with versions of GCC too old to have C99 39 * variadic macro support. 40 */ 41 #if !defined(__attribute__) && !defined(__alloc_size__) 42 # if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)) \ 43 && !defined(__clang__) 44 # define __alloc_size__(spec, args...) /* empty */ 45 # endif 46 #endif 47 48 /* 49 * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ 50 * settings that GCC does. For them, suppress warnings about unknown 51 * attributes on declarations. This unfortunately will affect the entire 52 * compilation context, but there's no push and pop available. 53 */ 54 #if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__)) 55 # pragma GCC diagnostic ignored "-Wattributes" 56 #endif 57 58 /* 59 * BEGIN_DECLS is used at the beginning of declarations so that C++ 60 * compilers don't mangle their names. END_DECLS is used at the end. 61 */ 62 #undef BEGIN_DECLS 63 #undef END_DECLS 64 #ifdef __cplusplus 65 # define BEGIN_DECLS extern "C" { 66 # define END_DECLS } 67 #else 68 # define BEGIN_DECLS /* empty */ 69 # define END_DECLS /* empty */ 70 #endif 71 72 #endif /* !PORTABLE_MACROS_H */ 73