X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=src%2Finclude%2Fc.h;h=7578f572d3cbb11730fd1e43f8ea1d4cb09fdead;hb=901be0fad4034c9cf8a3588fd6cf2ece82e4b8ce;hp=ebed0ab94548972f45d2e1bce5383c240a30d617;hpb=70c9763d4815ac847f0f7694f43eb6a59a236868;p=postgresql diff --git a/src/include/c.h b/src/include/c.h index ebed0ab945..7578f572d3 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-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.181 2005/03/29 00:17:16 tgl Exp $ + * $PostgreSQL: pgsql/src/include/c.h,v 1.239 2010/01/07 04:53:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -52,15 +52,18 @@ #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 +#undef errcode +#endif + #include #include #include @@ -69,6 +72,9 @@ #ifdef HAVE_STRINGS_H #include #endif +#ifdef HAVE_STDINT_H +#include +#endif #include #include @@ -80,29 +86,31 @@ #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 -#define _(x) gettext((x)) +#define _(x) gettext(x) #ifdef ENABLE_NLS #include #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) @@ -127,7 +135,6 @@ #define CppAsString(identifier) #identifier #define CppConcat(x, y) x##y - #else /* !HAVE_STRINGIZE */ #define CppAsString(identifier) "identifier" @@ -171,11 +178,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 @@ -190,7 +192,6 @@ typedef char bool; #define false ((bool) 0) #endif #endif /* not C++ */ -#endif /* __BEOS__ */ typedef bool *BoolPtr; @@ -257,22 +258,6 @@ typedef uint8 bits8; /* >= 8 bits */ 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 */ @@ -296,21 +281,11 @@ typedef long long int int64; 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) @@ -322,7 +297,7 @@ typedef unsigned long int uint64; /* Select timestamp representation (float8 or int64) */ -#if defined(USE_INTEGER_DATETIMES) && !defined(INT64_IS_BUSTED) +#ifdef USE_INTEGER_DATETIMES #define HAVE_INT64_TIMESTAMP #endif @@ -365,7 +340,8 @@ typedef float float4; typedef double float8; /* - * Oid, RegProcedure, TransactionId, SubTransactionId, CommandId, AclId + * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, + * CommandId */ /* typedef Oid is in postgres_ext.h */ @@ -379,17 +355,22 @@ typedef regproc RegProcedure; typedef uint32 TransactionId; +typedef uint32 LocalTransactionId; + 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 */ @@ -405,13 +386,16 @@ typedef struct * 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]; }; @@ -430,7 +414,7 @@ typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */ /* * 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: + * 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 @@ -439,9 +423,9 @@ typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */ */ 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; @@ -450,9 +434,9 @@ typedef struct 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; @@ -460,21 +444,27 @@ typedef struct } 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) +/* + * 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 @@ -497,12 +487,10 @@ typedef NameData *Name; * 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)) -#define AclIdIsValid(aclId) ((bool) ((aclId) != 0)) - #define RegProcedureIsValid(p) OidIsValid(p) @@ -531,21 +519,21 @@ 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. + * 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)) @@ -555,6 +543,14 @@ typedef NameData *Name; /* 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 @@ -608,8 +604,8 @@ 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 @@ -619,32 +615,35 @@ typedef NameData *Name; * 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 ((((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 * _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 @@ -654,20 +653,21 @@ typedef NameData *Name; #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) @@ -680,15 +680,16 @@ typedef NameData *Name; * 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; \ @@ -701,12 +702,40 @@ 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) + + +/* 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 /* ---------------------------------------------------------------- @@ -727,21 +756,16 @@ typedef NameData *Name; */ #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 -#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. @@ -762,8 +786,8 @@ 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 */ +#ifndef PGDLLIMPORT +#define PGDLLIMPORT /* no special DLL markers on most ports */ #endif /* @@ -806,6 +830,14 @@ extern int fdatasync(int fildes); #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