postgresql/src/include/c.h

1054 lines
31 KiB
C
Raw Normal View History

1996-10-31 08:10:14 +01:00
/*-------------------------------------------------------------------------
*
* c.h
* Fundamental C definitions. This is included by every .c file in
* PostgreSQL (via either postgres.h or postgres_fe.h, as appropriate).
*
* Note that the definitions here are not intended to be exposed to clients
* of the frontend interface libraries --- so we don't worry much about
* polluting the namespace with lots of stuff...
1996-10-31 08:10:14 +01:00
*
*
* Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
1996-10-31 08:10:14 +01:00
*
2010-09-20 22:08:53 +02:00
* src/include/c.h
1996-10-31 08:10:14 +01:00
*
*-------------------------------------------------------------------------
*/
/*
*----------------------------------------------------------------
* TABLE OF CONTENTS
1996-10-31 08:10:14 +01:00
*
* When adding stuff to this file, please try to put stuff
* into the relevant section, or add new sections as appropriate.
1996-10-31 08:10:14 +01:00
*
* section description
* ------- ------------------------------------------------
* 0) pg_config.h and standard system headers
* 1) hacks to cope with non-ANSI C compilers
* 2) bool, true, false, TRUE, FALSE, NULL
* 3) standard system types
* 4) IsValid macros for system types
* 5) offsetof, lengthof, endof, alignment
* 6) assertions
* 7) widely useful macros
* 8) random stuff
* 9) system-specific hacks
1996-10-31 08:10:14 +01:00
*
* 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
* macros are the kind of thing that might go here.
*
*----------------------------------------------------------------
1996-10-31 08:10:14 +01:00
*/
#ifndef C_H
1996-10-31 08:10:14 +01:00
#define C_H
#include "postgres_ext.h"
/* Must undef pg_config_ext.h symbols before including pg_config.h */
#undef PG_INT64_TYPE
1999-07-17 06:12:10 +02:00
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
/*
* We always rely on the WIN32 macro being set by our build system,
* but _WIN32 is the compiler pre-defined macro. So make sure we define
* WIN32 whenever _WIN32 is set, to facilitate standalone building.
*/
#if defined(_WIN32) && !defined(WIN32)
#define WIN32
#endif
#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 includes further down */
#include "pg_config_os.h" /* must be before any system header files */
#endif
1999-07-17 06:12:10 +02:00
#if _MSC_VER >= 1400 || defined(HAVE_CRTDEFS_H)
#define errcode __msvc_errcode
#include <crtdefs.h>
#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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <stdarg.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
2002-08-21 19:20:58 +02:00
#include <sys/types.h>
1999-01-17 07:20:06 +01:00
#include <errno.h>
2004-09-09 02:59:49 +02:00
#if defined(WIN32) || defined(__CYGWIN__)
2003-08-04 02:43:34 +02:00
#include <fcntl.h> /* ensure O_BINARY is available */
#endif
1999-01-17 07:20:06 +01:00
#if defined(WIN32) || defined(__CYGWIN__)
/* We have to redefine some system functions after they are included above. */
#include "pg_config_os.h"
#endif
/* Must be before gettext() games below */
#include <locale.h>
2008-10-10 00:23:46 +02:00
#define _(x) gettext(x)
#ifdef ENABLE_NLS
#include <libintl.h>
#else
#define gettext(x) (x)
2008-10-10 00:23:46 +02:00
#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
2005-02-15 02:03:47 +01:00
/*
* Use this to mark string constants as needing translation at some later
* 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.
* http://www.gnu.org/software/autoconf/manual/gettext/Special-cases.html
2005-02-15 02:03:47 +01:00
*/
#define gettext_noop(x) (x)
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 1: hacks to cope with non-ANSI C compilers
1996-10-31 08:10:14 +01:00
*
* type prefixes (const, signed, volatile, inline) are handled in pg_config.h.
* ----------------------------------------------------------------
1996-10-31 08:10:14 +01:00
*/
/*
1999-05-25 18:15:34 +02:00
* CppAsString
* Convert the argument to a string, using the C preprocessor.
1999-05-25 18:15:34 +02:00
* CppConcat
* Concatenate two arguments together, using the C preprocessor.
*
* Note: There used to be support here for pre-ANSI C compilers that didn't
* support # and ##. Nowadays, these macros are just for clarity and/or
* backward compatibility with existing PostgreSQL code.
1996-10-31 08:10:14 +01:00
*/
#define CppAsString(identifier) #identifier
#define CppConcat(x, y) x##y
/*
* dummyret is used to set return values in macros that use ?: to make
* assignments. gcc wants these to be void, other compilers like char
*/
1999-05-25 18:15:34 +02:00
#ifdef __GNUC__ /* GNU cc */
#define dummyret void
#else
#define dummyret char
1996-10-31 08:10:14 +01:00
#endif
#ifndef __GNUC__
#define __attribute__(_arg_)
#endif
/* ----------------------------------------------------------------
* Section 2: bool, true, false, TRUE, FALSE, NULL
* ----------------------------------------------------------------
*/
/*
* bool
* Boolean value, either true or false.
*
* XXX for C++ compilers, we assume the compiler has a compatible
* built-in definition of bool.
*/
#ifndef __cplusplus
#ifndef bool
typedef char bool;
#endif
#ifndef true
#define true ((bool) 1)
#endif
#ifndef false
#define false ((bool) 0)
#endif
#endif /* not C++ */
typedef bool *BoolPtr;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/*
* NULL
* Null pointer.
*/
#ifndef NULL
#define NULL ((void *) 0)
#endif
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 3: standard system types
1996-10-31 08:10:14 +01:00
* ----------------------------------------------------------------
*/
/*
1999-05-25 18:15:34 +02:00
* Pointer
* Variable holding address of any memory resident object.
*
* XXX Pointer arithmetic is done with this, so it can't be void *
* under "true" ANSI compilers.
*/
typedef char *Pointer;
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* intN
* Signed integer, EXACTLY N BITS IN SIZE,
* used for numerical computations and the
* frontend/backend protocol.
1996-10-31 08:10:14 +01:00
*/
#ifndef HAVE_INT8
typedef signed char int8; /* == 8 bits */
typedef signed short int16; /* == 16 bits */
typedef signed int int32; /* == 32 bits */
2002-09-04 22:31:48 +02:00
#endif /* not HAVE_INT8 */
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* uintN
* Unsigned integer, EXACTLY N BITS IN SIZE,
* used for numerical computations and the
* frontend/backend protocol.
1996-10-31 08:10:14 +01:00
*/
#ifndef HAVE_UINT8
typedef unsigned char uint8; /* == 8 bits */
typedef unsigned short uint16; /* == 16 bits */
typedef unsigned int uint32; /* == 32 bits */
2002-09-04 22:31:48 +02:00
#endif /* not HAVE_UINT8 */
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* bitsN
* Unit of bitwise operation, AT LEAST N BITS IN SIZE.
1996-10-31 08:10:14 +01:00
*/
typedef uint8 bits8; /* >= 8 bits */
typedef uint16 bits16; /* >= 16 bits */
typedef uint32 bits32; /* >= 32 bits */
1996-10-31 08:10:14 +01:00
/*
* 64-bit integers
*/
#ifdef HAVE_LONG_INT_64
/* Plain "long int" fits, use it */
#ifndef HAVE_INT64
typedef long int int64;
#endif
#ifndef HAVE_UINT64
typedef unsigned long int uint64;
#endif
#elif defined(HAVE_LONG_LONG_INT_64)
/* We have working support for "long long int", use that */
#ifndef HAVE_INT64
typedef long long int int64;
#endif
#ifndef HAVE_UINT64
typedef unsigned long long int uint64;
#endif
#else
/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
#error must have a working 64-bit integer datatype
#endif
2001-03-22 05:01:46 +01:00
/* Decide if we need to decorate 64-bit constants */
#ifdef HAVE_LL_CONSTANTS
#define INT64CONST(x) ((int64) x##LL)
2004-09-26 17:13:42 +02:00
#define UINT64CONST(x) ((uint64) x##ULL)
#else
#define INT64CONST(x) ((int64) x)
#define UINT64CONST(x) ((uint64) x)
#endif
/* snprintf format strings to use for 64-bit integers */
#define INT64_FORMAT "%" INT64_MODIFIER "d"
#define UINT64_FORMAT "%" INT64_MODIFIER "u"
/* Select timestamp representation (float8 or int64) */
#ifdef USE_INTEGER_DATETIMES
Support alternate storage scheme of 64-bit integer for date/time types. Use "--enable-integer-datetimes" in configuration to use this rather than the original float8 storage. I would recommend the integer-based storage for any platform on which it is available. We perhaps should make this the default for the production release. Change timezone(timestamptz) results to return timestamp rather than a character string. Formerly, we didn't have a way to represent timestamps with an explicit time zone other than freezing the info into a string. Now, we can reasonably omit the explicit time zone from the result and return a timestamp with values appropriate for the specified time zone. Much cleaner, and if you need the time zone in the result you can put it into a character string pretty easily anyway. Allow fractional seconds in date/time types even for dates prior to 1BC. Limit timestamp data types to 6 decimal places of precision. Just right for a micro-second storage of int8 date/time types, and reduces the number of places ad-hoc rounding was occuring for the float8-based types. Use lookup tables for precision/rounding calculations for timestamp and interval types. Formerly used pow() to calculate the desired value but with a more limited range there is no reason to not type in a lookup table. Should be *much* better performance, though formerly there were some optimizations to help minimize the number of times pow() was called. Define a HAVE_INT64_TIMESTAMP variable. Based on the configure option "--enable-integer-datetimes" and the existing internal INT64_IS_BUSTED. Add explicit date/interval operators and functions for addition and subtraction. Formerly relied on implicit type promotion from date to timestamp with time zone. Change timezone conversion functions for the timetz type from "timetz()" to "timezone()". This is consistant with other time zone coersion functions for other types. Bump the catalog version to 200204201. Fix up regression tests to reflect changes in fractional seconds representation for date/times in BC eras. All regression tests pass on my Linux box.
2002-04-21 21:52:18 +02:00
#define HAVE_INT64_TIMESTAMP
#endif
/* sig_atomic_t is required by ANSI C, but may be missing on old platforms */
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
#endif
1996-10-31 08:10:14 +01:00
/*
* Size
* Size of any memory resident object, as returned by sizeof.
1996-10-31 08:10:14 +01:00
*/
typedef size_t Size;
/*
* Index
* Index into any memory resident array.
*
* Note:
* Indices are non negative.
*/
typedef unsigned int Index;
/*
* Offset
* Offset into any memory resident array.
*
* Note:
* This differs from an Index in that an Index is always
* non negative, whereas Offset may be negative.
*/
typedef signed int Offset;
/*
* Common Postgres datatype names (as used in the catalogs)
*/
typedef float float4;
typedef double float8;
/*
* Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
* CommandId
*/
/* typedef Oid is in postgres_ext.h */
/*
* regproc is the type name used in the include/catalog headers, but
* RegProcedure is the preferred name in C code.
*/
typedef Oid regproc;
typedef regproc RegProcedure;
typedef uint32 TransactionId;
typedef uint32 LocalTransactionId;
typedef uint32 SubTransactionId;
#define InvalidSubTransactionId ((SubTransactionId) 0)
#define TopSubTransactionId ((SubTransactionId) 1)
/* MultiXactId must be equivalent to TransactionId, to fit in t_xmax */
typedef TransactionId MultiXactId;
typedef uint32 MultiXactOffset;
typedef uint32 CommandId;
1996-10-31 08:10:14 +01:00
#define FirstCommandId ((CommandId) 0)
#define InvalidCommandId (~(CommandId)0)
1996-10-31 08:10:14 +01:00
/*
* Array indexing support
1996-10-31 08:10:14 +01:00
*/
#define MAXDIM 6
typedef struct
{
int indx[MAXDIM];
} IntArray;
1996-10-31 08:10:14 +01:00
/* ----------------
* Variable-length datatypes all share the 'struct varlena' header.
*
* NOTE: for TOASTable types, this is an oversimplification, since the value
* may be compressed or moved out-of-line. However datatype-specific routines
* are mostly content to deal with de-TOASTed values only, and of course
* client-side routines should never see a TOASTed value. But even in a
* de-TOASTed value, beware of touching vl_len_ directly, as its representation
* is no longer convenient. It's recommended that code always use the VARDATA,
* VARSIZE, and SET_VARSIZE macros instead of relying on direct mentions of
* the struct fields. See postgres.h for details of the TOASTed form.
* ----------------
1996-10-31 08:10:14 +01:00
*/
struct varlena
{
char vl_len_[4]; /* Do not touch this field directly! */
char vl_dat[1];
};
1996-10-31 08:10:14 +01:00
#define VARHDRSZ ((int32) sizeof(int32))
1996-10-31 08:10:14 +01:00
/*
* These widely-used datatypes are just a varlena header and the data bytes.
* There is no terminating null or anything like that --- the data length is
* always VARSIZE(ptr) - VARHDRSZ.
1996-10-31 08:10:14 +01:00
*/
typedef struct varlena bytea;
typedef struct varlena text;
typedef struct varlena BpChar; /* blank-padded char, ie SQL char(n) */
2001-03-22 05:01:46 +01:00
typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */
1996-10-31 08:10:14 +01:00
/*
* Specialized array types. These are physically laid out just the same
* as regular arrays (so that the regular array subscripting code works
* with them). They exist as distinct types mostly for historical reasons:
* they have nonstandard I/O behavior which we don't want to change for fear
* of breaking applications that look at the system catalogs. There is also
* an implementation issue for oidvector: it's part of the primary key for
* pg_proc, and we can't use the normal btree array support routines for that
* without circularity.
1996-10-31 08:10:14 +01:00
*/
typedef struct
{
int32 vl_len_; /* these fields must match ArrayType! */
int ndim; /* always 1 for int2vector */
int32 dataoffset; /* always 0 for int2vector */
Oid elemtype;
int dim1;
int lbound1;
int16 values[1]; /* VARIABLE LENGTH ARRAY */
} int2vector; /* VARIABLE LENGTH STRUCT */
1996-10-31 08:10:14 +01:00
typedef struct
{
int32 vl_len_; /* these fields must match ArrayType! */
int ndim; /* always 1 for oidvector */
int32 dataoffset; /* always 0 for oidvector */
Oid elemtype;
int dim1;
int lbound1;
Oid values[1]; /* VARIABLE LENGTH ARRAY */
} oidvector; /* VARIABLE LENGTH STRUCT */
1996-10-31 08:10:14 +01:00
/*
Reduce the alignment requirement of type "name" from int to char, and arrange to suppress zero-padding of "name" entries in indexes. The alignment change is unlikely to save any space, but it is really needed anyway to make the world safe for our widespread practice of passing plain old C strings to functions that are declared as taking Name. In the previous coding, the C compiler was entitled to assume that a Name pointer was word-aligned; but we were failing to guarantee that. I think the reason we'd not seen failures is that usually the only thing that gets done with such a pointer is strcmp(), which is hard to optimize in a way that exploits word-alignment. Still, some enterprising compiler guy will probably think of a way eventually, or we might change our code in a way that exposes more-obvious optimization opportunities. The padding change is accomplished in one-liner fashion by declaring the "name" index opclasses to use storage type "cstring" in pg_opclass.h. Normally btree and hash don't allow a nondefault storage type, because they don't have any provisions for converting the input datum to another type. However, because name and cstring are effectively the same thing except for padding, no conversion is needed --- we only need index_form_tuple() to treat the datum as being cstring not name, and this is sufficient. This seems to make for about a one-third reduction in the typical sizes of system catalog indexes that involve "name" columns, of which we have many. These two changes are only weakly related, but the alignment change makes me feel safer that the padding change won't introduce problems, so I'm committing them together.
2008-06-24 19:58:27 +02:00
* Representation of a Name: effectively just a C string, but null-padded to
* exactly NAMEDATALEN bytes. The use of a struct is historical.
*/
Reduce the alignment requirement of type "name" from int to char, and arrange to suppress zero-padding of "name" entries in indexes. The alignment change is unlikely to save any space, but it is really needed anyway to make the world safe for our widespread practice of passing plain old C strings to functions that are declared as taking Name. In the previous coding, the C compiler was entitled to assume that a Name pointer was word-aligned; but we were failing to guarantee that. I think the reason we'd not seen failures is that usually the only thing that gets done with such a pointer is strcmp(), which is hard to optimize in a way that exploits word-alignment. Still, some enterprising compiler guy will probably think of a way eventually, or we might change our code in a way that exposes more-obvious optimization opportunities. The padding change is accomplished in one-liner fashion by declaring the "name" index opclasses to use storage type "cstring" in pg_opclass.h. Normally btree and hash don't allow a nondefault storage type, because they don't have any provisions for converting the input datum to another type. However, because name and cstring are effectively the same thing except for padding, no conversion is needed --- we only need index_form_tuple() to treat the datum as being cstring not name, and this is sufficient. This seems to make for about a one-third reduction in the typical sizes of system catalog indexes that involve "name" columns, of which we have many. These two changes are only weakly related, but the alignment change makes me feel safer that the padding change won't introduce problems, so I'm committing them together.
2008-06-24 19:58:27 +02:00
typedef struct nameData
{
char data[NAMEDATALEN];
} NameData;
typedef NameData *Name;
#define NameStr(name) ((name).data)
/*
* Support macros for escaping strings. escape_backslash should be TRUE
* if generating a non-standard-conforming string. Prefixing a string
* with ESCAPE_STRING_SYNTAX guarantees it is non-standard-conforming.
* Beware of multiple evaluation of the "ch" argument!
*/
#define SQL_STR_DOUBLE(ch, escape_backslash) \
((ch) == '\'' || ((ch) == '\\' && (escape_backslash)))
2006-06-27 01:53:14 +02:00
#define ESCAPE_STRING_SYNTAX 'E'
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 4: IsValid macros for system types
1996-10-31 08:10:14 +01:00
* ----------------------------------------------------------------
*/
/*
1999-05-25 18:15:34 +02:00
* BoolIsValid
* True iff bool is valid.
1996-10-31 08:10:14 +01:00
*/
#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true)
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* PointerIsValid
* True iff pointer is valid.
1996-10-31 08:10:14 +01:00
*/
#define PointerIsValid(pointer) ((const void*)(pointer) != NULL)
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* PointerIsAligned
* True iff pointer is properly aligned to point to the given type.
1996-10-31 08:10:14 +01:00
*/
#define PointerIsAligned(pointer, type) \
(((uintptr_t)(pointer) % (sizeof (type))) == 0)
1996-10-31 08:10:14 +01:00
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
#define RegProcedureIsValid(p) OidIsValid(p)
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 5: offsetof, lengthof, endof, alignment
1996-10-31 08:10:14 +01:00
* ----------------------------------------------------------------
*/
/*
1999-05-25 18:15:34 +02:00
* offsetof
* Offset of a structure/union field within that structure/union.
1996-10-31 08:10:14 +01:00
*
* XXX This is supposed to be part of stddef.h, but isn't on
* some systems (like SunOS 4).
1996-10-31 08:10:14 +01:00
*/
#ifndef offsetof
#define offsetof(type, field) ((long) &((type *)0)->field)
#endif /* offsetof */
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* lengthof
* Number of elements in an array.
1996-10-31 08:10:14 +01:00
*/
#define lengthof(array) (sizeof (array) / sizeof ((array)[0]))
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* endof
* Address of the element one past the last in an array.
1996-10-31 08:10:14 +01:00
*/
#define endof(array) (&(array)[lengthof(array)])
1996-10-31 08:10:14 +01:00
/* ----------------
* Alignment macros: align a length or address appropriately for a given type.
* The fooALIGN() macros round up to a multiple of the required alignment,
* while the fooALIGN_DOWN() macros round down. The latter are more useful
* for problems like "how many X-sized structures will fit in a page?".
1996-10-31 08:10:14 +01:00
*
* NOTE: TYPEALIGN[_DOWN] will not work if ALIGNVAL is not a power of 2.
* That case seems extremely unlikely to be needed in practice, however.
* ----------------
1996-10-31 08:10:14 +01:00
*/
#define TYPEALIGN(ALIGNVAL,LEN) \
(((uintptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((uintptr_t) ((ALIGNVAL) - 1)))
1996-10-31 08:10:14 +01:00
#define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN))
#define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN))
#define LONGALIGN(LEN) TYPEALIGN(ALIGNOF_LONG, (LEN))
#define DOUBLEALIGN(LEN) TYPEALIGN(ALIGNOF_DOUBLE, (LEN))
#define MAXALIGN(LEN) TYPEALIGN(MAXIMUM_ALIGNOF, (LEN))
/* MAXALIGN covers only built-in types, not buffers */
#define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN))
#define CACHELINEALIGN(LEN) TYPEALIGN(PG_CACHE_LINE_SIZE, (LEN))
1996-10-31 08:10:14 +01:00
#define TYPEALIGN_DOWN(ALIGNVAL,LEN) \
(((uintptr_t) (LEN)) & ~((uintptr_t) ((ALIGNVAL) - 1)))
#define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN))
#define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN))
#define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_LONG, (LEN))
#define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN))
#define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN))
1996-10-31 08:10:14 +01:00
/*
* The above macros will not work with types wider than uintptr_t, like with
* uint64 on 32-bit platforms. That's not problem for the usual use where a
* pointer or a length is aligned, but for the odd case that you need to
* align something (potentially) wider, use TYPEALIGN64.
*/
#define TYPEALIGN64(ALIGNVAL,LEN) \
(((uint64) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64) ((ALIGNVAL) - 1)))
/* we don't currently need wider versions of the other ALIGN macros */
#define MAXALIGN64(LEN) TYPEALIGN64(MAXIMUM_ALIGNOF, (LEN))
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* 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) ((void)true)
#define AssertMacro(condition) ((void)true)
#define AssertArg(condition) ((void)true)
#define AssertState(condition) ((void)true)
Add a basic atomic ops API abstracting away platform/architecture details. Several upcoming performance/scalability improvements require atomic operations. This new API avoids the need to splatter compiler and architecture dependent code over all the locations employing atomic ops. For several of the potential usages it'd be problematic to maintain both, a atomics using implementation and one using spinlocks or similar. In all likelihood one of the implementations would not get tested regularly under concurrency. To avoid that scenario the new API provides a automatic fallback of atomic operations to spinlocks. All properties of atomic operations are maintained. This fallback - obviously - isn't as fast as just using atomic ops, but it's not bad either. For one of the future users the atomics ontop spinlocks implementation was actually slightly faster than the old purely spinlock using implementation. That's important because it reduces the fear of regressing older platforms when improving the scalability for new ones. The API, loosely modeled after the C11 atomics support, currently provides 'atomic flags' and 32 bit unsigned integers. If the platform efficiently supports atomic 64 bit unsigned integers those are also provided. To implement atomics support for a platform/architecture/compiler for a type of atomics 32bit compare and exchange needs to be implemented. If available and more efficient native support for flags, 32 bit atomic addition, and corresponding 64 bit operations may also be provided. Additional useful atomic operations are implemented generically ontop of these. The implementation for various versions of gcc, msvc and sun studio have been tested. Additional existing stub implementations for * Intel icc * HUPX acc * IBM xlc are included but have never been tested. These will likely require fixes based on buildfarm and user feedback. As atomic operations also require barriers for some operations the existing barrier support has been moved into the atomics code. Author: Andres Freund with contributions from Oskari Saarenmaa Reviewed-By: Amit Kapila, Robert Haas, Heikki Linnakangas and Álvaro Herrera Discussion: CA+TgmoYBW+ux5-8Ja=Mcyuy8=VXAnVRHp3Kess6Pn3DMXAPAEA@mail.gmail.com, 20131015123303.GH5300@awork2.anarazel.de, 20131028205522.GI20248@awork2.anarazel.de
2014-09-25 23:49:05 +02:00
#define AssertPointerAlignment(ptr, bndr) ((void)true)
#define Trap(condition, errorType) ((void)true)
#define TrapMacro(condition, errorType) (true)
#elif defined(FRONTEND)
#include <assert.h>
#define Assert(p) assert(p)
#define AssertMacro(p) ((void) assert(p))
#define AssertArg(condition) assert(condition)
#define AssertState(condition) assert(condition)
Add a basic atomic ops API abstracting away platform/architecture details. Several upcoming performance/scalability improvements require atomic operations. This new API avoids the need to splatter compiler and architecture dependent code over all the locations employing atomic ops. For several of the potential usages it'd be problematic to maintain both, a atomics using implementation and one using spinlocks or similar. In all likelihood one of the implementations would not get tested regularly under concurrency. To avoid that scenario the new API provides a automatic fallback of atomic operations to spinlocks. All properties of atomic operations are maintained. This fallback - obviously - isn't as fast as just using atomic ops, but it's not bad either. For one of the future users the atomics ontop spinlocks implementation was actually slightly faster than the old purely spinlock using implementation. That's important because it reduces the fear of regressing older platforms when improving the scalability for new ones. The API, loosely modeled after the C11 atomics support, currently provides 'atomic flags' and 32 bit unsigned integers. If the platform efficiently supports atomic 64 bit unsigned integers those are also provided. To implement atomics support for a platform/architecture/compiler for a type of atomics 32bit compare and exchange needs to be implemented. If available and more efficient native support for flags, 32 bit atomic addition, and corresponding 64 bit operations may also be provided. Additional useful atomic operations are implemented generically ontop of these. The implementation for various versions of gcc, msvc and sun studio have been tested. Additional existing stub implementations for * Intel icc * HUPX acc * IBM xlc are included but have never been tested. These will likely require fixes based on buildfarm and user feedback. As atomic operations also require barriers for some operations the existing barrier support has been moved into the atomics code. Author: Andres Freund with contributions from Oskari Saarenmaa Reviewed-By: Amit Kapila, Robert Haas, Heikki Linnakangas and Álvaro Herrera Discussion: CA+TgmoYBW+ux5-8Ja=Mcyuy8=VXAnVRHp3Kess6Pn3DMXAPAEA@mail.gmail.com, 20131015123303.GH5300@awork2.anarazel.de, 20131028205522.GI20248@awork2.anarazel.de
2014-09-25 23:49:05 +02:00
#define AssertPointerAlignment(ptr, bndr) ((void)true)
#else /* USE_ASSERT_CHECKING && !FRONTEND */
/*
* Trap
* Generates an exception if the given condition is true.
*/
#define Trap(condition, errorType) \
do { \
if (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) (! (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")
Add a basic atomic ops API abstracting away platform/architecture details. Several upcoming performance/scalability improvements require atomic operations. This new API avoids the need to splatter compiler and architecture dependent code over all the locations employing atomic ops. For several of the potential usages it'd be problematic to maintain both, a atomics using implementation and one using spinlocks or similar. In all likelihood one of the implementations would not get tested regularly under concurrency. To avoid that scenario the new API provides a automatic fallback of atomic operations to spinlocks. All properties of atomic operations are maintained. This fallback - obviously - isn't as fast as just using atomic ops, but it's not bad either. For one of the future users the atomics ontop spinlocks implementation was actually slightly faster than the old purely spinlock using implementation. That's important because it reduces the fear of regressing older platforms when improving the scalability for new ones. The API, loosely modeled after the C11 atomics support, currently provides 'atomic flags' and 32 bit unsigned integers. If the platform efficiently supports atomic 64 bit unsigned integers those are also provided. To implement atomics support for a platform/architecture/compiler for a type of atomics 32bit compare and exchange needs to be implemented. If available and more efficient native support for flags, 32 bit atomic addition, and corresponding 64 bit operations may also be provided. Additional useful atomic operations are implemented generically ontop of these. The implementation for various versions of gcc, msvc and sun studio have been tested. Additional existing stub implementations for * Intel icc * HUPX acc * IBM xlc are included but have never been tested. These will likely require fixes based on buildfarm and user feedback. As atomic operations also require barriers for some operations the existing barrier support has been moved into the atomics code. Author: Andres Freund with contributions from Oskari Saarenmaa Reviewed-By: Amit Kapila, Robert Haas, Heikki Linnakangas and Álvaro Herrera Discussion: CA+TgmoYBW+ux5-8Ja=Mcyuy8=VXAnVRHp3Kess6Pn3DMXAPAEA@mail.gmail.com, 20131015123303.GH5300@awork2.anarazel.de, 20131028205522.GI20248@awork2.anarazel.de
2014-09-25 23:49:05 +02:00
/*
* Check that `ptr' is `bndr' aligned.
*/
#define AssertPointerAlignment(ptr, bndr) \
Trap(TYPEALIGN(bndr, (uintptr_t)(ptr)) != (uintptr_t)(ptr), \
"UnalignedPointer")
#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
1996-10-31 08:10:14 +01:00
* ----------------------------------------------------------------
*/
/*
1999-05-25 18:15:34 +02:00
* Max
* Return the maximum of two numbers.
1996-10-31 08:10:14 +01:00
*/
#define Max(x, y) ((x) > (y) ? (x) : (y))
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* Min
* Return the minimum of two numbers.
1996-10-31 08:10:14 +01:00
*/
#define Min(x, y) ((x) < (y) ? (x) : (y))
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* Abs
* Return the absolute value of the argument.
1996-10-31 08:10:14 +01:00
*/
#define Abs(x) ((x) >= 0 ? (x) : -(x))
1996-10-31 08:10:14 +01:00
/*
1999-05-25 18:15:34 +02:00
* StrNCpy
* Like standard library function strncpy(), except that result string
* is guaranteed to be null-terminated --- that is, at most N-1 bytes
* of the source string will be kept.
* Also, the macro returns no result (too hard to do that without
* evaluating the arguments multiple times, which seems worse).
*
* BTW: when you need to copy a non-null-terminated string (like a text
* datum) and add a null, do not do it with StrNCpy(..., len+1). That
* might seem to work, but it fetches one byte more than there is in the
* text object. One fine day you'll have a SIGSEGV because there isn't
* another byte before the end of memory. Don't laugh, we've had real
* live bug reports from real live users over exactly this mistake.
* Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead.
*/
#define StrNCpy(dst,src,len) \
do \
{ \
char * _dst = (dst); \
Size _len = (len); \
\
if (_len > 0) \
{ \
strncpy(_dst, (src), _len); \
_dst[_len-1] = '\0'; \
} \
} while (0)
/* Get a bit mask of the bits set in non-long aligned addresses */
#define LONG_ALIGN_MASK (sizeof(long) - 1)
1998-02-11 22:38:08 +01:00
1998-02-11 22:45:40 +01:00
/*
* MemSet
* Exactly the same as standard library function memset(), but considerably
* faster for zeroing small word-aligned structures (such as parsetree nodes).
* This has to be a macro because the main point is to avoid function-call
* overhead. However, we have also found that the loop is faster than
2002-10-09 01:12:22 +02:00
* native libc memset() on some platforms, even those with assembler
* memset() functions. More research needs to be done, perhaps with
* MEMSET_LOOP_LIMIT tests in configure.
*/
#define MemSet(start, val, len) \
do \
{ \
2005-07-21 17:16:30 +02:00
/* must be void* because we don't know if it is integer aligned yet */ \
void *_vstart = (void *) (start); \
int _val = (val); \
Size _len = (len); \
\
if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \
(_len & LONG_ALIGN_MASK) == 0 && \
_val == 0 && \
_len <= MEMSET_LOOP_LIMIT && \
/* \
* If MEMSET_LOOP_LIMIT == 0, optimizer should find \
* the whole "if" false at compile time. \
*/ \
MEMSET_LOOP_LIMIT != 0) \
{ \
long *_start = (long *) _vstart; \
long *_stop = (long *) ((char *) _start + _len); \
while (_start < _stop) \
*_start++ = 0; \
} \
else \
memset(_vstart, _val, _len); \
} while (0)
/*
* MemSetAligned is the same as MemSet except it omits the test to see if
* "start" is word-aligned. This is okay to use if the caller knows a-priori
* that the pointer is suitably aligned (typically, because he just got it
* from palloc(), which always delivers a max-aligned pointer).
*/
#define MemSetAligned(start, val, len) \
do \
{ \
long *_start = (long *) (start); \
int _val = (val); \
Size _len = (len); \
\
if ((_len & LONG_ALIGN_MASK) == 0 && \
_val == 0 && \
_len <= MEMSET_LOOP_LIMIT && \
MEMSET_LOOP_LIMIT != 0) \
{ \
long *_stop = (long *) ((char *) _start + _len); \
while (_start < _stop) \
*_start++ = 0; \
} \
else \
memset(_start, _val, _len); \
} while (0)
/*
* MemSetTest/MemSetLoop are a variant version that allow all the tests in
* MemSet to be done at compile time in cases where "val" and "len" are
* constants *and* we know the "start" pointer must be word-aligned.
* If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use
* MemSetAligned. Beware of multiple evaluations of the arguments when using
* this approach.
*/
#define MemSetTest(val, len) \
( ((len) & LONG_ALIGN_MASK) == 0 && \
(len) <= MEMSET_LOOP_LIMIT && \
MEMSET_LOOP_LIMIT != 0 && \
(val) == 0 )
#define MemSetLoop(start, val, len) \
do \
{ \
long * _start = (long *) (start); \
long * _stop = (long *) ((char *) _start + (Size) (len)); \
\
while (_start < _stop) \
*_start++ = 0; \
} while (0)
1997-09-18 16:21:02 +02:00
Improve handling of ereport(ERROR) and elog(ERROR). In commit 71450d7fd6c7cf7b3e38ac56e363bff6a681973c, we added code to inform suitably-intelligent compilers that ereport() doesn't return if the elevel is ERROR or higher. This patch extends that to elog(), and also fixes a double-evaluation hazard that the previous commit created in ereport(), as well as reducing the emitted code size. The elog() improvement requires the compiler to support __VA_ARGS__, which should be available in just about anything nowadays since it's required by C99. But our minimum language baseline is still C89, so add a configure test for that. The previous commit assumed that ereport's elevel could be evaluated twice, which isn't terribly safe --- there are already counterexamples in xlog.c. On compilers that have __builtin_constant_p, we can use that to protect the second test, since there's no possible optimization gain if the compiler doesn't know the value of elevel. Otherwise, use a local variable inside the macros to prevent double evaluation. The local-variable solution is inferior because (a) it leads to useless code being emitted when elevel isn't constant, and (b) it increases the optimization level needed for the compiler to recognize that subsequent code is unreachable. But it seems better than not teaching non-gcc compilers about unreachability at all. Lastly, if the compiler has __builtin_unreachable(), we can use that instead of abort(), resulting in a noticeable code savings since no function call is actually emitted. However, it seems wise to do this only in non-assert builds. In an assert build, continue to use abort(), so that the behavior will be predictable and debuggable if the "impossible" happens. These changes involve making the ereport and elog macros emit do-while statement blocks not just expressions, which forces small changes in a few call sites. Andres Freund, Tom Lane, Heikki Linnakangas
2013-01-14 00:39:20 +01:00
/*
* 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()
2013-01-23 11:47:00 +01:00
#elif defined(_MSC_VER) && !defined(USE_ASSERT_CHECKING)
#define pg_unreachable() __assume(0)
Improve handling of ereport(ERROR) and elog(ERROR). In commit 71450d7fd6c7cf7b3e38ac56e363bff6a681973c, we added code to inform suitably-intelligent compilers that ereport() doesn't return if the elevel is ERROR or higher. This patch extends that to elog(), and also fixes a double-evaluation hazard that the previous commit created in ereport(), as well as reducing the emitted code size. The elog() improvement requires the compiler to support __VA_ARGS__, which should be available in just about anything nowadays since it's required by C99. But our minimum language baseline is still C89, so add a configure test for that. The previous commit assumed that ereport's elevel could be evaluated twice, which isn't terribly safe --- there are already counterexamples in xlog.c. On compilers that have __builtin_constant_p, we can use that to protect the second test, since there's no possible optimization gain if the compiler doesn't know the value of elevel. Otherwise, use a local variable inside the macros to prevent double evaluation. The local-variable solution is inferior because (a) it leads to useless code being emitted when elevel isn't constant, and (b) it increases the optimization level needed for the compiler to recognize that subsequent code is unreachable. But it seems better than not teaching non-gcc compilers about unreachability at all. Lastly, if the compiler has __builtin_unreachable(), we can use that instead of abort(), resulting in a noticeable code savings since no function call is actually emitted. However, it seems wise to do this only in non-assert builds. In an assert build, continue to use abort(), so that the behavior will be predictable and debuggable if the "impossible" happens. These changes involve making the ereport and elog macros emit do-while statement blocks not just expressions, which forces small changes in a few call sites. Andres Freund, Tom Lane, Heikki Linnakangas
2013-01-14 00:39:20 +01:00
#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.
*/
Add a basic atomic ops API abstracting away platform/architecture details. Several upcoming performance/scalability improvements require atomic operations. This new API avoids the need to splatter compiler and architecture dependent code over all the locations employing atomic ops. For several of the potential usages it'd be problematic to maintain both, a atomics using implementation and one using spinlocks or similar. In all likelihood one of the implementations would not get tested regularly under concurrency. To avoid that scenario the new API provides a automatic fallback of atomic operations to spinlocks. All properties of atomic operations are maintained. This fallback - obviously - isn't as fast as just using atomic ops, but it's not bad either. For one of the future users the atomics ontop spinlocks implementation was actually slightly faster than the old purely spinlock using implementation. That's important because it reduces the fear of regressing older platforms when improving the scalability for new ones. The API, loosely modeled after the C11 atomics support, currently provides 'atomic flags' and 32 bit unsigned integers. If the platform efficiently supports atomic 64 bit unsigned integers those are also provided. To implement atomics support for a platform/architecture/compiler for a type of atomics 32bit compare and exchange needs to be implemented. If available and more efficient native support for flags, 32 bit atomic addition, and corresponding 64 bit operations may also be provided. Additional useful atomic operations are implemented generically ontop of these. The implementation for various versions of gcc, msvc and sun studio have been tested. Additional existing stub implementations for * Intel icc * HUPX acc * IBM xlc are included but have never been tested. These will likely require fixes based on buildfarm and user feedback. As atomic operations also require barriers for some operations the existing barrier support has been moved into the atomics code. Author: Andres Freund with contributions from Oskari Saarenmaa Reviewed-By: Amit Kapila, Robert Haas, Heikki Linnakangas and Álvaro Herrera Discussion: CA+TgmoYBW+ux5-8Ja=Mcyuy8=VXAnVRHp3Kess6Pn3DMXAPAEA@mail.gmail.com, 20131015123303.GH5300@awork2.anarazel.de, 20131028205522.GI20248@awork2.anarazel.de
2014-09-25 23:49:05 +02:00
/* declarations which are only visible when not inlining and in the .c file */
#ifdef PG_USE_INLINE
#define STATIC_IF_INLINE static inline
#else
#define STATIC_IF_INLINE
#endif /* PG_USE_INLINE */
Add a basic atomic ops API abstracting away platform/architecture details. Several upcoming performance/scalability improvements require atomic operations. This new API avoids the need to splatter compiler and architecture dependent code over all the locations employing atomic ops. For several of the potential usages it'd be problematic to maintain both, a atomics using implementation and one using spinlocks or similar. In all likelihood one of the implementations would not get tested regularly under concurrency. To avoid that scenario the new API provides a automatic fallback of atomic operations to spinlocks. All properties of atomic operations are maintained. This fallback - obviously - isn't as fast as just using atomic ops, but it's not bad either. For one of the future users the atomics ontop spinlocks implementation was actually slightly faster than the old purely spinlock using implementation. That's important because it reduces the fear of regressing older platforms when improving the scalability for new ones. The API, loosely modeled after the C11 atomics support, currently provides 'atomic flags' and 32 bit unsigned integers. If the platform efficiently supports atomic 64 bit unsigned integers those are also provided. To implement atomics support for a platform/architecture/compiler for a type of atomics 32bit compare and exchange needs to be implemented. If available and more efficient native support for flags, 32 bit atomic addition, and corresponding 64 bit operations may also be provided. Additional useful atomic operations are implemented generically ontop of these. The implementation for various versions of gcc, msvc and sun studio have been tested. Additional existing stub implementations for * Intel icc * HUPX acc * IBM xlc are included but have never been tested. These will likely require fixes based on buildfarm and user feedback. As atomic operations also require barriers for some operations the existing barrier support has been moved into the atomics code. Author: Andres Freund with contributions from Oskari Saarenmaa Reviewed-By: Amit Kapila, Robert Haas, Heikki Linnakangas and Álvaro Herrera Discussion: CA+TgmoYBW+ux5-8Ja=Mcyuy8=VXAnVRHp3Kess6Pn3DMXAPAEA@mail.gmail.com, 20131015123303.GH5300@awork2.anarazel.de, 20131028205522.GI20248@awork2.anarazel.de
2014-09-25 23:49:05 +02:00
/* declarations which are marked inline when inlining, extern otherwise */
#ifdef PG_USE_INLINE
#define STATIC_IF_INLINE_DECLARE static inline
#else
#define STATIC_IF_INLINE_DECLARE extern
#endif /* PG_USE_INLINE */
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 8: random stuff
1996-10-31 08:10:14 +01:00
* ----------------------------------------------------------------
*/
/* msb for char */
#define HIGHBIT (0x80)
#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT)
1996-10-31 08:10:14 +01:00
#define STATUS_OK (0)
#define STATUS_ERROR (-1)
#define STATUS_EOF (-2)
#define STATUS_FOUND (1)
#define STATUS_WAITING (2)
1996-10-31 08:10:14 +01:00
/*
* 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 */
/*
* To better support parallel installations of major PostgeSQL
* versions as well as parallel installations of major library soname
* versions, we mangle the gettext domain name by appending those
* version numbers. The coding rule ought to be that whereever the
* domain name is mentioned as a literal, it must be wrapped into
* PG_TEXTDOMAIN(). The macros below do not work on non-literals; but
* that is somewhat intentional because it avoids having to worry
* about multiple states of premangling and postmangling as the values
* are being passed around.
*
* Make sure this matches the installation rules in nls-global.mk.
*/
/* need a second indirection because we want to stringize the macro value, not the name */
#define CppAsString2(x) CppAsString(x)
#ifdef SO_MAJOR_VERSION
#define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION)
#else
#define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION)
#endif
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 9: system-specific hacks
1996-10-31 08:10:14 +01:00
*
* This should be limited to things that absolutely have to be
* included in every source file. The port-specific header file
* is usually a better place for this sort of thing.
1996-10-31 08:10:14 +01:00
* ----------------------------------------------------------------
*/
/*
* NOTE: this is also used for opening text files.
2004-08-29 07:07:03 +02:00
* WIN32 treats Control-Z as EOF in files opened in text mode.
* Therefore, we open files in binary mode on Win32 so we can read
* literal control-Z. The other affect is that we see CRLF, but
2004-08-29 07:07:03 +02:00
* that is OK because we can already handle those cleanly.
*/
2004-09-09 02:59:49 +02:00
#if defined(WIN32) || defined(__CYGWIN__)
2000-06-02 18:40:09 +02:00
#define PG_BINARY O_BINARY
#define PG_BINARY_A "ab"
2001-03-22 05:01:46 +01:00
#define PG_BINARY_R "rb"
#define PG_BINARY_W "wb"
#else
2001-03-22 05:01:46 +01:00
#define PG_BINARY 0
#define PG_BINARY_A "a"
2001-03-22 05:01:46 +01:00
#define PG_BINARY_R "r"
#define PG_BINARY_W "w"
#endif
/*
* Provide prototypes for routines not present in a particular machine's
* standard C library.
*/
#if !HAVE_DECL_SNPRINTF
extern int
snprintf(char *str, size_t count, const char *fmt,...)
/* This extension allows gcc to check the format string */
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
#endif
#if !HAVE_DECL_VSNPRINTF
1999-05-25 18:15:34 +02:00
extern int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
#endif
1999-05-25 18:15:34 +02:00
#if !defined(HAVE_MEMMOVE) && !defined(memmove)
#define memmove(d, s, c) bcopy(s, d, c)
#endif
/* no special DLL markers on most ports */
#ifndef PGDLLIMPORT
#define PGDLLIMPORT
#endif
#ifndef PGDLLEXPORT
#define PGDLLEXPORT
#endif
/*
* The following is used as the arg list for signal handlers. Any ports
* that take something other than an int argument should override this in
* their pg_config_os.h file. Note that variable names are required
* because it is used in both the prototypes as well as the definitions.
* Note also the long name. We expect that this won't collide with
* other names causing compiler warnings.
2003-08-04 02:43:34 +02:00
*/
#ifndef SIGNAL_ARGS
#define SIGNAL_ARGS int postgres_signal_arg
#endif
/*
* When there is no sigsetjmp, its functionality is provided by plain
* setjmp. Incidentally, nothing provides setjmp's functionality in
* that case.
*/
#ifndef HAVE_SIGSETJMP
2003-08-04 02:43:34 +02:00
#define sigjmp_buf jmp_buf
#define sigsetjmp(x,y) setjmp(x)
#define siglongjmp longjmp
#endif
#if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC
2003-08-04 02:43:34 +02:00
extern int fdatasync(int fildes);
#endif
/* If strtoq() exists, rename it to the more standard strtoll() */
#if defined(HAVE_LONG_LONG_INT_64) && !defined(HAVE_STRTOLL) && defined(HAVE_STRTOQ)
2003-08-04 02:43:34 +02:00
#define strtoll strtoq
#define HAVE_STRTOLL 1
#endif
/* If strtouq() exists, rename it to the more standard strtoull() */
#if defined(HAVE_LONG_LONG_INT_64) && !defined(HAVE_STRTOULL) && defined(HAVE_STRTOUQ)
2003-08-04 02:43:34 +02:00
#define strtoull strtouq
#define HAVE_STRTOULL 1
#endif
/*
* We assume if we have these two functions, we have their friends too, and
* can use the wide-character functions.
*/
#if defined(HAVE_WCSTOMBS) && defined(HAVE_TOWLOWER)
#define USE_WIDE_UPPER_LOWER
#endif
/* EXEC_BACKEND defines */
#ifdef EXEC_BACKEND
#define NON_EXEC_STATIC
#else
#define NON_EXEC_STATIC static
#endif
/* /port compatibility functions */
#include "port.h"
#endif /* C_H */