Hash :
0291b5b7
Author :
Date :
2011-06-03T19:59:16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
#ifndef INCLUDE_util_h__
#define INCLUDE_util_h__
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define bitsizeof(x) (CHAR_BIT * sizeof(x))
#define MSB(x, bits) ((x) & (~0ULL << (bitsizeof(x) - (bits))))
/*
* Custom memory allocation wrappers
* that set error code and error message
* on allocation failure
*/
GIT_INLINE(void *) git__malloc(size_t len)
{
void *ptr = malloc(len);
if (!ptr)
git__throw(GIT_ENOMEM, "Out of memory. Failed to allocate %d bytes.", (int)len);
return ptr;
}
GIT_INLINE(void *) git__calloc(size_t nelem, size_t elsize)
{
void *ptr = calloc(nelem, elsize);
if (!ptr)
git__throw(GIT_ENOMEM, "Out of memory. Failed to allocate %d bytes.", (int)elsize);
return ptr;
}
GIT_INLINE(char *) git__strdup(const char *str)
{
char *ptr = strdup(str);
if (!ptr)
git__throw(GIT_ENOMEM, "Out of memory. Failed to duplicate string");
return ptr;
}
GIT_INLINE(char *) git__strndup(const char *str, size_t n)
{
size_t length;
char *ptr;
length = strlen(str);
if (n < length)
length = n;
ptr = malloc(length + 1);
if (!ptr)
git__throw(GIT_ENOMEM, "Out of memory. Failed to duplicate string");
memcpy(ptr, str, length);
ptr[length] = 0;
return ptr;
}
GIT_INLINE(void *) git__realloc(void *ptr, size_t size)
{
void *new_ptr = realloc(ptr, size);
if (!new_ptr)
git__throw(GIT_ENOMEM, "Out of memory. Failed to allocate %d bytes.", (int)size);
return new_ptr;
}
extern int git__fmt(char *, size_t, const char *, ...)
GIT_FORMAT_PRINTF(3, 4);
extern int git__prefixcmp(const char *str, const char *prefix);
extern int git__suffixcmp(const char *str, const char *suffix);
extern int git__strtol32(long *n, const char *buff, const char **end_buf, int base);
/*
* The dirname() function shall take a pointer to a character string
* that contains a pathname, and return a pointer to a string that is a
* pathname of the parent directory of that file. Trailing '/' characters
* in the path are not counted as part of the path.
*
* If path does not contain a '/', then dirname() shall return a pointer to
* the string ".". If path is a null pointer or points to an empty string,
* dirname() shall return a pointer to the string "." .
*
* The `git__dirname` implementation is thread safe. The returned
* string must be manually free'd.
*
* The `git__dirname_r` implementation expects a string allocated
* by the user with big enough size.
*/
extern char *git__dirname(const char *path);
extern int git__dirname_r(char *buffer, size_t bufflen, const char *path);
/*
* This function returns the basename of the file, which is the last
* part of its full name given by fname, with the drive letter and
* leading directories stripped off. For example, the basename of
* c:/foo/bar/file.ext is file.ext, and the basename of a:foo is foo.
*
* Trailing slashes and backslashes are significant: the basename of
* c:/foo/bar/ is an empty string after the rightmost slash.
*
* The `git__basename` implementation is thread safe. The returned
* string must be manually free'd.
*
* The `git__basename_r` implementation expects a string allocated
* by the user with big enough size.
*/
extern char *git__basename(const char *path);
extern int git__basename_r(char *buffer, size_t bufflen, const char *path);
extern const char *git__topdir(const char *path);
/**
* Join two paths together. Takes care of properly fixing the
* middle slashes and everything
*
* The paths are joined together into buffer_out; this is expected
* to be an user allocated buffer of `GIT_PATH_MAX` size
*/
extern void git__joinpath_n(char *buffer_out, int npath, ...);
GIT_INLINE(void) git__joinpath(char *buffer_out, const char *path_a, const char *path_b)
{
git__joinpath_n(buffer_out, 2, path_a, path_b);
}
extern void git__hexdump(const char *buffer, size_t n);
extern uint32_t git__hash(const void *key, int len, uint32_t seed);
/** @return true if p fits into the range of a size_t */
GIT_INLINE(int) git__is_sizet(git_off_t p)
{
size_t r = (size_t)p;
return p == (git_off_t)r;
}
/* 32-bit cross-platform rotl */
#ifdef _MSC_VER /* use built-in method in MSVC */
# define git__rotl(v, s) (uint32_t)_rotl(v, s)
#else /* use bitops in GCC; with o2 this gets optimized to a rotl instruction */
# define git__rotl(v, s) (uint32_t)(((uint32_t)(v) << (s)) | ((uint32_t)(v) >> (32 - (s))))
#endif
extern char *git__strtok(char **end, const char *sep);
extern void git__strntolower(char *str, int len);
extern void git__strtolower(char *str);
#define STRLEN(str) (sizeof(str) - 1)
#define GIT_OID_LINE_LENGTH(header) (STRLEN(header) + 1 + GIT_OID_HEXSZ + 1)
/*
* Realloc the buffer pointed at by variable 'x' so that it can hold
* at least 'nr' entries; the number of entries currently allocated
* is 'alloc', using the standard growing factor alloc_nr() macro.
*
* DO NOT USE any expression with side-effect for 'x' or 'alloc'.
*/
#define alloc_nr(x) (((x)+16)*3/2)
#define ALLOC_GROW(x, nr, alloc) \
do { \
if ((nr) > alloc) { \
if (alloc_nr(alloc) < (nr)) \
alloc = (nr); \
else \
alloc = alloc_nr(alloc); \
x = xrealloc((x), alloc * sizeof(*(x))); \
} \
} while (0)
#endif /* INCLUDE_util_h__ */