postgresql/src/include/c.h

795 lines
21 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
*
*
2003-08-04 04:40:20 +02:00
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
1996-10-31 08:10:14 +01:00
*
2003-08-04 04:40:20 +02:00
* $Id: c.h,v 1.152 2003/08/04 02:40:10 momjian Exp $
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) widely useful macros
* 7) random stuff
* 8) 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
/*
* 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.
*/
1999-07-17 06:12:10 +02:00
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
#ifndef WIN32
#include "pg_config_os.h" /* must be before any system header files */
#endif
#include "postgres_ext.h"
1999-07-17 06:12:10 +02:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <stdarg.h>
#ifdef HAVE_STRINGS_H
#include <strings.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>
2003-08-04 02:43:34 +02:00
#include <fcntl.h> /* ensure O_BINARY is available */
#ifdef HAVE_SUPPORTDEFS_H
#include <SupportDefs.h>
#endif
1999-01-17 07:20:06 +01:00
#if defined(WIN32) && !defined(_MSC_VER) && !defined(__BORLANDC__)
/* 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>
#ifdef ENABLE_NLS
#include <libintl.h>
#else
#define gettext(x) (x)
#endif
#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: the standard Autoconf macro AC_C_STRINGIZE actually only checks
* whether #identifier works, but if we have that we likely have ## too.
1996-10-31 08:10:14 +01:00
*/
#if defined(HAVE_STRINGIZE)
1996-10-31 08:10:14 +01:00
#define CppAsString(identifier) #identifier
#define CppConcat(x, y) x##y
1996-10-31 08:10:14 +01:00
#else /* !HAVE_STRINGIZE */
1996-10-31 08:10:14 +01:00
#define CppAsString(identifier) "identifier"
1996-10-31 08:10:14 +01:00
/*
* CppIdentity -- On Reiser based cpp's this is used to concatenate
* two tokens. That is
* CppIdentity(A)B ==> AB
* We renamed it to _private_CppIdentity because it should not
* be referenced outside this file. On other cpp's it
* produces A B.
1996-10-31 08:10:14 +01:00
*/
#define _priv_CppIdentity(x)x
#define CppConcat(x, y) _priv_CppIdentity(x)y
#endif /* !HAVE_STRINGIZE */
/*
* 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.
*/
/* BeOS defines bool already, but the compiler chokes on the
* #ifndef unless we wrap it in this check.
*/
2001-03-22 05:01:46 +01:00
#ifndef __BEOS__
#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++ */
#endif /* __BEOS__ */
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
*/
/* 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 */
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
* boolN
* Boolean value, AT LEAST N BITS IN SIZE.
1996-10-31 08:10:14 +01:00
*/
typedef uint8 bool8; /* >= 8 bits */
typedef uint16 bool16; /* >= 16 bits */
typedef uint32 bool32; /* >= 32 bits */
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
/*
1999-05-25 18:15:34 +02:00
* wordN
* Unit of storage, AT LEAST N BITS IN SIZE,
* used to fetch/store data.
1996-10-31 08:10:14 +01:00
*/
typedef uint8 word8; /* >= 8 bits */
typedef uint16 word16; /* >= 16 bits */
typedef uint32 word32; /* >= 32 bits */
1996-10-31 08:10:14 +01:00
/*
* floatN
* Floating point number, AT LEAST N BITS IN SIZE,
* used for numerical computations.
1996-10-31 08:10:14 +01:00
*
* Since sizeof(floatN) may be > sizeof(char *), always pass
* floatN by reference.
1996-10-31 08:10:14 +01:00
*
* XXX: these typedefs are now deprecated in favor of float4 and float8.
* They will eventually go away.
1996-10-31 08:10:14 +01:00
*/
typedef float float32data;
typedef double float64data;
typedef float *float32;
typedef double *float64;
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
2001-03-22 05:01:46 +01:00
#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
2001-03-22 05:01:46 +01:00
2002-09-04 22:31:48 +02:00
#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;
#endif
2001-03-22 05:01:46 +01:00
#define INT64_IS_BUSTED
2002-09-04 22:31:48 +02:00
#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)
#else
#define INT64CONST(x) ((int64) x)
#define UINT64CONST(x) ((uint64) x)
#endif
/* Select timestamp representation (float8 or int64) */
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
#if defined(USE_INTEGER_DATETIMES) && !defined(INT64_IS_BUSTED)
#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;
#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 int16 int2;
typedef int32 int4;
typedef float float4;
typedef double float8;
/*
* Oid, RegProcedure, TransactionId, CommandId, AclId
*/
/* 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 CommandId;
1996-10-31 08:10:14 +01:00
#define FirstCommandId ((CommandId) 0)
1996-10-31 08:10:14 +01:00
typedef int32 AclId; /* user and group identifiers */
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
2002-09-04 22:31:48 +02:00
* 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.
* ----------------
1996-10-31 08:10:14 +01:00
*/
struct varlena
{
int32 vl_len;
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
/*
* Fixed-length array types (these are not varlena's!)
1996-10-31 08:10:14 +01:00
*/
typedef int2 int2vector[INDEX_MAX_KEYS];
typedef Oid oidvector[INDEX_MAX_KEYS];
1996-10-31 08:10:14 +01:00
/*
* 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.
*/
typedef union nameData
{
char data[NAMEDATALEN];
int alignmentDummy;
} NameData;
typedef NameData *Name;
#define NameStr(name) ((name).data)
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) ((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) \
(((long)(pointer) % (sizeof (type))) == 0)
1996-10-31 08:10:14 +01:00
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
#define AclIdIsValid(aclId) ((bool) ((aclId) != 0))
#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)])
/* ----------------
* Alignment macros: align a length or address appropriately for a given type.
1996-10-31 08:10:14 +01:00
*
* 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.
1996-10-31 08:10:14 +01:00
*
* NOTE: TYPEALIGN will not work if ALIGNVAL is not a power of 2.
* That case seems extremely unlikely to occur in practice, however.
* ----------------
1996-10-31 08:10:14 +01:00
*/
#define TYPEALIGN(ALIGNVAL,LEN) (((long)(LEN) + (ALIGNVAL-1)) & ~(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))
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 6: 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
2001-03-22 05:01:46 +01:00
* 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)
1998-02-11 22:38:08 +01:00
/* Get a bit mask of the bits set in non-int32 aligned addresses */
#define INT_ALIGN_MASK (sizeof(int32) - 1)
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
2003-08-04 02:43:34 +02:00
* 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
* platform-specific MEMSET_LOOP_LIMIT values or tests in configure.
*
2002-10-08 21:17:58 +02:00
* bjm 2002-10-08
*/
#define MemSet(start, val, len) \
do \
{ \
int32 * _start = (int32 *) (start); \
int _val = (val); \
Size _len = (len); \
\
if ((((long) _start) & INT_ALIGN_MASK) == 0 && \
(_len & INT_ALIGN_MASK) == 0 && \
_val == 0 && \
_len <= MEMSET_LOOP_LIMIT) \
{ \
int32 * _stop = (int32 *) ((char *) _start + _len); \
while (_start < _stop) \
*_start++ = 0; \
} \
else \
memset((char *) _start, _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
* 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 \
{ \
int32 * _start = (int32 *) (start); \
int _val = (val); \
Size _len = (len); \
\
if ((_len & INT_ALIGN_MASK) == 0 && \
_val == 0 && \
_len <= MEMSET_LOOP_LIMIT) \
{ \
int32 * _stop = (int32 *) ((char *) _start + _len); \
while (_start < _stop) \
*_start++ = 0; \
} \
else \
memset((char *) _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) & INT_ALIGN_MASK) == 0 && \
(len) <= MEMSET_LOOP_LIMIT && \
(val) == 0 )
#define MemSetLoop(start, val, len) \
do \
{ \
int32 * _start = (int32 *) (start); \
int32 * _stop = (int32 *) ((char *) _start + (Size) (len)); \
\
while (_start < _stop) \
*_start++ = 0; \
} while (0)
1997-09-18 16:21:02 +02:00
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 7: random stuff
1996-10-31 08:10:14 +01:00
* ----------------------------------------------------------------
*/
/* msb for char */
#define CSIGNBIT (0x80)
1996-10-31 08:10:14 +01:00
#define STATUS_OK (0)
#define STATUS_ERROR (-1)
#define STATUS_EOF (-2)
#define STATUS_FOUND (1)
1996-10-31 08:10:14 +01:00
/* ----------------------------------------------------------------
* Section 8: system-specific hacks
1996-10-31 08:10:14 +01:00
*
* This should be limited to things that absolutely have to be
2001-03-22 05:01:46 +01:00
* 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
* ----------------------------------------------------------------
*/
#if defined(__CYGWIN__) || defined(WIN32)
2000-06-02 18:40:09 +02:00
#define PG_BINARY O_BINARY
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_R "r"
#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;
2003-08-04 02:43:34 +02:00
/* 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)
1996-10-31 08:10:14 +01:00
#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
1996-10-31 08:10:14 +01:00
/* These are for things that are one way on Unix and another on NT */
#define NULL_DEV "/dev/null"
1996-10-31 08:10:14 +01:00
/*
* 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(printf, 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
#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.
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
/* /port compatibility functions */
#include "port.h"
#endif /* C_H */