#ifndef GIT_COMPAT_UTIL_H
#define GIT_COMPAT_UTIL_H
#if __STDC_VERSION__ - 0 < 199901L
#error "Required C99 support is in a test phase. Please see git-compat-util.h for more details."
#endif
#ifdef USE_MSVC_CRTDBG
#include <stdlib.h>
#include <crtdbg.h>
#endif
struct strbuf;
#define _FILE_OFFSET_BITS …
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
#define GIT_GNUC_PREREQ(maj, min) …
#else
#define GIT_GNUC_PREREQ …
#endif
#ifndef FLEX_ARRAY
#if defined(__SUNPRO_C) && (__SUNPRO_C <= 0x580)
#elif defined(__GNUC__)
# if (__GNUC__ >= 3)
#define FLEX_ARRAY …
# else
#define FLEX_ARRAY …
# endif
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define FLEX_ARRAY …
#endif
#ifndef FLEX_ARRAY
#define FLEX_ARRAY …
#endif
#endif
#define BUILD_ASSERT_OR_ZERO(cond) …
#if GIT_GNUC_PREREQ(3, 1)
#define BARF_UNLESS_AN_ARRAY(arr) …
#define BARF_UNLESS_COPYABLE(dst, src) …
#else
#define BARF_UNLESS_AN_ARRAY …
#define BARF_UNLESS_COPYABLE …
#endif
#define ARRAY_SIZE(x) …
#define bitsizeof(x) …
#define maximum_signed_value_of_type(a) …
#define maximum_unsigned_value_of_type(a) …
#define signed_add_overflows(a, b) …
#define unsigned_add_overflows(a, b) …
#define unsigned_mult_overflows(a, b) …
#define unsigned_left_shift_overflows(a, shift) …
#ifdef __GNUC__
#define TYPEOF(x) …
#else
#define TYPEOF …
#endif
#define MSB(x, bits) …
#define HAS_MULTI_BITS(i) …
#define DIV_ROUND_UP(n,d) …
#define decimal_length(x) …
#ifdef __MINGW64__
#define _POSIX_C_SOURCE …
#elif defined(__sun__)
# if __STDC_VERSION__ - 0 >= 199901L
#define _XOPEN_SOURCE …
# else
#define _XOPEN_SOURCE …
# endif
#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && \
!defined(_M_UNIX) && !defined(__sgi) && !defined(__DragonFly__) && \
!defined(__TANDEM) && !defined(__QNX__) && !defined(__MirBSD__) && \
!defined(__CYGWIN__)
#define _XOPEN_SOURCE …
#define _XOPEN_SOURCE_EXTENDED …
#endif
#define _ALL_SOURCE …
#define _GNU_SOURCE …
#define _BSD_SOURCE …
#define _DEFAULT_SOURCE …
#define _NETBSD_SOURCE …
#define _SGI_SOURCE …
#if GIT_GNUC_PREREQ(4, 5)
#define UNUSED …
#elif defined(__GNUC__)
#define UNUSED …
#else
#define UNUSED
#endif
#if defined(WIN32) && !defined(__CYGWIN__)
# if !defined(_WIN32_WINNT)
#define _WIN32_WINNT …
# endif
#define WIN32_LEAN_AND_MEAN …
#include <winsock2.h>
#ifndef NO_UNIX_SOCKETS
#include <afunix.h>
#endif
#include <windows.h>
#define GIT_WINDOWS_NATIVE
#endif
#if defined(NO_UNIX_SOCKETS) || !defined(GIT_WINDOWS_NATIVE)
static inline int _have_unix_sockets(void)
{ … }
#define have_unix_sockets …
#endif
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include <errno.h>
#include <limits.h>
#include <locale.h>
#ifdef NEEDS_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <sys/types.h>
#include <dirent.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
#include <assert.h>
#include <regex.h>
#include <utime.h>
#include <syslog.h>
#if !defined(NO_POLL_H)
#include <poll.h>
#elif !defined(NO_SYS_POLL_H)
#include <sys/poll.h>
#else
#include <poll.h>
#endif
#ifdef HAVE_BSD_SYSCTL
#include <sys/sysctl.h>
#endif
static inline int is_xplatform_dir_sep(int c)
{ … }
#if defined(__CYGWIN__)
#include "compat/win32/path-utils.h"
#endif
#if defined(__MINGW32__)
#include "compat/win32/path-utils.h"
#include "compat/mingw.h"
#elif defined(_MSC_VER)
#include "compat/win32/path-utils.h"
#include "compat/msvc.h"
#else
#include <sys/utsname.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/statvfs.h>
#include <termios.h>
#ifndef NO_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>
#include <sys/un.h>
#ifndef NO_INTTYPES_H
#include <inttypes.h>
#else
#include <stdint.h>
#endif
#ifdef HAVE_ARC4RANDOM_LIBBSD
#include <bsd/stdlib.h>
#endif
#ifdef HAVE_GETRANDOM
#include <sys/random.h>
#endif
#ifdef NO_INTPTR_T
typedef long intptr_t;
typedef unsigned long uintptr_t;
#endif
#undef _ALL_SOURCE
#include <grp.h>
#define _ALL_SOURCE …
#endif
#ifdef PRECOMPOSE_UNICODE
#include "compat/precompose_utf8.h"
#else
static inline const char *precompose_argv_prefix(int argc UNUSED,
const char **argv UNUSED,
const char *prefix)
{ … }
static inline const char *precompose_string_if_needed(const char *in)
{ … }
#define probe_utf8_pathname_composition() …
#endif
#ifdef MKDIR_WO_TRAILING_SLASH
#define mkdir …
int compat_mkdir_wo_trailing_slash(const char*, mode_t);
#endif
#ifdef time
#undef time
#endif
static inline time_t git_time(time_t *tloc)
{ … }
#define time …
#ifdef NO_STRUCT_ITIMERVAL
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};
#endif
#ifdef NO_SETITIMER
static inline int git_setitimer(int which UNUSED,
const struct itimerval *value UNUSED,
struct itimerval *newvalue UNUSED) {
return 0;
}
#undef setitimer
#define setitimer …
#endif
#ifndef NO_LIBGEN_H
#include <libgen.h>
#else
#define basename …
char *gitbasename(char *);
#define dirname …
char *gitdirname(char *);
#endif
#ifndef NO_ICONV
#include <iconv.h>
#endif
#ifndef NO_OPENSSL
#ifdef __APPLE__
#undef __AVAILABILITY_MACROS_USES_AVAILABILITY
#define __AVAILABILITY_MACROS_USES_AVAILABILITY …
#include <AvailabilityMacros.h>
#undef DEPRECATED_ATTRIBUTE
#define DEPRECATED_ATTRIBUTE
#undef __AVAILABILITY_MACROS_USES_AVAILABILITY
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
#ifdef HAVE_SYSINFO
# include <sys/sysinfo.h>
#endif
#ifndef NI_MAXHOST
#define NI_MAXHOST …
#endif
#ifndef NI_MAXSERV
#define NI_MAXSERV …
#endif
#ifndef PATH_MAX
#define PATH_MAX …
#endif
#ifndef NAME_MAX
#define NAME_MAX …
#endif
timestamp_t;
#define PRItime …
#define parse_timestamp …
#define TIME_MAX …
#define TIME_MIN …
#ifndef PATH_SEP
#define PATH_SEP …
#endif
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifndef _PATH_DEFPATH
#define _PATH_DEFPATH …
#endif
#ifndef platform_core_config
struct config_context;
static inline int noop_core_config(const char *var UNUSED,
const char *value UNUSED,
const struct config_context *ctx UNUSED,
void *cb UNUSED)
{ … }
#define platform_core_config …
#endif
int lstat_cache_aware_rmdir(const char *path);
#if !defined(__MINGW32__) && !defined(_MSC_VER)
#define rmdir …
#endif
#ifndef has_dos_drive_prefix
static inline int git_has_dos_drive_prefix(const char *path UNUSED)
{ … }
#define has_dos_drive_prefix …
#endif
#ifndef skip_dos_drive_prefix
static inline int git_skip_dos_drive_prefix(char **path UNUSED)
{ … }
#define skip_dos_drive_prefix …
#endif
static inline int git_is_dir_sep(int c)
{ … }
#ifndef is_dir_sep
#define is_dir_sep …
#endif
#ifndef offset_1st_component
static inline int git_offset_1st_component(const char *path)
{ … }
#define offset_1st_component …
#endif
#ifndef fspathcmp
#define fspathcmp …
#endif
#ifndef fspathncmp
#define fspathncmp …
#endif
#ifndef is_valid_path
#define is_valid_path(path) …
#endif
#ifndef is_path_owned_by_current_user
#ifdef __TANDEM
#define ROOT_UID …
#else
#define ROOT_UID …
#endif
static inline void extract_id_from_env(const char *env, uid_t *id)
{ … }
static inline int is_path_owned_by_current_uid(const char *path,
struct strbuf *report UNUSED)
{ … }
#define is_path_owned_by_current_user …
#endif
#ifndef find_last_dir_sep
static inline char *git_find_last_dir_sep(const char *path)
{ … }
#define find_last_dir_sep …
#endif
#ifndef has_dir_sep
static inline int git_has_dir_sep(const char *path)
{ … }
#define has_dir_sep(path) …
#endif
#ifndef query_user_email
#define query_user_email() …
#endif
#ifdef __TANDEM
#include <floss.h(floss_execl,floss_execlp,floss_execv,floss_execvp)>
#include <floss.h(floss_getpwuid)>
#ifndef NSIG
#define NSIG …
#endif
#endif
#if defined(__HP_cc) && (__HP_cc >= 61000)
#define NORETURN …
#define NORETURN_PTR
#elif defined(__GNUC__) && !defined(NO_NORETURN)
#define NORETURN …
#define NORETURN_PTR …
#elif defined(_MSC_VER)
#define NORETURN …
#define NORETURN_PTR
#else
#define NORETURN
#define NORETURN_PTR
#ifndef __GNUC__
#ifndef __attribute__
#define __attribute__(x)
#endif
#endif
#endif
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define LAST_ARG_MUST_BE_NULL …
#define RESULT_MUST_BE_USED …
#else
#define LAST_ARG_MUST_BE_NULL
#define RESULT_MUST_BE_USED
#endif
#define MAYBE_UNUSED …
#include "compat/bswap.h"
#include "wrapper.h"
NORETURN void usage(const char *err);
NORETURN void usagef(const char *err, ...) __attribute__((format (printf, 1, 2)));
NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2)));
NORETURN void die_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
int die_message(const char *err, ...) __attribute__((format (printf, 1, 2)));
int die_message_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
int error_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
#ifndef NO_OPENSSL
#ifdef APPLE_COMMON_CRYPTO
#include "compat/apple-common-crypto.h"
#else
#include <openssl/evp.h>
#include <openssl/hmac.h>
#endif
#include <openssl/x509v3.h>
#endif
#ifdef HAVE_OPENSSL_CSPRNG
#include <openssl/rand.h>
#endif
#if defined(__GNUC__)
static inline int const_error(void)
{ … }
#define error(...) …
#define error_errno(...) …
#endif
report_fn;
void set_die_routine(NORETURN_PTR report_fn routine);
report_fn get_die_message_routine(void);
void set_error_routine(report_fn routine);
report_fn get_error_routine(void);
void set_warn_routine(report_fn routine);
report_fn get_warn_routine(void);
void set_die_is_recursing_routine(int (*routine)(void));
static inline bool skip_prefix(const char *str, const char *prefix,
const char **out)
{ … }
static inline bool skip_prefix_mem(const char *buf, size_t len,
const char *prefix,
const char **out, size_t *outlen)
{ … }
static inline bool strip_suffix_mem(const char *buf, size_t *len,
const char *suffix)
{ … }
static inline bool strip_suffix(const char *str, const char *suffix,
size_t *len)
{ … }
#define SWAP(a, b) …
#if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
#ifndef PROT_READ
#define PROT_READ …
#define PROT_WRITE …
#define MAP_PRIVATE …
#endif
#define mmap …
#define munmap …
void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
int git_munmap(void *start, size_t length);
#else
#include <sys/mman.h>
#endif
#ifdef NO_MMAP
#define DEFAULT_PACKED_GIT_WINDOW_SIZE …
#else
#define DEFAULT_PACKED_GIT_WINDOW_SIZE …
#endif
#ifndef MAP_FAILED
#define MAP_FAILED …
#endif
#ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
#define on_disk_bytes …
#else
#define on_disk_bytes(st) …
#endif
#ifdef NEEDS_MODE_TRANSLATION
#undef S_IFMT
#undef S_IFREG
#undef S_IFDIR
#undef S_IFLNK
#undef S_IFBLK
#undef S_IFCHR
#undef S_IFIFO
#undef S_IFSOCK
#define S_IFMT …
#define S_IFREG …
#define S_IFDIR …
#define S_IFLNK …
#define S_IFBLK …
#define S_IFCHR …
#define S_IFIFO …
#define S_IFSOCK …
#ifdef stat
#undef stat
#endif
#define stat …
int git_stat(const char *, struct stat *);
#ifdef fstat
#undef fstat
#endif
#define fstat …
int git_fstat(int, struct stat *);
#ifdef lstat
#undef lstat
#endif
#define lstat …
int git_lstat(const char *, struct stat *);
#endif
#define DEFAULT_PACKED_GIT_LIMIT …
#ifdef NO_PREAD
#define pread …
ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
#endif
#ifdef NO_SETENV
#define setenv …
int gitsetenv(const char *, const char *, int);
#endif
#ifdef NO_MKDTEMP
#define mkdtemp …
char *gitmkdtemp(char *);
#endif
#ifdef NO_UNSETENV
#define unsetenv …
int gitunsetenv(const char *);
#endif
#ifdef NO_STRCASESTR
#define strcasestr …
char *gitstrcasestr(const char *haystack, const char *needle);
#endif
#ifdef NO_STRLCPY
#define strlcpy …
size_t gitstrlcpy(char *, const char *, size_t);
#endif
#ifdef NO_STRTOUMAX
#define strtoumax …
uintmax_t gitstrtoumax(const char *, char **, int);
#define strtoimax …
intmax_t gitstrtoimax(const char *, char **, int);
#endif
#ifdef NO_HSTRERROR
#define hstrerror …
const char *githstrerror(int herror);
#endif
#ifdef NO_MEMMEM
#define memmem …
void *gitmemmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#endif
#ifdef OVERRIDE_STRDUP
#ifdef strdup
#undef strdup
#endif
#define strdup …
char *gitstrdup(const char *s);
#endif
#ifdef NO_GETPAGESIZE
#define getpagesize …
#endif
#ifndef O_CLOEXEC
#define O_CLOEXEC …
#endif
#ifdef FREAD_READS_DIRECTORIES
# if !defined(SUPPRESS_FOPEN_REDEFINITION)
# ifdef fopen
# undef fopen
# endif
#define fopen(a,b) …
# endif
FILE *git_fopen(const char*, const char*);
#endif
#ifdef SNPRINTF_RETURNS_BOGUS
#ifdef snprintf
#undef snprintf
#endif
#define snprintf …
int git_snprintf(char *str, size_t maxsize,
const char *format, ...);
#ifdef vsnprintf
#undef vsnprintf
#endif
#define vsnprintf …
int git_vsnprintf(char *str, size_t maxsize,
const char *format, va_list ap);
#endif
#ifdef OPEN_RETURNS_EINTR
#undef open
#define open …
int git_open_with_retry(const char *path, int flag, ...);
#endif
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 1)
#define HAVE_STRCHRNUL
#endif
#endif
#ifndef HAVE_STRCHRNUL
#define strchrnul …
static inline char *gitstrchrnul(const char *s, int c)
{
while (*s && *s != c)
s++;
return (char *)s;
}
#endif
#ifdef NO_INET_PTON
int inet_pton(int af, const char *src, void *dst);
#endif
#ifdef NO_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#ifdef NO_PTHREADS
#define atexit …
int git_atexit(void (*handler)(void));
#endif
static inline size_t st_add(size_t a, size_t b)
{ … }
#define st_add3(a,b,c) …
#define st_add4(a,b,c,d) …
static inline size_t st_mult(size_t a, size_t b)
{ … }
static inline size_t st_sub(size_t a, size_t b)
{ … }
static inline size_t st_left_shift(size_t a, unsigned shift)
{ … }
static inline unsigned long cast_size_t_to_ulong(size_t a)
{ … }
static inline uint32_t cast_size_t_to_uint32_t(size_t a)
{ … }
static inline int cast_size_t_to_int(size_t a)
{ … }
#ifndef MAX_IO_SIZE
#define MAX_IO_SIZE_DEFAULT …
# if defined(SSIZE_MAX) && (SSIZE_MAX < MAX_IO_SIZE_DEFAULT)
#define MAX_IO_SIZE …
# else
#define MAX_IO_SIZE …
# endif
#endif
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#define xalloca(size) …
#define xalloca_free(p) …
#else
#define xalloca …
#define xalloca_free …
#endif
#define FREE_AND_NULL(p) …
#define ALLOC_ARRAY(x, alloc) …
#define CALLOC_ARRAY(x, alloc) …
#define REALLOC_ARRAY(x, alloc) …
#define COPY_ARRAY(dst, src, n) …
static inline void copy_array(void *dst, const void *src, size_t n, size_t size)
{ … }
#define MOVE_ARRAY(dst, src, n) …
static inline void move_array(void *dst, const void *src, size_t n, size_t size)
{ … }
#define DUP_ARRAY(dst, src, n) …
#define FLEX_ALLOC_MEM(x, flexname, buf, len) …
#define FLEXPTR_ALLOC_MEM(x, ptrname, buf, len) …
#define FLEX_ALLOC_STR(x, flexname, str) …
#define FLEXPTR_ALLOC_STR(x, ptrname, str) …
#define alloc_nr(x) …
#define ALLOC_GROW(x, nr, alloc) …
#define ALLOC_GROW_BY(x, nr, increase, alloc) …
static inline char *xstrdup_or_null(const char *str)
{ … }
static inline size_t xsize_t(off_t len)
{ … }
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX …
#endif
#include "sane-ctype.h"
static inline int skip_iprefix(const char *str, const char *prefix,
const char **out)
{ … }
static inline int skip_iprefix_mem(const char *buf, size_t len,
const char *prefix,
const char **out, size_t *outlen)
{ … }
static inline int strtoul_ui(char const *s, int base, unsigned int *result)
{ … }
static inline int strtol_i(char const *s, int base, int *result)
{ … }
void git_stable_qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
#ifdef INTERNAL_QSORT
#define qsort …
#endif
#define QSORT(base, n, compar) …
static inline void sane_qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *))
{ … }
#define STABLE_QSORT(base, n, compar) …
#ifndef HAVE_ISO_QSORT_S
int git_qsort_s(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *, void *), void *ctx);
#define qsort_s …
#endif
#define QSORT_S(base, n, compar, ctx) …
#ifndef REG_STARTEND
#error "Git requires REG_STARTEND support. Compile with NO_REGEX=NeedsStartEnd"
#endif
static inline int regexec_buf(const regex_t *preg, const char *buf, size_t size,
size_t nmatch, regmatch_t pmatch[], int eflags)
{ … }
#ifdef USE_ENHANCED_BASIC_REGULAR_EXPRESSIONS
int git_regcomp(regex_t *preg, const char *pattern, int cflags);
#define regcomp …
#endif
#ifndef DIR_HAS_BSD_GROUP_SEMANTICS
#define FORCE_DIR_SET_GID …
#else
#define FORCE_DIR_SET_GID …
#endif
#ifdef NO_NSEC
#undef USE_NSEC
#define ST_CTIME_NSEC …
#define ST_MTIME_NSEC …
#else
#ifdef USE_ST_TIMESPEC
#define ST_CTIME_NSEC …
#define ST_MTIME_NSEC …
#else
#define ST_CTIME_NSEC(st) …
#define ST_MTIME_NSEC(st) …
#endif
#endif
#ifdef UNRELIABLE_FSTAT
#define fstat_is_reliable …
#else
#define fstat_is_reliable() …
#endif
#ifndef va_copy
#ifdef __va_copy
#define va_copy …
#else
#define va_copy …
#endif
#endif
extern int BUG_exit_code;
extern int bug_called_must_BUG;
__attribute__((format (printf, 3, 4))) NORETURN
void BUG_fl(const char *file, int line, const char *fmt, ...);
#define BUG(...) …
__attribute__((format (printf, 3, 4)))
void bug_fl(const char *file, int line, const char *fmt, ...);
#define bug(...) …
#define BUG_if_bug(...) …
#ifndef FSYNC_METHOD_DEFAULT
#ifdef __APPLE__
#define FSYNC_METHOD_DEFAULT …
#else
#define FSYNC_METHOD_DEFAULT …
#endif
#endif
#ifndef SHELL_PATH
#define SHELL_PATH …
#endif
#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
static inline void git_flockfile(FILE *fh UNUSED)
{
;
}
static inline void git_funlockfile(FILE *fh UNUSED)
{
;
}
#undef flockfile
#undef funlockfile
#undef getc_unlocked
#define flockfile …
#define funlockfile …
#define getc_unlocked …
#endif
#ifdef FILENO_IS_A_MACRO
int git_fileno(FILE *stream);
# ifndef COMPAT_CODE_FILENO
# undef fileno
#define fileno …
# endif
#endif
#ifdef NEED_ACCESS_ROOT_HANDLER
int git_access(const char *path, int mode);
# ifndef COMPAT_CODE_ACCESS
# ifdef access
# undef access
# endif
#define access …
# endif
#endif
static inline int is_missing_file_error(int errno_)
{ … }
int cmd_main(int, const char **);
int common_exit(const char *file, int line, int code);
#define exit(code) …
#ifdef SUPPRESS_ANNOTATED_LEAKS
void unleak_memory(const void *ptr, size_t len);
#define UNLEAK …
#else
#define UNLEAK(var) …
#endif
#define z_const
#include <zlib.h>
#if ZLIB_VERNUM < 0x1290
int uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong *sourceLen);
#endif
#include "banned.h"
#define container_of(ptr, type, member) …
static inline void *container_of_or_null_offset(void *ptr, size_t offset)
{ … }
#define container_of_or_null(ptr, type, member) …
#if defined(__GNUC__)
#define OFFSETOF_VAR(ptr, member) …
#else
#define OFFSETOF_VAR …
#endif
#endif