* polluting the namespace with lots of stuff...
*
*
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: c.h,v 1.154 2003/10/11 19:53:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.213 2006/10/03 20:33:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 will include further down */
#include "pg_config_os.h" /* must be before any system header files */
#endif
#include "postgres_ext.h"
+#include "pg_trace.h"
+
+#if defined(__BORLANDC__) || (_MSC_VER >= 1400)
+#define errcode __msvc_errcode
+#include <crtdefs.h>
+#undef errcode
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
+#if defined(WIN32) || defined(__CYGWIN__)
#include <fcntl.h> /* ensure O_BINARY is available */
+#endif
#ifdef HAVE_SUPPORTDEFS_H
#include <SupportDefs.h>
#endif
-#if defined(WIN32) && !defined(_MSC_VER) && !defined(__BORLANDC__)
-/* We have to redefine some system functions after they are included above */
+#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>
+#define _(x) gettext((x))
+
#ifdef ENABLE_NLS
#include <libintl.h>
#else
#define gettext(x) (x)
#endif
+
+/*
+ * Use this to mark strings to be translated by gettext, in places where
+ * you don't want an actual function call to occur (eg, constant tables).
+ */
#define gettext_noop(x) (x)
#define CppAsString(identifier) #identifier
#define CppConcat(x, y) x##y
-
#else /* !HAVE_STRINGIZE */
#define CppAsString(identifier) "identifier"
* 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;
* used for numerical computations and the
* frontend/backend protocol.
*/
-/* Also defined in interfaces/odbc/md5.h */
#ifndef HAVE_UINT8
typedef unsigned char uint8; /* == 8 bits */
typedef unsigned short uint16; /* == 16 bits */
typedef unsigned int uint32; /* == 32 bits */
#endif /* not HAVE_UINT8 */
-/*
- * boolN
- * Boolean value, AT LEAST N BITS IN SIZE.
- */
-typedef uint8 bool8; /* >= 8 bits */
-typedef uint16 bool16; /* >= 16 bits */
-typedef uint32 bool32; /* >= 32 bits */
-
/*
* bitsN
* Unit of bitwise operation, AT LEAST N BITS IN SIZE.
typedef uint16 bits16; /* >= 16 bits */
typedef uint32 bits32; /* >= 32 bits */
-/*
- * wordN
- * Unit of storage, AT LEAST N BITS IN SIZE,
- * used to fetch/store data.
- */
-typedef uint8 word8; /* >= 8 bits */
-typedef uint16 word16; /* >= 16 bits */
-typedef uint32 word32; /* >= 32 bits */
-
/*
* floatN
* Floating point number, AT LEAST N BITS IN SIZE,
#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 */
/* Decide if we need to decorate 64-bit constants */
#ifdef HAVE_LL_CONSTANTS
#define INT64CONST(x) ((int64) x##LL)
-#define UINT64CONST(x) ((uint64) x##LL)
+#define UINT64CONST(x) ((uint64) x##ULL)
#else
#define INT64CONST(x) ((int64) x)
#define UINT64CONST(x) ((uint64) x)
#define HAVE_INT64_TIMESTAMP
#endif
-/* Global variable holding time zone information. */
-#ifndef HAVE_UNDERSCORE_TIMEZONE
-#define TIMEZONE_GLOBAL timezone
-#else
-#define TIMEZONE_GLOBAL _timezone
-#define tzname _tzname /* should be in time.h? */
-#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;
typedef double float8;
/*
- * Oid, RegProcedure, TransactionId, CommandId, AclId
+ * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
+ * CommandId
*/
/* typedef Oid is in postgres_ext.h */
typedef uint32 TransactionId;
+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;
#define FirstCommandId ((CommandId) 0)
-typedef int32 AclId; /* user and group identifiers */
-
/*
* Array indexing support
*/
typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */
/*
- * Fixed-length array types (these are not varlena's!)
+ * 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.
*/
+typedef struct
+{
+ int32 size; /* these fields must match ArrayType! */
+ int ndim; /* always 1 for int2vector */
+ int32 dataoffset; /* always 0 for int2vector */
+ Oid elemtype;
+ int dim1;
+ int lbound1;
+ int2 values[1]; /* VARIABLE LENGTH ARRAY */
+} int2vector; /* VARIABLE LENGTH STRUCT */
-typedef int2 int2vector[INDEX_MAX_KEYS];
-typedef Oid oidvector[INDEX_MAX_KEYS];
+typedef struct
+{
+ int32 size; /* 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 */
/*
* We want NameData to have length NAMEDATALEN and int alignment,
#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)))
+
+#define ESCAPE_STRING_SYNTAX 'E'
/* ----------------------------------------------------------------
* Section 4: IsValid macros for system types
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
-#define AclIdIsValid(aclId) ((bool) ((aclId) != 0))
-
#define RegProcedureIsValid(p) OidIsValid(p)
* endof
* Address of the element one past the last in an array.
*/
-#define endof(array) (&array[lengthof(array)])
+#define endof(array) (&(array)[lengthof(array)])
/* ----------------
* Alignment macros: align a length or address appropriately for a given type.
*/
#define TYPEALIGN(ALIGNVAL,LEN) \
- (((long) (LEN) + (ALIGNVAL-1)) & ~((long) (ALIGNVAL-1)))
+ (((long) (LEN) + ((ALIGNVAL) - 1)) & ~((long) ((ALIGNVAL) - 1)))
#define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN))
#define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN))
} 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 \
{ \
- /* (void *) used because we check for alignment below */ \
- int32 * _start = (int32 *) (void *) (start); \
+ /* 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 ((((long) _start) & INT_ALIGN_MASK) == 0 && \
- (_len & INT_ALIGN_MASK) == 0 && \
+ if ((((long) _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 * _stop = (int32 *) ((char *) _start + _len); \
+ long *_start = (long *) _vstart; \
+ long *_stop = (long *) ((char *) _start + _len); \
while (_start < _stop) \
*_start++ = 0; \
} \
else \
- memset((char *) _start, _val, _len); \
+ 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; \
} \
else \
- memset((char *) _start, _val, _len); \
+ memset(_start, _val, _len); \
} while (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)
/* ----------------------------------------------------------------
* ----------------------------------------------------------------
*/
-#if defined(__CYGWIN__) || defined(WIN32)
+/*
+ * NOTE: this is also used for opening text files.
+ * 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
+ * that is OK because we can already handle those cleanly.
+ */
+#if defined(WIN32) || defined(__CYGWIN__)
#define PG_BINARY O_BINARY
#define PG_BINARY_R "rb"
#define PG_BINARY_W "wb"
#define PG_BINARY_W "w"
#endif
-#if !defined(WIN32) && !defined(__BEOS__)
-#define FCNTL_NONBLOCK(sock) fcntl(sock, F_SETFL, O_NONBLOCK)
-#else
-extern long ioctlsocket_ret;
-
-/* Returns non-0 on failure, while fcntl() returns -1 on failure */
-#ifdef WIN32
-#define FCNTL_NONBLOCK(sock) ((ioctlsocket(sock, FIONBIO, &ioctlsocket_ret) == 0) ? 0 : -1)
-#endif
-#ifdef __BEOS__
-#define FCNTL_NONBLOCK(sock) ((ioctl(sock, FIONBIO, &ioctlsocket_ret) == 0) ? 0 : -1)
-#endif
-#endif
-
#if defined(sun) && defined(__sparc__) && !defined(__SVR4)
#include <unistd.h>
#endif
#define HAVE_STRTOULL 1
#endif
+/* EXEC_BACKEND defines */
+#ifdef EXEC_BACKEND
+#define NON_EXEC_STATIC
+#else
+#define NON_EXEC_STATIC static
+#endif
+
/* /port compatibility functions */
#include "port.h"