1 #ifndef UTIL_XMALLOC_H
2 #define UTIL_XMALLOC_H
3 
4 #include <limits.h>
5 #include <stdarg.h>
6 #include <stddef.h>
7 #include <string.h>
8 #include "macros.h"
9 
10 #define xnew(type, n) xmalloc(size_multiply(sizeof(type), (n)))
11 #define xnew0(type, n) xcalloc(size_multiply(sizeof(type), (n)))
12 
13 #define xrenew(mem, n) do { \
14     mem = xrealloc(mem, size_multiply(sizeof(*mem), (n))); \
15 } while (0)
16 
17 #define xmemdup_literal(l) xmemdup(l, sizeof("" l ""))
18 
19 void *xmalloc(size_t size) XMALLOC ALLOC_SIZE(1);
20 void *xcalloc(size_t size) XMALLOC ALLOC_SIZE(1);
21 void *xrealloc(void *ptr, size_t size) RETURNS_NONNULL ALLOC_SIZE(2);
22 char *xstrdup(const char *str) XSTRDUP;
23 char *xstrndup(const char *str, size_t n) XSTRDUP;
24 char *xstrdup_toupper(const char *str) XSTRDUP;
25 char *xstrcut(const char *str, size_t size) XSTRDUP;
26 char *xvasprintf(const char *format, va_list ap) VPRINTF(1) XMALLOC;
27 char *xasprintf(const char *format, ...) PRINTF(1) XMALLOC;
28 size_t size_multiply_(size_t a, size_t b);
29 size_t size_add(size_t a, size_t b);
30 
size_multiply(size_t a,size_t b)31 static inline size_t size_multiply(size_t a, size_t b)
32 {
33     // If either argument is 1, the multiplication can't overflow
34     // and is thus safe to be inlined without checks.
35     if (a == 1 || b == 1) {
36         return a * b;
37     }
38     // Otherwise, emit a call to the checked implementation (which is
39     // extern, because it may call fatal_error()).
40     return size_multiply_(a, b);
41 }
42 
43 NONNULL_ARGS_AND_RETURN ALLOC_SIZE(2)
xmemdup(const void * ptr,size_t size)44 static inline void *xmemdup(const void *ptr, size_t size)
45 {
46     void *buf = xmalloc(size);
47     memcpy(buf, ptr, size);
48     return buf;
49 }
50 
51 // Round x up to a multiple of r (which *must* be a power of 2)
ROUND_UP(size_t x,size_t r)52 static inline size_t ROUND_UP(size_t x, size_t r)
53 DIAGNOSE_IF(!IS_POWER_OF_2(r))
54 {
55     r--;
56     return (x + r) & ~r;
57 }
58 
round_size_to_next_power_of_2(size_t x)59 static inline size_t round_size_to_next_power_of_2(size_t x)
60 {
61     x--;
62     for (size_t i = 1, n = sizeof(size_t) * CHAR_BIT; i < n; i <<= 1) {
63         x |= x >> i;
64     }
65     return x + 1;
66 }
67 
68 XSTRDUP
xstrslice(const char * str,size_t pos,size_t end)69 static inline char *xstrslice(const char *str, size_t pos, size_t end)
70 {
71     return xstrcut(str + pos, end - pos);
72 }
73 
74 #endif
75