config.mak.uname: set FREAD_READS_DIRECTORIES for Linux and FreeBSD
[gitweb.git] / git-compat-util.h
index 8aab0c30474764b3e71d4e6c0bc66c52218b3d5e..6be55cf8b39b9322339f92479a1e8b3396a3813c 100644 (file)
@@ -527,6 +527,16 @@ static inline int ends_with(const char *str, const char *suffix)
        return strip_suffix(str, suffix, &len);
 }
 
+#define SWAP(a, b) do {                                                \
+       void *_swap_a_ptr = &(a);                               \
+       void *_swap_b_ptr = &(b);                               \
+       unsigned char _swap_buffer[sizeof(a)];                  \
+       memcpy(_swap_buffer, _swap_a_ptr, sizeof(a));           \
+       memcpy(_swap_a_ptr, _swap_b_ptr, sizeof(a) +            \
+              BUILD_ASSERT_OR_ZERO(sizeof(a) == sizeof(b)));   \
+       memcpy(_swap_b_ptr, _swap_buffer, sizeof(a));           \
+} while (0)
+
 #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
 
 #ifndef PROT_READ
@@ -629,11 +639,6 @@ extern int gitsetenv(const char *, const char *, int);
 extern char *gitmkdtemp(char *);
 #endif
 
-#ifdef NO_MKSTEMPS
-#define mkstemps gitmkstemps
-extern int gitmkstemps(char *, int);
-#endif
-
 #ifdef NO_UNSETENV
 #define unsetenv gitunsetenv
 extern void gitunsetenv(const char *);
@@ -684,10 +689,12 @@ char *gitstrdup(const char *s);
 #endif
 
 #ifdef FREAD_READS_DIRECTORIES
-#ifdef fopen
-#undef fopen
-#endif
-#define fopen(a,b) git_fopen(a,b)
+# if !defined(SUPPRESS_FOPEN_REDEFINITION)
+#  ifdef fopen
+#   undef fopen
+#  endif
+#  define fopen(a,b) git_fopen(a,b)
+# endif
 extern FILE *git_fopen(const char*, const char*);
 #endif
 
@@ -793,14 +800,20 @@ extern FILE *xfopen(const char *path, const char *mode);
 extern FILE *xfdopen(int fd, const char *mode);
 extern int xmkstemp(char *template);
 extern int xmkstemp_mode(char *template, int mode);
-extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
-extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);
 extern char *xgetcwd(void);
 extern FILE *fopen_for_writing(const char *path);
 
 #define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc)))
 #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc)))
 
+#define COPY_ARRAY(dst, src, n) copy_array((dst), (src), (n), sizeof(*(dst)) + \
+       BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src))))
+static inline void copy_array(void *dst, const void *src, size_t n, size_t size)
+{
+       if (n)
+               memcpy(dst, src, st_mult(size, n));
+}
+
 /*
  * These functions help you allocate structs with flex arrays, and copy
  * the data directly into the array. For example, if you had:
@@ -843,11 +856,14 @@ extern FILE *fopen_for_writing(const char *path);
  * times, and it must be assignable as an lvalue.
  */
 #define FLEX_ALLOC_MEM(x, flexname, buf, len) do { \
-       (x) = NULL; /* silence -Wuninitialized for offset calculation */ \
-       (x) = xalloc_flex(sizeof(*(x)), (char *)(&((x)->flexname)) - (char *)(x), (buf), (len)); \
+       size_t flex_array_len_ = (len); \
+       (x) = xcalloc(1, st_add3(sizeof(*(x)), flex_array_len_, 1)); \
+       memcpy((void *)(x)->flexname, (buf), flex_array_len_); \
 } while (0)
 #define FLEXPTR_ALLOC_MEM(x, ptrname, buf, len) do { \
-       (x) = xalloc_flex(sizeof(*(x)), sizeof(*(x)), (buf), (len)); \
+       size_t flex_array_len_ = (len); \
+       (x) = xcalloc(1, st_add3(sizeof(*(x)), flex_array_len_, 1)); \
+       memcpy((x) + 1, (buf), flex_array_len_); \
        (x)->ptrname = (void *)((x)+1); \
 } while(0)
 #define FLEX_ALLOC_STR(x, flexname, str) \
@@ -855,14 +871,6 @@ extern FILE *fopen_for_writing(const char *path);
 #define FLEXPTR_ALLOC_STR(x, ptrname, str) \
        FLEXPTR_ALLOC_MEM((x), ptrname, (str), strlen(str))
 
-static inline void *xalloc_flex(size_t base_len, size_t offset,
-                               const void *src, size_t src_len)
-{
-       unsigned char *ret = xcalloc(1, st_add3(base_len, src_len, 1));
-       memcpy(ret + offset, src, src_len);
-       return ret;
-}
-
 static inline char *xstrdup_or_null(const char *str)
 {
        return str ? xstrdup(str) : NULL;
@@ -878,6 +886,12 @@ static inline size_t xsize_t(off_t len)
 __attribute__((format (printf, 3, 4)))
 extern int xsnprintf(char *dst, size_t max, const char *fmt, ...);
 
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 256
+#endif
+
+extern int xgethostname(char *buf, size_t len);
+
 /* in ctype.c, for kwset users */
 extern const unsigned char tolower_trans_tbl[256];
 
@@ -977,6 +991,25 @@ void git_qsort(void *base, size_t nmemb, size_t size,
 #define qsort git_qsort
 #endif
 
+#define QSORT(base, n, compar) sane_qsort((base), (n), sizeof(*(base)), compar)
+static inline void sane_qsort(void *base, size_t nmemb, size_t size,
+                             int(*compar)(const void *, const void *))
+{
+       if (nmemb > 1)
+               qsort(base, nmemb, size, 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 git_qsort_s
+#endif
+
+#define QSORT_S(base, n, compar, ctx) do {                     \
+       if (qsort_s((base), (n), sizeof(*(base)), compar, ctx)) \
+               die("BUG: qsort_s() failed");                   \
+} while (0)
+
 #ifndef REG_STARTEND
 #error "Git requires REG_STARTEND support. Compile with NO_REGEX=NeedsStartEnd"
 #endif
@@ -1090,6 +1123,6 @@ struct tm *git_gmtime_r(const time_t *, struct tm *);
 #define getc_unlocked(fh) getc(fh)
 #endif
 
-#endif
-
 extern int cmd_main(int, const char **);
+
+#endif