nkeynes@362: /* ANSI and traditional C compatability macros nkeynes@362: Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 nkeynes@362: Free Software Foundation, Inc. nkeynes@362: This file is part of the GNU C Library. nkeynes@362: nkeynes@362: This program is free software; you can redistribute it and/or modify nkeynes@362: it under the terms of the GNU General Public License as published by nkeynes@362: the Free Software Foundation; either version 2 of the License, or nkeynes@362: (at your option) any later version. nkeynes@362: nkeynes@362: This program is distributed in the hope that it will be useful, nkeynes@362: but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@362: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@362: GNU General Public License for more details. nkeynes@362: nkeynes@362: You should have received a copy of the GNU General Public License nkeynes@362: along with this program; if not, write to the Free Software nkeynes@362: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ nkeynes@362: nkeynes@362: /* ANSI and traditional C compatibility macros nkeynes@362: nkeynes@362: ANSI C is assumed if __STDC__ is #defined. nkeynes@362: nkeynes@362: Macro ANSI C definition Traditional C definition nkeynes@362: ----- ---- - ---------- ----------- - ---------- nkeynes@362: ANSI_PROTOTYPES 1 not defined nkeynes@362: PTR `void *' `char *' nkeynes@362: PTRCONST `void *const' `char *' nkeynes@362: LONG_DOUBLE `long double' `double' nkeynes@362: const not defined `' nkeynes@362: volatile not defined `' nkeynes@362: signed not defined `' nkeynes@362: VA_START(ap, var) va_start(ap, var) va_start(ap) nkeynes@362: nkeynes@362: Note that it is safe to write "void foo();" indicating a function nkeynes@362: with no return value, in all K+R compilers we have been able to test. nkeynes@362: nkeynes@362: For declaring functions with prototypes, we also provide these: nkeynes@362: nkeynes@362: PARAMS ((prototype)) nkeynes@362: -- for functions which take a fixed number of arguments. Use this nkeynes@362: when declaring the function. When defining the function, write a nkeynes@362: K+R style argument list. For example: nkeynes@362: nkeynes@362: char *strcpy PARAMS ((char *dest, char *source)); nkeynes@362: ... nkeynes@362: char * nkeynes@362: strcpy (dest, source) nkeynes@362: char *dest; nkeynes@362: char *source; nkeynes@362: { ... } nkeynes@362: nkeynes@362: nkeynes@362: VPARAMS ((prototype, ...)) nkeynes@362: -- for functions which take a variable number of arguments. Use nkeynes@362: PARAMS to declare the function, VPARAMS to define it. For example: nkeynes@362: nkeynes@362: int printf PARAMS ((const char *format, ...)); nkeynes@362: ... nkeynes@362: int nkeynes@362: printf VPARAMS ((const char *format, ...)) nkeynes@362: { nkeynes@362: ... nkeynes@362: } nkeynes@362: nkeynes@362: For writing functions which take variable numbers of arguments, we nkeynes@362: also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These nkeynes@362: hide the differences between K+R and C89 more nkeynes@362: thoroughly than the simple VA_START() macro mentioned above. nkeynes@362: nkeynes@362: VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end. nkeynes@362: Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls nkeynes@362: corresponding to the list of fixed arguments. Then use va_arg nkeynes@362: normally to get the variable arguments, or pass your va_list object nkeynes@362: around. You do not declare the va_list yourself; VA_OPEN does it nkeynes@362: for you. nkeynes@362: nkeynes@362: Here is a complete example: nkeynes@362: nkeynes@362: int nkeynes@362: printf VPARAMS ((const char *format, ...)) nkeynes@362: { nkeynes@362: int result; nkeynes@362: nkeynes@362: VA_OPEN (ap, format); nkeynes@362: VA_FIXEDARG (ap, const char *, format); nkeynes@362: nkeynes@362: result = vfprintf (stdout, format, ap); nkeynes@362: VA_CLOSE (ap); nkeynes@362: nkeynes@362: return result; nkeynes@362: } nkeynes@362: nkeynes@362: nkeynes@362: You can declare variables either before or after the VA_OPEN, nkeynes@362: VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning nkeynes@362: and end of a block. They must appear at the same nesting level, nkeynes@362: and any variables declared after VA_OPEN go out of scope at nkeynes@362: VA_CLOSE. Unfortunately, with a K+R compiler, that includes the nkeynes@362: argument list. You can have multiple instances of VA_OPEN/VA_CLOSE nkeynes@362: pairs in a single function in case you need to traverse the nkeynes@362: argument list more than once. nkeynes@362: nkeynes@362: For ease of writing code which uses GCC extensions but needs to be nkeynes@362: portable to other compilers, we provide the GCC_VERSION macro that nkeynes@362: simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various nkeynes@362: wrappers around __attribute__. Also, __extension__ will be #defined nkeynes@362: to nothing if it doesn't work. See below. nkeynes@362: nkeynes@362: This header also defines a lot of obsolete macros: nkeynes@362: CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID, nkeynes@362: AND, DOTS, NOARGS. Don't use them. */ nkeynes@362: nkeynes@362: #ifndef _ANSIDECL_H nkeynes@362: #define _ANSIDECL_H 1 nkeynes@362: nkeynes@362: /* Every source file includes this file, nkeynes@362: so they will all get the switch for lint. */ nkeynes@362: /* LINTLIBRARY */ nkeynes@362: nkeynes@362: /* Using MACRO(x,y) in cpp #if conditionals does not work with some nkeynes@362: older preprocessors. Thus we can't define something like this: nkeynes@362: nkeynes@362: #define HAVE_GCC_VERSION(MAJOR, MINOR) \ nkeynes@362: (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) nkeynes@362: nkeynes@362: and then test "#if HAVE_GCC_VERSION(2,7)". nkeynes@362: nkeynes@362: So instead we use the macro below and test it against specific values. */ nkeynes@362: nkeynes@362: /* This macro simplifies testing whether we are using gcc, and if it nkeynes@362: is of a particular minimum version. (Both major & minor numbers are nkeynes@362: significant.) This macro will evaluate to 0 if we are not using nkeynes@362: gcc at all. */ nkeynes@362: #ifndef GCC_VERSION nkeynes@362: #define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) nkeynes@362: #endif /* GCC_VERSION */ nkeynes@362: nkeynes@362: #if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus)) nkeynes@362: /* All known AIX compilers implement these things (but don't always nkeynes@362: define __STDC__). The RISC/OS MIPS compiler defines these things nkeynes@362: in SVR4 mode, but does not define __STDC__. */ nkeynes@362: /* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other nkeynes@362: C++ compilers, does not define __STDC__, though it acts as if this nkeynes@362: was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */ nkeynes@362: nkeynes@362: #define ANSI_PROTOTYPES 1 nkeynes@362: #define PTR void * nkeynes@362: #define PTRCONST void *const nkeynes@362: #define LONG_DOUBLE long double nkeynes@362: nkeynes@362: /* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in nkeynes@362: a #ifndef. */ nkeynes@362: #ifndef PARAMS nkeynes@362: #define PARAMS(ARGS) ARGS nkeynes@362: #endif nkeynes@362: nkeynes@362: #define VPARAMS(ARGS) ARGS nkeynes@362: #define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) nkeynes@362: nkeynes@362: /* variadic function helper macros */ nkeynes@362: /* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's nkeynes@362: use without inhibiting further decls and without declaring an nkeynes@362: actual variable. */ nkeynes@362: #define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy nkeynes@362: #define VA_CLOSE(AP) } va_end(AP); } nkeynes@362: #define VA_FIXEDARG(AP, T, N) struct Qdmy nkeynes@362: nkeynes@362: #undef const nkeynes@362: #undef volatile nkeynes@362: #undef signed nkeynes@362: nkeynes@362: /* inline requires special treatment; it's in C99, and GCC >=2.7 supports nkeynes@362: it too, but it's not in C89. */ nkeynes@362: #undef inline nkeynes@362: #if __STDC_VERSION__ > 199901L nkeynes@362: /* it's a keyword */ nkeynes@362: #else nkeynes@362: # if GCC_VERSION >= 2007 nkeynes@362: # define inline __inline__ /* __inline__ prevents -pedantic warnings */ nkeynes@362: # else nkeynes@362: # define inline /* nothing */ nkeynes@362: # endif nkeynes@362: #endif nkeynes@362: nkeynes@362: /* These are obsolete. Do not use. */ nkeynes@362: #ifndef IN_GCC nkeynes@362: #define CONST const nkeynes@362: #define VOLATILE volatile nkeynes@362: #define SIGNED signed nkeynes@362: nkeynes@362: #define PROTO(type, name, arglist) type name arglist nkeynes@362: #define EXFUN(name, proto) name proto nkeynes@362: #define DEFUN(name, arglist, args) name(args) nkeynes@362: #define DEFUN_VOID(name) name(void) nkeynes@362: #define AND , nkeynes@362: #define DOTS , ... nkeynes@362: #define NOARGS void nkeynes@362: #endif /* ! IN_GCC */ nkeynes@362: nkeynes@362: #else /* Not ANSI C. */ nkeynes@362: nkeynes@362: #undef ANSI_PROTOTYPES nkeynes@362: #define PTR char * nkeynes@362: #define PTRCONST PTR nkeynes@362: #define LONG_DOUBLE double nkeynes@362: nkeynes@362: #define PARAMS(args) () nkeynes@362: #define VPARAMS(args) (va_alist) va_dcl nkeynes@362: #define VA_START(va_list, var) va_start(va_list) nkeynes@362: nkeynes@362: #define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy nkeynes@362: #define VA_CLOSE(AP) } va_end(AP); } nkeynes@362: #define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE) nkeynes@362: nkeynes@362: /* some systems define these in header files for non-ansi mode */ nkeynes@362: #undef const nkeynes@362: #undef volatile nkeynes@362: #undef signed nkeynes@362: #undef inline nkeynes@362: #define const nkeynes@362: #define volatile nkeynes@362: #define signed nkeynes@362: #define inline nkeynes@362: nkeynes@362: #ifndef IN_GCC nkeynes@362: #define CONST nkeynes@362: #define VOLATILE nkeynes@362: #define SIGNED nkeynes@362: nkeynes@362: #define PROTO(type, name, arglist) type name () nkeynes@362: #define EXFUN(name, proto) name() nkeynes@362: #define DEFUN(name, arglist, args) name arglist args; nkeynes@362: #define DEFUN_VOID(name) name() nkeynes@362: #define AND ; nkeynes@362: #define DOTS nkeynes@362: #define NOARGS nkeynes@362: #endif /* ! IN_GCC */ nkeynes@362: nkeynes@362: #endif /* ANSI C. */ nkeynes@362: nkeynes@362: /* Define macros for some gcc attributes. This permits us to use the nkeynes@362: macros freely, and know that they will come into play for the nkeynes@362: version of gcc in which they are supported. */ nkeynes@362: nkeynes@362: #if (GCC_VERSION < 2007) nkeynes@362: # define __attribute__(x) nkeynes@362: #endif nkeynes@362: nkeynes@362: /* Attribute __malloc__ on functions was valid as of gcc 2.96. */ nkeynes@362: #ifndef ATTRIBUTE_MALLOC nkeynes@362: # if (GCC_VERSION >= 2096) nkeynes@362: # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) nkeynes@362: # else nkeynes@362: # define ATTRIBUTE_MALLOC nkeynes@362: # endif /* GNUC >= 2.96 */ nkeynes@362: #endif /* ATTRIBUTE_MALLOC */ nkeynes@362: nkeynes@362: /* Attributes on labels were valid as of gcc 2.93. */ nkeynes@362: #ifndef ATTRIBUTE_UNUSED_LABEL nkeynes@362: # if (GCC_VERSION >= 2093) nkeynes@362: # define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED nkeynes@362: # else nkeynes@362: # define ATTRIBUTE_UNUSED_LABEL nkeynes@362: # endif /* GNUC >= 2.93 */ nkeynes@362: #endif /* ATTRIBUTE_UNUSED_LABEL */ nkeynes@362: nkeynes@362: #ifndef ATTRIBUTE_UNUSED nkeynes@362: #define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) nkeynes@362: #endif /* ATTRIBUTE_UNUSED */ nkeynes@362: nkeynes@362: /* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the nkeynes@362: identifier name. */ nkeynes@362: #if ! defined(__cplusplus) || (GCC_VERSION >= 3004) nkeynes@362: # define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED nkeynes@362: #else /* !__cplusplus || GNUC >= 3.4 */ nkeynes@362: # define ARG_UNUSED(NAME) NAME nkeynes@362: #endif /* !__cplusplus || GNUC >= 3.4 */ nkeynes@362: nkeynes@362: #ifndef ATTRIBUTE_NORETURN nkeynes@362: #define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) nkeynes@362: #endif /* ATTRIBUTE_NORETURN */ nkeynes@362: nkeynes@362: /* Attribute `nonnull' was valid as of gcc 3.3. */ nkeynes@362: #ifndef ATTRIBUTE_NONNULL nkeynes@362: # if (GCC_VERSION >= 3003) nkeynes@362: # define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m))) nkeynes@362: # else nkeynes@362: # define ATTRIBUTE_NONNULL(m) nkeynes@362: # endif /* GNUC >= 3.3 */ nkeynes@362: #endif /* ATTRIBUTE_NONNULL */ nkeynes@362: nkeynes@362: /* Attribute `pure' was valid as of gcc 3.0. */ nkeynes@362: #ifndef ATTRIBUTE_PURE nkeynes@362: # if (GCC_VERSION >= 3000) nkeynes@362: # define ATTRIBUTE_PURE __attribute__ ((__pure__)) nkeynes@362: # else nkeynes@362: # define ATTRIBUTE_PURE nkeynes@362: # endif /* GNUC >= 3.0 */ nkeynes@362: #endif /* ATTRIBUTE_PURE */ nkeynes@362: nkeynes@362: /* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. nkeynes@362: This was the case for the `printf' format attribute by itself nkeynes@362: before GCC 3.3, but as of 3.3 we need to add the `nonnull' nkeynes@362: attribute to retain this behavior. */ nkeynes@362: #ifndef ATTRIBUTE_PRINTF nkeynes@362: #define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) nkeynes@362: #define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) nkeynes@362: #define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) nkeynes@362: #define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) nkeynes@362: #define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) nkeynes@362: #define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) nkeynes@362: #endif /* ATTRIBUTE_PRINTF */ nkeynes@362: nkeynes@362: /* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A nkeynes@362: NULL format specifier was allowed as of gcc 3.3. */ nkeynes@362: #ifndef ATTRIBUTE_NULL_PRINTF nkeynes@362: # if (GCC_VERSION >= 3003) nkeynes@362: # define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) nkeynes@362: # else nkeynes@362: # define ATTRIBUTE_NULL_PRINTF(m, n) nkeynes@362: # endif /* GNUC >= 3.3 */ nkeynes@362: # define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2) nkeynes@362: # define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3) nkeynes@362: # define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4) nkeynes@362: # define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5) nkeynes@362: # define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) nkeynes@362: #endif /* ATTRIBUTE_NULL_PRINTF */ nkeynes@362: nkeynes@362: /* Attribute `sentinel' was valid as of gcc 3.5. */ nkeynes@362: #ifndef ATTRIBUTE_SENTINEL nkeynes@362: # if (GCC_VERSION >= 3005) nkeynes@362: # define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) nkeynes@362: # else nkeynes@362: # define ATTRIBUTE_SENTINEL nkeynes@362: # endif /* GNUC >= 3.5 */ nkeynes@362: #endif /* ATTRIBUTE_SENTINEL */ nkeynes@362: nkeynes@362: /* We use __extension__ in some places to suppress -pedantic warnings nkeynes@362: about GCC extensions. This feature didn't work properly before nkeynes@362: gcc 2.8. */ nkeynes@362: #if GCC_VERSION < 2008 nkeynes@362: #define __extension__ nkeynes@362: #endif nkeynes@362: nkeynes@362: #endif /* ansidecl.h */