git-compat-util.hon commit Merge part of js/portable into next (1a9366c)
   1#ifndef GIT_COMPAT_UTIL_H
   2#define GIT_COMPAT_UTIL_H
   3
   4#ifndef FLEX_ARRAY
   5#if defined(__GNUC__) && (__GNUC__ < 3)
   6#define FLEX_ARRAY 0
   7#else
   8#define FLEX_ARRAY /* empty */
   9#endif
  10#endif
  11
  12#include <unistd.h>
  13#include <stdio.h>
  14#include <sys/stat.h>
  15#include <fcntl.h>
  16#include <stddef.h>
  17#include <stdlib.h>
  18#include <stdarg.h>
  19#include <string.h>
  20#include <errno.h>
  21#include <limits.h>
  22#include <sys/param.h>
  23#include <netinet/in.h>
  24#include <sys/types.h>
  25#include <dirent.h>
  26
  27#ifdef __GNUC__
  28#define NORETURN __attribute__((__noreturn__))
  29#else
  30#define NORETURN
  31#ifndef __attribute__
  32#define __attribute__(x)
  33#endif
  34#endif
  35
  36/* General helper functions */
  37extern void usage(const char *err) NORETURN;
  38extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
  39extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
  40
  41#ifdef NO_MMAP
  42
  43#ifndef PROT_READ
  44#define PROT_READ 1
  45#define PROT_WRITE 2
  46#define MAP_PRIVATE 1
  47#define MAP_FAILED ((void*)-1)
  48#endif
  49
  50#define mmap gitfakemmap
  51#define munmap gitfakemunmap
  52extern void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);
  53extern int gitfakemunmap(void *start, size_t length);
  54
  55#else /* NO_MMAP */
  56
  57#include <sys/mman.h>
  58
  59#endif /* NO_MMAP */
  60
  61#ifdef NO_SETENV
  62#define setenv gitsetenv
  63extern int gitsetenv(const char *, const char *, int);
  64#endif
  65
  66#ifdef NO_UNSETENV
  67#define unsetenv gitunsetenv
  68extern void gitunsetenv(const char *);
  69#endif
  70
  71#ifdef NO_STRCASESTR
  72#define strcasestr gitstrcasestr
  73extern char *gitstrcasestr(const char *haystack, const char *needle);
  74#endif
  75
  76static inline void *xmalloc(size_t size)
  77{
  78        void *ret = malloc(size);
  79        if (!ret && !size)
  80                ret = malloc(1);
  81        if (!ret)
  82                die("Out of memory, malloc failed");
  83        return ret;
  84}
  85
  86static inline void *xrealloc(void *ptr, size_t size)
  87{
  88        void *ret = realloc(ptr, size);
  89        if (!ret && !size)
  90                ret = realloc(ptr, 1);
  91        if (!ret)
  92                die("Out of memory, realloc failed");
  93        return ret;
  94}
  95
  96static inline void *xcalloc(size_t nmemb, size_t size)
  97{
  98        void *ret = calloc(nmemb, size);
  99        if (!ret && (!nmemb || !size))
 100                ret = calloc(1, 1);
 101        if (!ret)
 102                die("Out of memory, calloc failed");
 103        return ret;
 104}
 105
 106static inline ssize_t xread(int fd, void *buf, size_t len)
 107{
 108        ssize_t nr;
 109        while (1) {
 110                nr = read(fd, buf, len);
 111                if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
 112                        continue;
 113                return nr;
 114        }
 115}
 116
 117static inline ssize_t xwrite(int fd, const void *buf, size_t len)
 118{
 119        ssize_t nr;
 120        while (1) {
 121                nr = write(fd, buf, len);
 122                if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
 123                        continue;
 124                return nr;
 125        }
 126}
 127
 128/* Sane ctype - no locale, and works with signed chars */
 129#undef isspace
 130#undef isdigit
 131#undef isalpha
 132#undef isalnum
 133#undef tolower
 134#undef toupper
 135extern unsigned char sane_ctype[256];
 136#define GIT_SPACE 0x01
 137#define GIT_DIGIT 0x02
 138#define GIT_ALPHA 0x04
 139#define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
 140#define isspace(x) sane_istest(x,GIT_SPACE)
 141#define isdigit(x) sane_istest(x,GIT_DIGIT)
 142#define isalpha(x) sane_istest(x,GIT_ALPHA)
 143#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
 144#define tolower(x) sane_case((unsigned char)(x), 0x20)
 145#define toupper(x) sane_case((unsigned char)(x), 0)
 146
 147static inline int sane_case(int x, int high)
 148{
 149        if (sane_istest(x, GIT_ALPHA))
 150                x = (x & ~0x20) | high;
 151        return x;
 152}
 153
 154#ifndef MAXPATHLEN
 155#define MAXPATHLEN 256
 156#endif
 157#endif