X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=src%2Finclude%2Fc.h;h=db9983b4624d38688e13daae1ca58d53755476b4;hb=0184c6835cb99057f3d99f4b5a62965221e2bf13;hp=ba0fb355d25c282b444c1a2d3dec9899b9f5eba8;hpb=f142b0915116bfe0935b589045678a6c95e7abb9;p=postgresql diff --git a/src/include/c.h b/src/include/c.h index ba0fb355d2..db9983b462 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -9,10 +9,10 @@ * 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.129 2002/10/23 23:37:47 momjian Exp $ + * $PostgreSQL: pgsql/src/include/c.h,v 1.213 2006/10/03 20:33:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -51,7 +51,18 @@ */ #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 +#undef errcode +#endif #include #include @@ -63,22 +74,34 @@ #endif #include -#ifdef __CYGWIN__ #include -#include /* ensure O_BINARY is available */ +#if defined(WIN32) || defined(__CYGWIN__) +#include /* ensure O_BINARY is available */ #endif #ifdef HAVE_SUPPORTDEFS_H #include #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 +#define _(x) gettext((x)) + #ifdef ENABLE_NLS #include #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) @@ -102,7 +125,6 @@ #define CppAsString(identifier) #identifier #define CppConcat(x, y) x##y - #else /* !HAVE_STRINGIZE */ #define CppAsString(identifier) "identifier" @@ -146,11 +168,6 @@ * 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 @@ -165,7 +182,6 @@ typedef char bool; #define false ((bool) 0) #endif #endif /* not C++ */ -#endif /* __BEOS__ */ typedef bool *BoolPtr; @@ -218,21 +234,12 @@ typedef signed int int32; /* == 32 bits */ * 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. @@ -241,15 +248,6 @@ typedef uint8 bits8; /* >= 8 bits */ 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, @@ -278,7 +276,6 @@ typedef long int int64; #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 */ @@ -288,7 +285,6 @@ typedef long long int int64; #ifndef HAVE_UINT64 typedef unsigned long long int uint64; #endif - #else /* not HAVE_LONG_INT_64 and not * HAVE_LONG_LONG_INT_64 */ @@ -307,7 +303,7 @@ typedef unsigned long int uint64; /* 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) @@ -358,7 +354,8 @@ typedef float float4; typedef double float8; /* - * Oid, RegProcedure, TransactionId, CommandId + * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, + * CommandId */ /* typedef Oid is in postgres_ext.h */ @@ -372,6 +369,16 @@ typedef regproc RegProcedure; 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) @@ -414,11 +421,36 @@ typedef struct varlena BpChar; /* blank-padded char, ie SQL char(n) */ 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, @@ -436,6 +468,16 @@ 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))) + +#define ESCAPE_STRING_SYNTAX 'E' /* ---------------------------------------------------------------- * Section 4: IsValid macros for system types @@ -490,7 +532,7 @@ typedef NameData *Name; * 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. @@ -503,13 +545,16 @@ typedef NameData *Name; * ---------------- */ -#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)) /* ---------------------------------------------------------------- @@ -564,42 +609,96 @@ typedef NameData *Name; } 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. However, we have also found that the loop is faster than + * 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 \ { \ - 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) -#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 \ + { \ + 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) /* ---------------------------------------------------------------- @@ -608,12 +707,14 @@ typedef NameData *Name; */ /* 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) /* ---------------------------------------------------------------- @@ -625,7 +726,14 @@ typedef NameData *Name; * ---------------------------------------------------------------- */ -#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" @@ -639,18 +747,12 @@ typedef NameData *Name; #include #endif -#if defined(bsdi) -int fseeko(FILE *stream, off_t offset, int whence); -off_t ftello(FILE *stream); -#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. 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 @@ -668,4 +770,58 @@ extern int vsnprintf(char *str, size_t count, const char *fmt, va_list args); #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. + */ + +#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 */