return -1;
}
#define error(...) (error(__VA_ARGS__), const_error())
+#define error_errno(...) (error_errno(__VA_ARGS__), const_error())
#endif
extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));
return 0;
}
+/*
+ * Like skip_prefix, but promises never to read past "len" bytes of the input
+ * buffer, and returns the remaining number of bytes in "out" via "outlen".
+ */
+static inline int skip_prefix_mem(const char *buf, size_t len,
+ const char *prefix,
+ const char **out, size_t *outlen)
+{
+ size_t prefix_len = strlen(prefix);
+ if (prefix_len <= len && !memcmp(buf, prefix, prefix_len)) {
+ *out = buf + prefix_len;
+ *outlen = len - prefix_len;
+ return 1;
+ }
+ return 0;
+}
+
/*
* If buf ends with suffix, return 1 and subtract the length of the suffix
* from *len. Otherwise, return 0 and leave *len untouched.
const void *needle, size_t needlelen);
#endif
+#ifdef OVERRIDE_STRDUP
+#ifdef strdup
+#undef strdup
+#endif
+#define strdup gitstrdup
+char *gitstrdup(const char *s);
+#endif
+
#ifdef NO_GETPAGESIZE
#define getpagesize() sysconf(_SC_PAGESIZE)
#endif
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
#ifdef FREAD_READS_DIRECTORIES
#ifdef fopen
#undef fopen
#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:
* you can do:
*
* struct foo *f;
- * FLEX_ALLOC_STR(f, name, src);
+ * FLEXPTR_ALLOC_STR(f, name, src);
*
* and "name" will point to a block of memory after the struct, which will be
* freed along with the struct (but the pointer can be repointed anywhere).
* 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) \
#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;
#define qsort git_qsort
#endif
+#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)
+{
+ assert(nmatch > 0 && pmatch);
+ pmatch[0].rm_so = 0;
+ pmatch[0].rm_eo = size;
+ return regexec(preg, buf, nmatch, pmatch, eflags | REG_STARTEND);
+}
+
#ifndef DIR_HAS_BSD_GROUP_SEMANTICS
# define FORCE_DIR_SET_GID S_ISGID
#else