exit mem_realloc, enters p_realloc/xrealloc.
[apps/madmutt.git] / lib-lib / mem.h
1 /*
2  *  This program is free software; you can redistribute it and/or modify it
3  *  under the terms of the GNU General Public License as published by the Free
4  *  Software Foundation; either version 2 of the License, or (at your option)
5  *  any later version.
6  *
7  *  This program is distributed in the hope that it will be useful, but
8  *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9  *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
10  *  for more details.
11  *
12  *  You should have received a copy of the GNU General Public License along
13  *  with this program; if not, write to the Free Software Foundation, Inc.,
14  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Author: Pierre Habouzit <madcoder@debian.org>
17  */
18
19 #ifndef MUTT_LIB_LIB_MEM_H
20 #define MUTT_LIB_LIB_MEM_H
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 #define p_new(type, count)      ((type *)xmalloc(sizeof(type) * (count)))
27 #define p_clear(p, count)       ((void)memset((p), 0, sizeof(*(p)) * (count)))
28 #define p_dup(p, count)         xmemdup((p), sizeof(*(p)) * (count))
29 #define p_dupstr(p, len)        xmemdupstr((p), (len))
30 #define p_realloc(pp, count)    xrealloc((void*)(pp), sizeof(**(pp)) * (count))
31
32 #ifdef __GNUC__
33
34 #  define p_delete(mem_pp)                          \
35         do {                                        \
36             typeof(**(mem_pp)) **__ptr = (mem_pp);  \
37             free(*__ptr);                           \
38             *__ptr = NULL;                          \
39         } while(0)
40
41 #else
42
43 #  define p_delete(mem_p)                           \
44         do {                                        \
45             void *__ptr = (mem_p);                  \
46             free(*__ptr);                           \
47             *(void **)__ptr = NULL;                 \
48         } while (0)
49
50 #endif
51
52 static inline void *xmalloc(ssize_t size) {
53     void *mem;
54
55     if (size <= 0)
56         return NULL;
57
58     mem = calloc(size, 1);
59     if (!mem)
60         abort();
61     return mem;
62 }
63
64 static inline void xmemfree(void **ptr) {
65     p_delete(ptr);
66 }
67
68 static inline void xrealloc(void **ptr, ssize_t newsize) {
69     if (newsize <= 0) {
70         p_delete(ptr);
71     } else {
72         *ptr = realloc(*ptr, newsize);
73         if (!*ptr)
74             abort();
75     }
76 }
77
78 static inline void *xmemdup(const void *src, ssize_t size) {
79     return memcpy(xmalloc(size), src, size);
80 }
81
82 static inline void *xmemdupstr(const void *src, ssize_t len) {
83     char *res = memcpy(xmalloc(len + 1), src, len);
84     res[len] = '\0';
85     return res;
86 }
87
88 #endif /* MUTT_LIB_LIB_MEM_H */