#include <sys/time.h>
#include <time.h>
#include <signal.h>
-#ifndef USE_WILDMATCH
-#include <fnmatch.h>
-#endif
#include <assert.h>
#include <regex.h>
#include <utime.h>
#define has_dos_drive_prefix(path) 0
#endif
+#ifndef offset_1st_component
+#define offset_1st_component(path) (is_dir_sep((path)[0]))
+#endif
+
#ifndef is_dir_sep
#define is_dir_sep(c) ((c) == '/')
#endif
#else
#define NORETURN
#define NORETURN_PTR
+#ifndef __GNUC__
#ifndef __attribute__
#define __attribute__(x)
#endif
#endif
+#endif
/* The sentinel attribute is valid from gcc version 4.0 */
#if defined(__GNUC__) && (__GNUC__ >= 4)
#include "compat/bswap.h"
-#ifdef USE_WILDMATCH
#include "wildmatch.h"
-#define FNM_PATHNAME WM_PATHNAME
-#define FNM_CASEFOLD WM_CASEFOLD
-#define FNM_NOMATCH WM_NOMATCH
-static inline int fnmatch(const char *pattern, const char *string, int flags)
-{
- return wildmatch(pattern, string, flags, NULL);
-}
-#endif
/* General helper functions */
extern void vreportf(const char *prefix, const char *err, va_list params);
* trying to help gcc, anyway, it's OK; other compilers will fall back to
* using the function as usual.
*/
-#if defined(__GNUC__) && ! defined(__clang__)
-#define error(...) (error(__VA_ARGS__), -1)
+#if defined(__GNUC__)
+static inline int const_error(void)
+{
+ return -1;
+}
+#define error(...) (error(__VA_ARGS__), const_error())
#endif
extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));
extern void set_die_is_recursing_routine(int (*routine)(void));
extern int starts_with(const char *str, const char *prefix);
-extern int prefixcmp(const char *str, const char *prefix);
-extern int ends_with(const char *str, const char *suffix);
-extern int suffixcmp(const char *str, const char *suffix);
-static inline const char *skip_prefix(const char *str, const char *prefix)
+/*
+ * If the string "str" begins with the string found in "prefix", return 1.
+ * The "out" parameter is set to "str + strlen(prefix)" (i.e., to the point in
+ * the string right after the prefix).
+ *
+ * Otherwise, return 0 and leave "out" untouched.
+ *
+ * Examples:
+ *
+ * [extract branch name, fail if not a branch]
+ * if (!skip_prefix(ref, "refs/heads/", &branch)
+ * return -1;
+ *
+ * [skip prefix if present, otherwise use whole string]
+ * skip_prefix(name, "refs/heads/", &name);
+ */
+static inline int skip_prefix(const char *str, const char *prefix,
+ const char **out)
+{
+ do {
+ if (!*prefix) {
+ *out = str;
+ return 1;
+ }
+ } while (*str++ == *prefix++);
+ 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.
+ */
+static inline int strip_suffix_mem(const char *buf, size_t *len,
+ const char *suffix)
+{
+ size_t suflen = strlen(suffix);
+ if (*len < suflen || memcmp(buf + (*len - suflen), suffix, suflen))
+ return 0;
+ *len -= suflen;
+ return 1;
+}
+
+/*
+ * If str ends with suffix, return 1 and set *len to the size of the string
+ * without the suffix. Otherwise, return 0 and set *len to the size of the
+ * string.
+ *
+ * Note that we do _not_ NUL-terminate str to the new length.
+ */
+static inline int strip_suffix(const char *str, const char *suffix, size_t *len)
+{
+ *len = strlen(str);
+ return strip_suffix_mem(str, len, suffix);
+}
+
+static inline int ends_with(const char *str, const char *suffix)
{
- size_t len = strlen(prefix);
- return strncmp(str, prefix, len) ? NULL : str + len;
+ size_t len;
+ return strip_suffix(str, suffix, &len);
}
#if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
#endif
#ifdef SNPRINTF_RETURNS_BOGUS
+#ifdef snprintf
+#undef snprintf
+#endif
#define snprintf git_snprintf
extern int git_snprintf(char *str, size_t maxsize,
const char *format, ...);
+#ifdef vsnprintf
+#undef vsnprintf
+#endif
#define vsnprintf git_vsnprintf
extern int git_vsnprintf(char *str, size_t maxsize,
const char *format, va_list ap);
typedef void (*try_to_free_t)(size_t);
extern try_to_free_t set_try_to_free_routine(try_to_free_t);
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# define xalloca(size) (alloca(size))
+# define xalloca_free(p) do {} while (0)
+#else
+# define xalloca(size) (xmalloc(size))
+# define xalloca_free(p) (free(p))
+#endif
extern char *xstrdup(const char *str);
extern void *xmalloc(size_t size);
extern void *xmallocz(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 ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
extern int xdup(int fd);
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, unsigned char *sha1);
+extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);
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);
-}
-
/* in ctype.c, for kwset users */
extern const char tolower_trans_tbl[256];
#endif
#endif
+#if defined(__GNUC__) || (_MSC_VER >= 1400)
+#define HAVE_VARIADIC_MACROS 1
+#endif
+
/*
* Preserves errno, prints a message, but gives no warning for ENOENT.
* Always returns the return value of unlink(2).