mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-04-13 11:30:40 +02:00
Double spaces have fallen out of favor in recent years because they no longer contribute to readability. We have been using single spaces and editing related paragraphs for some time, but now it seems best to update the remaining instances to avoid churn in unrelated commits and to make it clearer what spacing contributors should use.
127 lines
8.1 KiB
C
127 lines
8.1 KiB
C
/***********************************************************************************************************************************
|
|
General Macros
|
|
|
|
Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
|
|
Portions Copyright (c) 1994, Regents of the University of California
|
|
***********************************************************************************************************************************/
|
|
#ifndef COMMON_MACRO_H
|
|
#define COMMON_MACRO_H
|
|
|
|
/***********************************************************************************************************************************
|
|
Convert the parameter to a zero-terminated string
|
|
|
|
Useful for converting non-string types (e.g. int) to strings for inclusion in messages.
|
|
***********************************************************************************************************************************/
|
|
#define STRINGIFY_HELPER(param) #param
|
|
#define STRINGIFY(param) STRINGIFY_HELPER(param)
|
|
|
|
/***********************************************************************************************************************************
|
|
Glue together a string/macro and another string//macro
|
|
|
|
Useful for creating function names when one or both of the macro parameter needs to be converted to a macro before concatenating.
|
|
common/type/object.h has numerous examples of this.
|
|
***********************************************************************************************************************************/
|
|
#define GLUE_HELPER(param1, param2) param1##param2
|
|
#define GLUE(param1, param2) GLUE_HELPER(param1, param2)
|
|
|
|
/***********************************************************************************************************************************
|
|
If param2 > param1 then assign it to param1
|
|
|
|
Useful for ensuring coverage in cases where compared values may be always ascending or descending.
|
|
***********************************************************************************************************************************/
|
|
#define MAX_ASSIGN(param1, param2) \
|
|
do \
|
|
{ \
|
|
if (param2 > param1) \
|
|
param1 = param2; \
|
|
} \
|
|
while (0)
|
|
|
|
/***********************************************************************************************************************************
|
|
If the "condition" (a compile-time-constant expression) evaluates to false then throw a compile error using the "message" (a string
|
|
literal).
|
|
|
|
gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic placement restrictions. Macros STATIC_ASSERT_STMT() and
|
|
STATIC_ASSERT_EXP() make it safe to use as a statement or in an expression, respectively.
|
|
|
|
Otherwise we fall back on a kluge that assumes the compiler will complain about a negative width for a struct bit-field. This will
|
|
not include a helpful error message, but it beats not getting an error at all. Note that when std=c99 it looks like gcc is using the
|
|
same kluge.
|
|
|
|
Adapted from PostgreSQL src/include/c.h.
|
|
***********************************************************************************************************************************/
|
|
#ifdef HAVE_STATIC_ASSERT
|
|
|
|
#define STATIC_ASSERT_STMT(condition, message) \
|
|
do {_Static_assert(condition, message);} while (0)
|
|
|
|
#define STATIC_ASSERT_EXPR(condition, message) \
|
|
((void)({STATIC_ASSERT_STMT(condition, message); true;}))
|
|
|
|
#else
|
|
|
|
#define STATIC_ASSERT_STMT(condition, message) \
|
|
((void)sizeof(struct {int static_assert_failure : (condition) ? 1 : -1;}))
|
|
|
|
#define STATIC_ASSERT_EXPR(condition, message) \
|
|
STATIC_ASSERT_STMT(condition, message)
|
|
|
|
#endif
|
|
|
|
/***********************************************************************************************************************************
|
|
Allows casting const-ness away from an expression, but doesn't allow changing the type. Enforcement of the latter currently only
|
|
works for gcc-like compilers.
|
|
|
|
Note that it is not safe to cast const-ness away if the result will ever be modified (it would be undefined behavior). Doing so can
|
|
cause compiler mis-optimizations or runtime crashes (by modifying read-only memory). It is only safe to use when the result will not
|
|
be modified, but API design or language restrictions prevent you from declaring that (e.g. because a function returns both const and
|
|
non-const variables).
|
|
|
|
Note that this only works in function scope, not for global variables (it would be nice, but not trivial, to improve that).
|
|
|
|
Adapted from PostgreSQL src/include/c.h.
|
|
***********************************************************************************************************************************/
|
|
#ifdef HAVE_BUILTIN_TYPES_COMPATIBLE_P
|
|
#define UNCONSTIFY(type, expression) \
|
|
(STATIC_ASSERT_EXPR(__builtin_types_compatible_p(__typeof(expression), const type), "invalid cast"), (type)(expression))
|
|
#else
|
|
#define UNCONSTIFY(type, expression) \
|
|
((type)(expression))
|
|
#endif
|
|
|
|
/***********************************************************************************************************************************
|
|
Determine the alignment of a data type
|
|
|
|
This macro reduces to a constant so it is safe to use anywhere a constant is allowed, e.g. a switch statement case.
|
|
***********************************************************************************************************************************/
|
|
#define ALIGN_OF(type) ((size_t)&((struct {char c; type t;} *)0)->t)
|
|
|
|
/***********************************************************************************************************************************
|
|
Determine the byte offset required to align a type after an arbitrary number of bytes
|
|
|
|
This is useful for determining how to correctly align a type in a buffer that is being dynamically built up like a struct.
|
|
***********************************************************************************************************************************/
|
|
#define ALIGN_OFFSET(type, bytes) (ALIGN_OF(type) - ((bytes) % ALIGN_OF(type)))
|
|
|
|
/***********************************************************************************************************************************
|
|
Determine size of a type in a struct
|
|
|
|
Using sizeof() on a struct member requires additional syntax.
|
|
***********************************************************************************************************************************/
|
|
#define SIZE_OF_STRUCT_MEMBER(struct, member) sizeof(((struct){0}).member)
|
|
|
|
/***********************************************************************************************************************************
|
|
Determine the length of an array that can be determined at compile time
|
|
|
|
For this macro to work correctly the array must be declared like:
|
|
|
|
int intList[] = {0, 1};
|
|
|
|
It will not work for an array declared like:
|
|
|
|
int *intList;
|
|
***********************************************************************************************************************************/
|
|
#define LENGTH_OF(array) (sizeof(array) / sizeof((array)[0]))
|
|
|
|
#endif
|