* 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...
+ * 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...
*
*
- * Portions Copyright (c) 1996-2002, 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.122 2002/08/21 17:20:58 petere Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.213 2006/10/03 20:33:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* 8) 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 macros
- * are the kind of thing that might go here.
+ * almost certainly wrong to put an "extern" declaration here. typedefs and
+ * macros are the kind of thing that might go here.
*
*----------------------------------------------------------------
*/
#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.
-*/
+/*
+ * 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 "pg_config.h"
+#include "pg_config_manual.h" /* must be after pg_config.h */
+#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>
#endif
#include <sys/types.h>
-#ifdef __CYGWIN__
#include <errno.h>
-#include <sys/fcntl.h> /* ensure O_BINARY is available */
+#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(__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.
- */
-/* Also defined in interfaces/odbc/md5.h */
-#ifndef __BEOS__
-
#ifndef __cplusplus
#ifndef bool
#define false ((bool) 0)
#endif
#endif /* not C++ */
-#endif /* __BEOS__ */
typedef bool *BoolPtr;
typedef signed char int8; /* == 8 bits */
typedef signed short int16; /* == 16 bits */
typedef signed int int32; /* == 32 bits */
-#endif /* not HAVE_INT8 */
+#endif /* not HAVE_INT8 */
/*
* uintN
* 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 */
+#endif /* not HAVE_UINT8 */
/*
* bitsN
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 */
+#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
#endif
#define INT64_IS_BUSTED
-
-#endif /* not HAVE_LONG_INT_64 and not HAVE_LONG_LONG_INT_64 */
+#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)
-#define UINT64CONST(x) ((uint64) x##LL)
+#define UINT64CONST(x) ((uint64) x##ULL)
#else
#define INT64CONST(x) ((int64) x)
#define UINT64CONST(x) ((uint64) x)
typedef double float8;
/*
- * Oid, RegProcedure, TransactionId, CommandId
+ * 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)
/* ----------------
* 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. See postgres.h for details of the TOASTed form.
+ * 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.
* ----------------
*/
struct varlena
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
* 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)) & ~(ALIGNVAL-1))
+#define TYPEALIGN(ALIGNVAL,LEN) \
+ (((long) (LEN) + ((ALIGNVAL) - 1)) & ~((long) ((ALIGNVAL) - 1)))
#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))
/* ----------------------------------------------------------------
} 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
* 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.
- *
- * We got the 64 number by testing this against the stock memset() on
- * BSD/OS 3.0. Larger values were slower. bjm 1997/09/11
- *
- * I think the crossover point could be a good deal higher for
- * most platforms, actually. tgl 2000-03-19
+ * 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
+ * MEMSET_LOOP_LIMIT tests in configure.
*/
#define MemSet(start, val, len) \
do \
{ \
- int32 * _start = (int32 *) (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)
+
+/*
+ * 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)
-#define MEMSET_LOOP_LIMIT 64
+
+/*
+ * 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)
/* ----------------------------------------------------------------
*/
/* 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)
/* ----------------------------------------------------------------
* ----------------------------------------------------------------
*/
-#ifdef __CYGWIN__
+/*
+ * 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"
/*
* Provide prototypes for routines not present in a particular machine's
- * standard C library. It'd be better to put these in pg_config.h, but
- * in pg_config.h we haven't yet included anything that defines size_t...
+ * standard C library.
*/
#if !HAVE_DECL_SNPRINTF
#define memmove(d, s, c) bcopy(s, d, c)
#endif
-/* ----------------
- * end of c.h
- * ----------------
+#ifndef DLLIMPORT
+#define DLLIMPORT /* no special DLL markers on most ports */
+#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.
+ */
+
+#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
+#define sigjmp_buf jmp_buf
+#define sigsetjmp(x,y) setjmp(x)
+#define siglongjmp longjmp
+#endif
+
+#if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC
+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)
+#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)
+#define strtoull strtouq
+#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"
#endif /* C_H */