X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=src%2Finclude%2Fc.h;h=596118342dfc4e4ba32741a9a9f3296747047ce8;hb=5ee73525d57380a55b5c87f8df1c30bd32fb98b3;hp=7bcc6351f070f579dd0ec9db992f617e1cec7a13;hpb=d9346f2186c51fbc7d3351d7e00d84e937c80925;p=postgresql diff --git a/src/include/c.h b/src/include/c.h index 7bcc6351f0..596118342d 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -9,10 +9,10 @@ * polluting the namespace with lots of stuff... * * - * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/c.h,v 1.233 2008/12/11 10:25:17 petere Exp $ + * src/include/c.h * *------------------------------------------------------------------------- */ @@ -31,9 +31,10 @@ * 3) standard system types * 4) IsValid macros for system types * 5) offsetof, lengthof, endof, alignment - * 6) widely useful macros - * 7) random stuff - * 8) system-specific hacks + * 6) assertions + * 7) widely useful macros + * 8) random stuff + * 9) system-specific hacks * * NOTE: since this file is included by both frontend and backend modules, it's * almost certainly wrong to put an "extern" declaration here. typedefs and @@ -44,26 +45,30 @@ #ifndef C_H #define C_H -/* - * We have to include stdlib.h here because it defines many of these macros - * on some platforms, and we only want our definitions used if stdlib.h doesn't - * have its own. The same goes for stddef and stdarg if present. - */ +#include "postgres_ext.h" + +/* Must undef pg_config_ext.h symbols before including pg_config.h */ +#undef PG_INT64_TYPE #include "pg_config.h" #include "pg_config_manual.h" /* must be after pg_config.h */ -#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 will include further - * down */ + +#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 includes further down */ #include "pg_config_os.h" /* must be before any system header files */ #endif -#include "postgres_ext.h" -#if _MSC_VER >= 1400 +#if _MSC_VER >= 1400 || defined(HAVE_CRTDEFS_H) #define errcode __msvc_errcode #include #undef errcode #endif +/* + * We have to include stdlib.h here because it defines many of these macros + * on some platforms, and we only want our definitions used if stdlib.h doesn't + * have its own. The same goes for stddef and stdarg if present. + */ + #include #include #include @@ -72,15 +77,15 @@ #ifdef HAVE_STRINGS_H #include #endif +#ifdef HAVE_STDINT_H +#include +#endif #include #include #if defined(WIN32) || defined(__CYGWIN__) #include /* ensure O_BINARY is available */ #endif -#ifdef HAVE_SUPPORTDEFS_H -#include -#endif #if defined(WIN32) || defined(__CYGWIN__) /* We have to redefine some system functions after they are included above. */ @@ -97,11 +102,13 @@ #else #define gettext(x) (x) #define dgettext(d,x) (x) +#define ngettext(s,p,n) ((n) == 1 ? (s) : (p)) +#define dngettext(d,s,p,n) ((n) == 1 ? (s) : (p)) #endif /* * Use this to mark string constants as needing translation at some later - * time, rather than immediately. This is useful for cases where you need + * time, rather than immediately. This is useful for cases where you need * access to the original string and translated string, and for cases where * immediate translation is not possible, like when initializing global * variables. @@ -274,21 +281,11 @@ typedef long long int int64; #ifndef HAVE_UINT64 typedef unsigned long long int uint64; #endif -#else /* not HAVE_LONG_INT_64 and not - * HAVE_LONG_LONG_INT_64 */ - -/* Won't actually work, but fall back to long int so that code compiles */ -#ifndef HAVE_INT64 -typedef long int int64; -#endif -#ifndef HAVE_UINT64 -typedef unsigned long int uint64; +#else +/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */ +#error must have a working 64-bit integer datatype #endif -#define INT64_IS_BUSTED -#endif /* not HAVE_LONG_INT_64 and not - * HAVE_LONG_LONG_INT_64 */ - /* Decide if we need to decorate 64-bit constants */ #ifdef HAVE_LL_CONSTANTS #define INT64CONST(x) ((int64) x##LL) @@ -300,7 +297,7 @@ typedef unsigned long int uint64; /* Select timestamp representation (float8 or int64) */ -#if defined(USE_INTEGER_DATETIMES) && !defined(INT64_IS_BUSTED) +#ifdef USE_INTEGER_DATETIMES #define HAVE_INT64_TIMESTAMP #endif @@ -337,8 +334,6 @@ typedef signed int Offset; /* * Common Postgres datatype names (as used in the catalogs) */ -typedef int16 int2; -typedef int32 int4; typedef float float4; typedef double float8; @@ -432,7 +427,7 @@ typedef struct Oid elemtype; int dim1; int lbound1; - int2 values[1]; /* VARIABLE LENGTH ARRAY */ + int16 values[1]; /* VARIABLE LENGTH ARRAY */ } int2vector; /* VARIABLE LENGTH STRUCT */ typedef struct @@ -483,14 +478,14 @@ typedef NameData *Name; * PointerIsValid * True iff pointer is valid. */ -#define PointerIsValid(pointer) ((void*)(pointer) != NULL) +#define PointerIsValid(pointer) ((const void*)(pointer) != NULL) /* * PointerIsAligned * True iff pointer is properly aligned to point to the given type. */ #define PointerIsAligned(pointer, type) \ - (((long)(pointer) % (sizeof (type))) == 0) + (((intptr_t)(pointer) % (sizeof (type))) == 0) #define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) @@ -536,7 +531,7 @@ typedef NameData *Name; */ #define TYPEALIGN(ALIGNVAL,LEN) \ - (((long) (LEN) + ((ALIGNVAL) - 1)) & ~((long) ((ALIGNVAL) - 1))) + (((intptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((intptr_t) ((ALIGNVAL) - 1))) #define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN)) #define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN)) @@ -547,7 +542,7 @@ typedef NameData *Name; #define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN)) #define TYPEALIGN_DOWN(ALIGNVAL,LEN) \ - (((long) (LEN)) & ~((long) ((ALIGNVAL) - 1))) + (((intptr_t) (LEN)) & ~((intptr_t) ((ALIGNVAL) - 1))) #define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN)) #define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN)) @@ -556,7 +551,134 @@ typedef NameData *Name; #define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN)) /* ---------------------------------------------------------------- - * Section 6: widely useful macros + * Section 6: assertions + * ---------------------------------------------------------------- + */ + +/* + * USE_ASSERT_CHECKING, if defined, turns on all the assertions. + * - plai 9/5/90 + * + * It should _NOT_ be defined in releases or in benchmark copies + */ + +/* + * Assert() can be used in both frontend and backend code. In frontend code it + * just calls the standard assert, if it's available. If use of assertions is + * not configured, it does nothing. + */ +#ifndef USE_ASSERT_CHECKING + +#define Assert(condition) +#define AssertMacro(condition) ((void)true) +#define AssertArg(condition) +#define AssertState(condition) +#define Trap(condition, errorType) +#define TrapMacro(condition, errorType) (true) + +#elif defined(FRONTEND) + +#include +#define Assert(p) assert(p) +#define AssertMacro(p) ((void) assert(p)) +#define AssertArg(condition) assert(condition) +#define AssertState(condition) assert(condition) +#else /* USE_ASSERT_CHECKING && !FRONTEND */ + +/* + * Trap + * Generates an exception if the given condition is true. + */ +#define Trap(condition, errorType) \ + do { \ + if ((assert_enabled) && (condition)) \ + ExceptionalCondition(CppAsString(condition), (errorType), \ + __FILE__, __LINE__); \ + } while (0) + +/* + * TrapMacro is the same as Trap but it's intended for use in macros: + * + * #define foo(x) (AssertMacro(x != 0), bar(x)) + * + * Isn't CPP fun? + */ +#define TrapMacro(condition, errorType) \ + ((bool) ((! assert_enabled) || ! (condition) || \ + (ExceptionalCondition(CppAsString(condition), (errorType), \ + __FILE__, __LINE__), 0))) + +#define Assert(condition) \ + Trap(!(condition), "FailedAssertion") + +#define AssertMacro(condition) \ + ((void) TrapMacro(!(condition), "FailedAssertion")) + +#define AssertArg(condition) \ + Trap(!(condition), "BadArgument") + +#define AssertState(condition) \ + Trap(!(condition), "BadState") +#endif /* USE_ASSERT_CHECKING && !FRONTEND */ + + +/* + * Macros to support compile-time assertion checks. + * + * If the "condition" (a compile-time-constant expression) evaluates to false, + * throw a compile error using the "errmessage" (a string literal). + * + * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic + * placement restrictions. These macros make it safe to use as a statement + * or in an expression, respectively. + * + * Otherwise we fall back on a kluge that assumes the compiler will complain + * about a negative width for a struct bit-field. This will not include a + * helpful error message, but it beats not getting an error at all. + */ +#ifdef HAVE__STATIC_ASSERT +#define StaticAssertStmt(condition, errmessage) \ + do { _Static_assert(condition, errmessage); } while(0) +#define StaticAssertExpr(condition, errmessage) \ + ({ StaticAssertStmt(condition, errmessage); true; }) +#else /* !HAVE__STATIC_ASSERT */ +#define StaticAssertStmt(condition, errmessage) \ + ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) +#define StaticAssertExpr(condition, errmessage) \ + StaticAssertStmt(condition, errmessage) +#endif /* HAVE__STATIC_ASSERT */ + + +/* + * Compile-time checks that a variable (or expression) has the specified type. + * + * AssertVariableIsOfType() can be used as a statement. + * AssertVariableIsOfTypeMacro() is intended for use in macros, eg + * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) + * + * If we don't have __builtin_types_compatible_p, we can still assert that + * the types have the same size. This is far from ideal (especially on 32-bit + * platforms) but it provides at least some coverage. + */ +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + ((void) StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename))) +#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(sizeof(varname) == sizeof(typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + ((void) StaticAssertExpr(sizeof(varname) == sizeof(typename), \ + CppAsString(varname) " does not have type " CppAsString(typename))) +#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ + + +/* ---------------------------------------------------------------- + * Section 7: widely useful macros * ---------------------------------------------------------------- */ /* @@ -628,7 +750,7 @@ typedef NameData *Name; int _val = (val); \ Size _len = (len); \ \ - if ((((long) _vstart) & LONG_ALIGN_MASK) == 0 && \ + if ((((intptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \ (_len & LONG_ALIGN_MASK) == 0 && \ _val == 0 && \ _len <= MEMSET_LOOP_LIMIT && \ @@ -699,8 +821,40 @@ typedef NameData *Name; } while (0) +/* + * Mark a point as unreachable in a portable fashion. This should preferably + * be something that the compiler understands, to aid code generation. + * In assert-enabled builds, we prefer abort() for debugging reasons. + */ +#if defined(HAVE__BUILTIN_UNREACHABLE) && !defined(USE_ASSERT_CHECKING) +#define pg_unreachable() __builtin_unreachable() +#elif defined(_MSC_VER) && !defined(USE_ASSERT_CHECKING) +#define pg_unreachable() __assume(0) +#else +#define pg_unreachable() abort() +#endif + + +/* + * Function inlining support -- Allow modules to define functions that may be + * inlined, if the compiler supports it. + * + * The function bodies must be defined in the module header prefixed by + * STATIC_IF_INLINE, protected by a cpp symbol that the module's .c file must + * define. If the compiler doesn't support inline functions, the function + * definitions are pulled in by the .c file as regular (not inline) symbols. + * + * The header must also declare the functions' prototypes, protected by + * !PG_USE_INLINE. + */ +#ifdef PG_USE_INLINE +#define STATIC_IF_INLINE static inline +#else +#define STATIC_IF_INLINE +#endif /* PG_USE_INLINE */ + /* ---------------------------------------------------------------- - * Section 7: random stuff + * Section 8: random stuff * ---------------------------------------------------------------- */ @@ -715,6 +869,18 @@ typedef NameData *Name; #define STATUS_WAITING (2) +/* + * Append PG_USED_FOR_ASSERTS_ONLY to definitions of variables that are only + * used in assert-enabled builds, to avoid compiler warnings about unused + * variables in assert-disabled builds. + */ +#ifdef USE_ASSERT_CHECKING +#define PG_USED_FOR_ASSERTS_ONLY +#else +#define PG_USED_FOR_ASSERTS_ONLY __attribute__((unused)) +#endif + + /* gettext domain name mangling */ /* @@ -735,14 +901,14 @@ typedef NameData *Name; #define CppAsString2(x) CppAsString(x) #ifdef SO_MAJOR_VERSION -# define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION) +#define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION) #else -# define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION) +#define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION) #endif /* ---------------------------------------------------------------- - * Section 8: system-specific hacks + * Section 9: system-specific hacks * * This should be limited to things that absolutely have to be * included in every source file. The port-specific header file @@ -778,7 +944,7 @@ typedef NameData *Name; extern int snprintf(char *str, size_t count, const char *fmt,...) /* This extension allows gcc to check the format string */ -__attribute__((format(printf, 3, 4))); +__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4))); #endif #if !HAVE_DECL_VSNPRINTF @@ -789,8 +955,12 @@ extern int vsnprintf(char *str, size_t count, const char *fmt, va_list args); #define memmove(d, s, c) bcopy(s, d, c) #endif +/* no special DLL markers on most ports */ #ifndef PGDLLIMPORT -#define PGDLLIMPORT /* no special DLL markers on most ports */ +#define PGDLLIMPORT +#endif +#ifndef PGDLLEXPORT +#define PGDLLEXPORT #endif /* @@ -840,7 +1010,7 @@ extern int fdatasync(int fildes); #if defined(HAVE_WCSTOMBS) && defined(HAVE_TOWLOWER) #define USE_WIDE_UPPER_LOWER #endif - + /* EXEC_BACKEND defines */ #ifdef EXEC_BACKEND #define NON_EXEC_STATIC