#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+#ifdef __GNUC__
+#define TYPEOF(x) (__typeof__(x))
+#else
+#define TYPEOF(x)
+#endif
+
+#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
+
+/* Approximation of the length of the decimal representation of this type. */
+#define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
+
#if !defined(__APPLE__) && !defined(__FreeBSD__)
#define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
extern uintmax_t gitstrtoumax(const char *, char **, int);
#endif
-extern void release_pack_memory(size_t);
+extern void release_pack_memory(size_t, int);
static inline char* xstrdup(const char *str)
{
char *ret = strdup(str);
if (!ret) {
- release_pack_memory(strlen(str) + 1);
+ release_pack_memory(strlen(str) + 1, -1);
ret = strdup(str);
if (!ret)
die("Out of memory, strdup failed");
if (!ret && !size)
ret = malloc(1);
if (!ret) {
- release_pack_memory(size);
+ release_pack_memory(size, -1);
ret = malloc(size);
if (!ret && !size)
ret = malloc(1);
return ret;
}
+static inline char *xstrndup(const char *str, size_t len)
+{
+ char *p;
+
+ p = memchr(str, '\0', len);
+ if (p)
+ len = p - str;
+ p = xmalloc(len + 1);
+ memcpy(p, str, len);
+ p[len] = '\0';
+ return p;
+}
+
static inline void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret) {
- release_pack_memory(size);
+ release_pack_memory(size, -1);
ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret && (!nmemb || !size))
ret = calloc(1, 1);
if (!ret) {
- release_pack_memory(nmemb * size);
+ release_pack_memory(nmemb * size, -1);
ret = calloc(nmemb, size);
if (!ret && (!nmemb || !size))
ret = calloc(1, 1);
if (ret == MAP_FAILED) {
if (!length)
return NULL;
- release_pack_memory(length);
+ release_pack_memory(length, fd);
ret = mmap(start, length, prot, flags, fd, offset);
if (ret == MAP_FAILED)
die("Out of memory? mmap failed: %s", strerror(errno));