2009-04-20 17:00:56 +04:00
# ifndef GIT_COMPAT_UTIL_H
# define GIT_COMPAT_UTIL_H
# define _FILE_OFFSET_BITS 64
# ifndef FLEX_ARRAY
/*
* 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
# endif
# endif
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
# ifdef __GNUC__
# define TYPEOF(x) (__typeof__(x))
# else
# define TYPEOF(x)
# endif
# define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
# define HAS_MULTI_BITS(i) ((i) & ((i) - 1)) /* checks if an integer has more than 1 bit set */
/* Approximation of the length of the decimal representation of this type. */
# define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
# if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && !defined(_M_UNIX)
# 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 */
# endif
# define _ALL_SOURCE 1
# define _GNU_SOURCE 1
# define _BSD_SOURCE 1
# 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>
# include <sys/time.h>
# include <time.h>
# include <signal.h>
# include <fnmatch.h>
# include <assert.h>
# include <regex.h>
# include <utime.h>
# include <sys/wait.h>
# include <sys/poll.h>
# include <sys/socket.h>
# include <sys/ioctl.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 <inttypes.h>
# ifndef NO_ICONV
# include <iconv.h>
# endif
/* 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
# ifndef PRIuMAX
# define PRIuMAX "llu"
# endif
# ifndef PRIu32
# define PRIu32 "u"
# endif
# ifndef PRIx32
# define PRIx32 "x"
# endif
# ifndef PATH_SEP
# define PATH_SEP ':'
# endif
# ifndef STRIP_EXTENSION
# define STRIP_EXTENSION ""
# endif
# ifndef has_dos_drive_prefix
# define has_dos_drive_prefix(path) 0
# endif
# ifndef is_dir_sep
# define is_dir_sep(c) ((c) == ' / ')
# endif
# 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 ) ) ) ;
extern void warning ( const char * err , . . . ) __attribute__ ( ( format ( printf , 1 , 2 ) ) ) ;
extern void set_die_routine ( void ( * routine ) ( const char * err , va_list params ) NORETURN ) ;
extern int prefixcmp ( const char * str , const char * prefix ) ;
extern time_t tm_to_time_t ( const struct tm * tm ) ;
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 ;
}
# if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
# ifndef PROT_READ
# define PROT_READ 1
# define PROT_WRITE 2
# define MAP_PRIVATE 1
# define MAP_FAILED ((void*)-1)
# endif
# 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 ) ;
# else /* NO_MMAP || USE_WIN32_MMAP */
# include <sys/mman.h>
# endif /* NO_MMAP || USE_WIN32_MMAP */
# ifdef NO_MMAP
/* This value must be multiple of (pagesize * 2) */
# define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)
# else /* NO_MMAP */
/* This value must be multiple of (pagesize * 2) */
# define DEFAULT_PACKED_GIT_WINDOW_SIZE \
( sizeof ( void * ) > = 8 \
? 1 * 1024 * 1024 * 1024 \
: 32 * 1024 * 1024 )
# endif /* NO_MMAP */
# 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
# define DEFAULT_PACKED_GIT_LIMIT \
( ( 1024L * 1024L ) * ( sizeof ( void * ) > = 8 ? 8192 : 256 ) )
# ifdef NO_PREAD
# define pread git_pread
extern ssize_t git_pread ( int fd , void * buf , size_t count , off_t offset ) ;
# endif
/*
* 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 ) ;
# ifdef NO_SETENV
# define setenv gitsetenv
extern int gitsetenv ( const char * , const char * , int ) ;
# endif
# ifdef NO_MKDTEMP
# define mkdtemp gitmkdtemp
extern char * gitmkdtemp ( char * ) ;
# endif
# ifdef NO_UNSETENV
# define unsetenv gitunsetenv
extern void gitunsetenv ( const char * ) ;
# endif
# ifdef NO_STRCASESTR
# define strcasestr gitstrcasestr
extern char * gitstrcasestr ( const char * haystack , const char * needle ) ;
# endif
# ifdef NO_STRLCPY
# define strlcpy gitstrlcpy
extern size_t gitstrlcpy ( char * , const char * , size_t ) ;
# endif
# ifdef NO_STRTOUMAX
# define strtoumax gitstrtoumax
extern uintmax_t gitstrtoumax ( const char * , char * * , int ) ;
# endif
# ifdef NO_HSTRERROR
# define hstrerror githstrerror
extern const char * githstrerror ( int herror ) ;
# endif
# ifdef NO_MEMMEM
# define memmem gitmemmem
void * gitmemmem ( const void * haystack , size_t haystacklen ,
const void * needle , size_t needlelen ) ;
# endif
# ifdef FREAD_READS_DIRECTORIES
# ifdef fopen
# undef fopen
# endif
# define fopen(a,b) git_fopen(a,b)
extern FILE * git_fopen ( const char * , const char * ) ;
# endif
# 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
# ifdef __GLIBC_PREREQ
# if __GLIBC_PREREQ(2, 1)
# define HAVE_STRCHRNUL
# endif
# endif
# ifndef HAVE_STRCHRNUL
# define strchrnul gitstrchrnul
static inline char * gitstrchrnul ( const char * s , int c )
{
while ( * s & & * s ! = c )
s + + ;
return ( char * ) s ;
}
# endif
2009-04-20 17:22:22 +04:00
/*
* Wrappers :
*/
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 ) ;
2009-05-27 11:10:38 +04:00
extern int xmkstemp ( char * template ) ;
2009-04-20 17:00:56 +04:00
static inline size_t xsize_t ( off_t len )
{
return ( size_t ) len ;
}
static inline int has_extension ( const char * filename , const char * ext )
{
size_t len = strlen ( filename ) ;
size_t extlen = strlen ( ext ) ;
return len > extlen & & ! memcmp ( filename + len - extlen , ext , extlen ) ;
}
/* Sane ctype - no locale, and works with signed chars */
# undef isascii
# undef isspace
# undef isdigit
# undef isalpha
# undef isalnum
# undef tolower
# undef toupper
extern unsigned char sane_ctype [ 256 ] ;
2009-06-18 11:44:20 +04:00
# define GIT_SPACE 0x01
# define GIT_DIGIT 0x02
# define GIT_ALPHA 0x04
# define GIT_GLOB_SPECIAL 0x08
# define GIT_REGEX_SPECIAL 0x10
# define GIT_PRINT_EXTRA 0x20
# define GIT_PRINT 0x3E
2009-04-20 17:00:56 +04:00
# define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
# define isascii(x) (((x) & ~0x7f) == 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)
2009-06-18 11:44:20 +04:00
# define isprint(x) sane_istest(x,GIT_PRINT)
2009-04-20 17:00:56 +04:00
# define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL)
# define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL)
# 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 ;
}
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 ;
}
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 ;
}
# 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
# ifndef DIR_HAS_BSD_GROUP_SEMANTICS
# define FORCE_DIR_SET_GID S_ISGID
# else
# define FORCE_DIR_SET_GID 0
# endif
# ifdef NO_NSEC
# undef USE_NSEC
# define ST_CTIME_NSEC(st) 0
# define ST_MTIME_NSEC(st) 0
# else
# ifdef USE_ST_TIMESPEC
# define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))
# define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec))
# else
# define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec))
# define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec))
# endif
# endif
# endif