git-compat-util.h 8.9 KB
Newer Older
1 2 3
#ifndef GIT_COMPAT_UTIL_H
#define GIT_COMPAT_UTIL_H

4 5
#define _FILE_OFFSET_BITS 64

6
#ifndef FLEX_ARRAY
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * See if our compiler is known to support flexible array members.
 */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define FLEX_ARRAY /* empty */
#elif defined(__GNUC__)
# if (__GNUC__ >= 3)
#  define FLEX_ARRAY /* empty */
# else
#  define FLEX_ARRAY 0 /* older GNU extension */
# endif
#endif

/*
 * Otherwise, default to safer but a bit wasteful traditional style
 */
#ifndef FLEX_ARRAY
# define FLEX_ARRAY 1
25 26 27
#endif
#endif

28 29
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

30 31 32 33 34 35 36
#ifdef __GNUC__
#define TYPEOF(x) (__typeof__(x))
#else
#define TYPEOF(x)
#endif

#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
P
Pierre Habouzit 已提交
37
#define HAS_MULTI_BITS(i)  ((i) & ((i) - 1))  /* checks if an integer has more than 1 bit set */
38

39 40 41
/* Approximation of the length of the decimal representation of this type. */
#define decimal_length(x)	((int)(sizeof(x) * 2.56 + 0.5) + 1)

B
Boyd Lynn Gerber 已提交
42
#if !defined(__APPLE__) && !defined(__FreeBSD__)  && !defined(__USLC__) && !defined(_M_UNIX)
43 44
#define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
45
#endif
46 47 48
#define _ALL_SOURCE 1
#define _GNU_SOURCE 1
#define _BSD_SOURCE 1
49

50 51 52 53 54 55 56 57 58 59 60 61 62
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <sys/param.h>
#include <sys/types.h>
#include <dirent.h>
63 64 65 66
#include <sys/time.h>
#include <time.h>
#include <signal.h>
#include <fnmatch.h>
J
Johannes Sixt 已提交
67 68 69 70 71
#include <assert.h>
#include <regex.h>
#include <utime.h>
#ifndef __MINGW32__
#include <sys/wait.h>
72 73
#include <sys/poll.h>
#include <sys/socket.h>
74
#include <sys/ioctl.h>
75
#ifndef NO_SYS_SELECT_H
76
#include <sys/select.h>
77
#endif
78 79 80 81 82
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>
83
#include <inttypes.h>
84 85 86 87 88
#if defined(__CYGWIN__)
#undef _XOPEN_SOURCE
#include <grp.h>
#define _XOPEN_SOURCE 600
#else
89
#undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
90
#include <grp.h>
91
#define _ALL_SOURCE 1
92
#endif
J
Johannes Sixt 已提交
93 94 95 96
#else 	/* __MINGW32__ */
/* pull in Windows compatibility stuff */
#include "compat/mingw.h"
#endif	/* __MINGW32__ */
97 98 99 100

#ifndef NO_ICONV
#include <iconv.h>
#endif
101

R
Robert Shearman 已提交
102 103 104 105 106
#ifndef NO_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif

107 108 109 110 111 112 113
/* On most systems <limits.h> would have given us this, but
 * not on some systems (e.g. GNU/Hurd).
 */
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif

114 115 116 117
#ifndef PRIuMAX
#define PRIuMAX "llu"
#endif

118 119 120 121 122 123 124 125
#ifndef PRIu32
#define PRIu32 "u"
#endif

#ifndef PRIx32
#define PRIx32 "x"
#endif

126 127 128 129
#ifndef PATH_SEP
#define PATH_SEP ':'
#endif

130 131 132 133
#ifndef STRIP_EXTENSION
#define STRIP_EXTENSION ""
#endif

134 135 136 137 138 139 140 141
#ifndef has_dos_drive_prefix
#define has_dos_drive_prefix(path) 0
#endif

#ifndef is_dir_sep
#define is_dir_sep(c) ((c) == '/')
#endif

142 143 144 145 146 147 148 149 150 151 152 153 154
#ifdef __GNUC__
#define NORETURN __attribute__((__noreturn__))
#else
#define NORETURN
#ifndef __attribute__
#define __attribute__(x)
#endif
#endif

/* General helper functions */
extern void usage(const char *err) NORETURN;
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
155
extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
156

P
Petr Baudis 已提交
157 158
extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);

J
Junio C Hamano 已提交
159
extern int prefixcmp(const char *str, const char *prefix);
160
extern time_t tm_to_time_t(const struct tm *tm);
J
Junio C Hamano 已提交
161

162 163 164 165 166 167
static inline const char *skip_prefix(const char *str, const char *prefix)
{
	size_t len = strlen(prefix);
	return strncmp(str, prefix, len) ? NULL : str + len;
}

168 169 170 171 172 173 174 175 176
#ifdef NO_MMAP

#ifndef PROT_READ
#define PROT_READ 1
#define PROT_WRITE 2
#define MAP_PRIVATE 1
#define MAP_FAILED ((void*)-1)
#endif

S
Shawn O. Pearce 已提交
177 178 179 180
#define mmap git_mmap
#define munmap git_munmap
extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
extern int git_munmap(void *start, size_t length);
181

182
/* This value must be multiple of (pagesize * 2) */
183 184
#define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)

185 186 187
#else /* NO_MMAP */

#include <sys/mman.h>
188 189

/* This value must be multiple of (pagesize * 2) */
190 191 192 193
#define DEFAULT_PACKED_GIT_WINDOW_SIZE \
	(sizeof(void*) >= 8 \
		?  1 * 1024 * 1024 * 1024 \
		: 32 * 1024 * 1024)
194 195 196

#endif /* NO_MMAP */

197 198 199 200 201 202
#ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
#define on_disk_bytes(st) ((st).st_size)
#else
#define on_disk_bytes(st) ((st).st_blocks * 512)
#endif

203
#define DEFAULT_PACKED_GIT_LIMIT \
204
	((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
205

206 207 208 209
#ifdef NO_PREAD
#define pread git_pread
extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
#endif
210 211 212 213 214 215
/*
 * Forward decl that will remind us if its twin in cache.h changes.
 * This function is used in compat/pread.c.  But we can't include
 * cache.h there.
 */
extern ssize_t read_in_full(int fd, void *buf, size_t count);
216

217 218 219 220 221
#ifdef NO_SETENV
#define setenv gitsetenv
extern int gitsetenv(const char *, const char *, int);
#endif

222 223 224 225 226
#ifdef NO_MKDTEMP
#define mkdtemp gitmkdtemp
extern char *gitmkdtemp(char *);
#endif

J
Jason Riedy 已提交
227 228 229 230 231
#ifdef NO_UNSETENV
#define unsetenv gitunsetenv
extern void gitunsetenv(const char *);
#endif

232 233 234 235 236
#ifdef NO_STRCASESTR
#define strcasestr gitstrcasestr
extern char *gitstrcasestr(const char *haystack, const char *needle);
#endif

237 238 239 240 241
#ifdef NO_STRLCPY
#define strlcpy gitstrlcpy
extern size_t gitstrlcpy(char *, const char *, size_t);
#endif

242 243 244 245 246
#ifdef NO_STRTOUMAX
#define strtoumax gitstrtoumax
extern uintmax_t gitstrtoumax(const char *, char **, int);
#endif

247 248 249 250 251
#ifdef NO_HSTRERROR
#define hstrerror githstrerror
extern const char *githstrerror(int herror);
#endif

R
René Scharfe 已提交
252 253 254 255 256 257
#ifdef NO_MEMMEM
#define memmem gitmemmem
void *gitmemmem(const void *haystack, size_t haystacklen,
                const void *needle, size_t needlelen);
#endif

258
#ifdef FREAD_READS_DIRECTORIES
259 260 261
#ifdef fopen
#undef fopen
#endif
262 263 264 265
#define fopen(a,b) git_fopen(a,b)
extern FILE *git_fopen(const char*, const char*);
#endif

266 267 268 269 270 271 272 273 274
#ifdef SNPRINTF_RETURNS_BOGUS
#define snprintf git_snprintf
extern int git_snprintf(char *str, size_t maxsize,
			const char *format, ...);
#define vsnprintf git_vsnprintf
extern int git_vsnprintf(char *str, size_t maxsize,
			 const char *format, va_list ap);
#endif

275 276 277 278 279 280 281
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 1)
#define HAVE_STRCHRNUL
#endif
#endif

#ifndef HAVE_STRCHRNUL
R
René Scharfe 已提交
282
#define strchrnul gitstrchrnul
283 284 285 286 287 288
static inline char *gitstrchrnul(const char *s, int c)
{
	while (*s && *s != c)
		s++;
	return (char *)s;
}
R
René Scharfe 已提交
289 290
#endif

291
extern void release_pack_memory(size_t, int);
292

293 294 295 296 297 298 299 300 301 302 303 304
extern char *xstrdup(const char *str);
extern void *xmalloc(size_t size);
extern void *xmemdupz(const void *data, size_t len);
extern char *xstrndup(const char *str, size_t len);
extern void *xrealloc(void *ptr, size_t size);
extern void *xcalloc(size_t nmemb, size_t size);
extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
extern ssize_t xread(int fd, void *buf, size_t len);
extern ssize_t xwrite(int fd, const void *buf, size_t len);
extern int xdup(int fd);
extern FILE *xfdopen(int fd, const char *mode);
extern int xmkstemp(char *template);
305

306 307 308 309 310
static inline size_t xsize_t(off_t len)
{
	return (size_t)len;
}

311
static inline int has_extension(const char *filename, const char *ext)
R
Rene Scharfe 已提交
312
{
313 314
	size_t len = strlen(filename);
	size_t extlen = strlen(ext);
R
Rene Scharfe 已提交
315 316 317
	return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
}

318 319 320 321 322 323 324 325 326 327 328
/* Sane ctype - no locale, and works with signed chars */
#undef isspace
#undef isdigit
#undef isalpha
#undef isalnum
#undef tolower
#undef toupper
extern unsigned char sane_ctype[256];
#define GIT_SPACE 0x01
#define GIT_DIGIT 0x02
#define GIT_ALPHA 0x04
329
#define GIT_SPECIAL 0x08
330 331 332 333 334
#define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
#define isspace(x) sane_istest(x,GIT_SPACE)
#define isdigit(x) sane_istest(x,GIT_DIGIT)
#define isalpha(x) sane_istest(x,GIT_ALPHA)
#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
335
#define isspecial(x) sane_istest(x,GIT_SPECIAL)
336 337 338 339 340 341 342 343 344 345
#define tolower(x) sane_case((unsigned char)(x), 0x20)
#define toupper(x) sane_case((unsigned char)(x), 0)

static inline int sane_case(int x, int high)
{
	if (sane_istest(x, GIT_ALPHA))
		x = (x & ~0x20) | high;
	return x;
}

346 347 348 349 350 351 352 353 354 355 356 357 358
static inline int strtoul_ui(char const *s, int base, unsigned int *result)
{
	unsigned long ul;
	char *p;

	errno = 0;
	ul = strtoul(s, &p, base);
	if (errno || *p || p == s || (unsigned int) ul != ul)
		return -1;
	*result = ul;
	return 0;
}

359 360 361 362 363 364 365 366 367 368 369 370 371
static inline int strtol_i(char const *s, int base, int *result)
{
	long ul;
	char *p;

	errno = 0;
	ul = strtol(s, &p, base);
	if (errno || *p || p == s || (int) ul != ul)
		return -1;
	*result = ul;
	return 0;
}

372 373 374 375 376 377
#ifdef INTERNAL_QSORT
void git_qsort(void *base, size_t nmemb, size_t size,
	       int(*compar)(const void *, const void *));
#define qsort git_qsort
#endif

378 379 380 381 382 383
#ifndef DIR_HAS_BSD_GROUP_SEMANTICS
# define FORCE_DIR_SET_GID S_ISGID
#else
# define FORCE_DIR_SET_GID 0
#endif

384
#endif