* polluting the namespace with lots of stuff...
*
*
- * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/c.h,v 1.190 2005/10/15 02:49:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.239 2010/01/07 04:53:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
-#if !defined(WIN32) && !defined(__CYGWIN__)
+#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 will include further
+ * down */
#include "pg_config_os.h" /* must be before any system header files */
-#else
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-#define WIN32_CLIENT_ONLY
-#endif
#endif
#include "postgres_ext.h"
+#if _MSC_VER >= 1400
+#define errcode __msvc_errcode
+#include <crtdefs.h>
+#undef errcode
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#include <sys/types.h>
#include <errno.h>
#endif
#if defined(WIN32) || defined(__CYGWIN__)
-#ifndef WIN32_CLIENT_ONLY
-/* We have to redefine some system functions after they are included above */
+/* We have to redefine some system functions after they are included above. */
#include "pg_config_os.h"
-#else
-#include "port/win32.h" /* We didn't run configure, but this is our
- * port file */
-#endif
#endif
/* Must be before gettext() games below */
#include <locale.h>
-#define _(x) gettext((x))
+#define _(x) gettext(x)
#ifdef ENABLE_NLS
#include <libintl.h>
#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
/*
- * These strings are to be translation via xgettext. We can't
- * call gettext() because it is located in variable initialization and
- * a function call can not be used.
+ * 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
*/
#define gettext_noop(x) (x)
* built-in definition of bool.
*/
-/* BeOS defines bool already, but the compiler chokes on the
- * #ifndef unless we wrap it in this check.
- */
-#ifndef __BEOS__
-
#ifndef __cplusplus
#ifndef bool
#define false ((bool) 0)
#endif
#endif /* not C++ */
-#endif /* __BEOS__ */
typedef bool *BoolPtr;
typedef uint16 bits16; /* >= 16 bits */
typedef uint32 bits32; /* >= 32 bits */
-/*
- * floatN
- * Floating point number, AT LEAST N BITS IN SIZE,
- * used for numerical computations.
- *
- * Since sizeof(floatN) may be > sizeof(char *), always pass
- * floatN by reference.
- *
- * XXX: these typedefs are now deprecated in favor of float4 and float8.
- * They will eventually go away.
- */
-typedef float float32data;
-typedef double float64data;
-typedef float *float32;
-typedef double *float64;
-
/*
* 64-bit integers
*/
#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_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)
/* Select timestamp representation (float8 or int64) */
-#if defined(USE_INTEGER_DATETIMES) && !defined(INT64_IS_BUSTED)
+#ifdef USE_INTEGER_DATETIMES
#define HAVE_INT64_TIMESTAMP
#endif
typedef uint32 TransactionId;
+typedef uint32 LocalTransactionId;
+
typedef uint32 SubTransactionId;
#define InvalidSubTransactionId ((SubTransactionId) 0)
* 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. See postgres.h for
- * details of the TOASTed form.
+ * 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.
* ----------------
*/
struct varlena
{
- int32 vl_len;
+ char vl_len_[4]; /* Do not touch this field directly! */
char vl_dat[1];
};
*/
typedef struct
{
- int32 size; /* these fields must match ArrayType! */
- int ndim;
- int flags;
+ 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;
typedef struct
{
- int32 size; /* these fields must match ArrayType! */
- int ndim;
- int flags;
+ 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;
} oidvector; /* VARIABLE LENGTH STRUCT */
/*
- * We want NameData to have length NAMEDATALEN and int alignment,
- * because that's how the data type 'name' is defined in pg_type.
- * Use a union to make sure the compiler agrees. Note that NAMEDATALEN
- * must be a multiple of sizeof(int), else sizeof(NameData) will probably
- * not come out equal to NAMEDATALEN.
+ * Representation of a Name: effectively just a C string, but null-padded to
+ * exactly NAMEDATALEN bytes. The use of a struct is historical.
*/
-typedef union nameData
+typedef struct nameData
{
char data[NAMEDATALEN];
- int alignmentDummy;
} NameData;
typedef NameData *Name;
#define NameStr(name) ((name).data)
-#define SQL_STR_DOUBLE(ch) ((ch) == '\'' || (ch) == '\\')
+/*
+ * 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)))
+
#define ESCAPE_STRING_SYNTAX 'E'
/* ----------------------------------------------------------------
* 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))
/* ----------------
* 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?".
*
- * There used to be some incredibly crufty platform-dependent hackery here,
- * but now we rely on the configure script to get the info for us. Much nicer.
- *
- * NOTE: TYPEALIGN will not work if ALIGNVAL is not a power of 2.
- * That case seems extremely unlikely to occur in practice, however.
+ * 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.
* ----------------
*/
#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))
/* MAXALIGN covers only built-in types, not buffers */
#define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN))
+#define TYPEALIGN_DOWN(ALIGNVAL,LEN) \
+ (((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))
+#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))
/* ----------------------------------------------------------------
* Section 6: widely useful macros
} while (0)
-/* Get a bit mask of the bits set in non-int32 aligned addresses */
-#define INT_ALIGN_MASK (sizeof(int32) - 1)
+/* Get a bit mask of the bits set in non-long aligned addresses */
+#define LONG_ALIGN_MASK (sizeof(long) - 1)
/*
* MemSet
* overhead. However, we have also found that the loop is faster than
* native libc memset() on some platforms, even those with assembler
* memset() functions. More research needs to be done, perhaps with
- * platform-specific MEMSET_LOOP_LIMIT values or tests in configure.
- *
- * bjm 2002-10-08
+ * MEMSET_LOOP_LIMIT tests in configure.
*/
#define MemSet(start, val, len) \
do \
int _val = (val); \
Size _len = (len); \
\
- if ((((long) _vstart) & INT_ALIGN_MASK) == 0 && \
- (_len & INT_ALIGN_MASK) == 0 && \
+ if ((((intptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \
+ (_len & LONG_ALIGN_MASK) == 0 && \
_val == 0 && \
- _len <= MEMSET_LOOP_LIMIT) \
+ _len <= MEMSET_LOOP_LIMIT && \
+ /* \
+ * If MEMSET_LOOP_LIMIT == 0, optimizer should find \
+ * the whole "if" false at compile time. \
+ */ \
+ MEMSET_LOOP_LIMIT != 0) \
{ \
- int32 *_start = (int32 *) _vstart; \
- int32 *_stop = (int32 *) ((char *) _start + _len); \
+ long *_start = (long *) _vstart; \
+ long *_stop = (long *) ((char *) _start + _len); \
while (_start < _stop) \
*_start++ = 0; \
} \
memset(_vstart, _val, _len); \
} while (0)
-#define MEMSET_LOOP_LIMIT 1024
-
/*
* 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
#define MemSetAligned(start, val, len) \
do \
{ \
- int32 *_start = (int32 *) (start); \
+ long *_start = (long *) (start); \
int _val = (val); \
Size _len = (len); \
\
- if ((_len & INT_ALIGN_MASK) == 0 && \
+ if ((_len & LONG_ALIGN_MASK) == 0 && \
_val == 0 && \
- _len <= MEMSET_LOOP_LIMIT) \
+ _len <= MEMSET_LOOP_LIMIT && \
+ MEMSET_LOOP_LIMIT != 0) \
{ \
- int32 *_stop = (int32 *) ((char *) _start + _len); \
+ long *_stop = (long *) ((char *) _start + _len); \
while (_start < _stop) \
*_start++ = 0; \
} \
* this approach.
*/
#define MemSetTest(val, len) \
- ( ((len) & INT_ALIGN_MASK) == 0 && \
+ ( ((len) & LONG_ALIGN_MASK) == 0 && \
(len) <= MEMSET_LOOP_LIMIT && \
+ MEMSET_LOOP_LIMIT != 0 && \
(val) == 0 )
#define MemSetLoop(start, val, len) \
do \
{ \
- int32 * _start = (int32 *) (start); \
- int32 * _stop = (int32 *) ((char *) _start + (Size) (len)); \
+ long * _start = (long *) (start); \
+ long * _stop = (long *) ((char *) _start + (Size) (len)); \
\
while (_start < _stop) \
*_start++ = 0; \
*/
/* msb for char */
-#define CSIGNBIT (0x80)
+#define HIGHBIT (0x80)
+#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT)
#define STATUS_OK (0)
#define STATUS_ERROR (-1)
#define STATUS_EOF (-2)
#define STATUS_FOUND (1)
+#define STATUS_WAITING (2)
+
+
+/* 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
/* ----------------------------------------------------------------
*/
#if defined(WIN32) || defined(__CYGWIN__)
#define PG_BINARY O_BINARY
+#define PG_BINARY_A "ab"
#define PG_BINARY_R "rb"
#define PG_BINARY_W "wb"
#else
#define PG_BINARY 0
+#define PG_BINARY_A "a"
#define PG_BINARY_R "r"
#define PG_BINARY_W "w"
#endif
-#if defined(sun) && defined(__sparc__) && !defined(__SVR4)
-#include <unistd.h>
-#endif
-
-/* These are for things that are one way on Unix and another on NT */
-#define NULL_DEV "/dev/null"
-
/*
* Provide prototypes for routines not present in a particular machine's
* standard C library.
#define memmove(d, s, c) bcopy(s, d, c)
#endif
-#ifndef DLLIMPORT
-#define DLLIMPORT /* no special DLL markers on most ports */
+#ifndef PGDLLIMPORT
+#define PGDLLIMPORT /* no special DLL markers on most ports */
#endif
/*
#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