More string and buffer functions.
[apps/madmutt.git] / lib-lib / mem.h
index db5ef49..d981a80 100644 (file)
@@ -20,9 +20,8 @@
 #ifndef MUTT_LIB_LIB_MEM_H
 #define MUTT_LIB_LIB_MEM_H
 
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
+#define ssizeof(foo)            (ssize_t)sizeof(foo)
+#define countof(foo)            (ssizeof(foo) / ssizeof(foo[0]))
 
 #define p_new(type, count)      ((type *)xmalloc(sizeof(type) * (count)))
 #define p_clear(p, count)       ((void)memset((p), 0, sizeof(*(p)) * (count)))
 #define p_dupstr(p, len)        xmemdupstr((p), (len))
 #define p_realloc(pp, count)    xrealloc((void*)(pp), sizeof(**(pp)) * (count))
 
+#define p_alloc_nr(x) (((x) + 16) * 3 / 2)
+
+#define p_allocgrow(pp, goalnb, allocnb)                  \
+  do {                                                    \
+      if ((goalnb) > *(allocnb)) {                        \
+          if (p_alloc_nr(*(allocnb)) < (goalnb)) {        \
+              *(allocnb) = (goalnb);                      \
+          } else {                                        \
+              *(allocnb) = p_alloc_nr(*(allocnb));        \
+          }                                               \
+          p_realloc(pp, *(allocnb));                      \
+      }                                                   \
+  } while (0)
+
 #ifdef __GNUC__
 
 #  define p_delete(mem_pp)                          \
@@ -87,6 +100,27 @@ static inline void *xmemdupstr(const void *src, ssize_t len) {
 }
 
 
+#define DO_REFCNT(type, prefix)                             \
+    static inline type *prefix##_new(void) {                \
+        type *res = prefix##_init(p_new(type, 1));          \
+        res->refcnt = 1;                                    \
+        return res;                                         \
+    }                                                       \
+    static inline type *prefix##_dup(type *t) {             \
+        t->refcnt++;                                        \
+        return t;                                           \
+    }                                                       \
+    static inline void prefix##_delete(type **tp) {         \
+        if (*tp) {                                          \
+            if (--(*tp)->refcnt > 0) {                      \
+                *tp = NULL;                                 \
+            } else {                                        \
+                prefix##_wipe(*tp);                         \
+                p_delete(tp);                               \
+            }                                               \
+        }                                                   \
+    }
+
 #define DO_INIT(type, prefix) \
     static inline type * prefix##_init(type *var) {         \
         p_clear(var, 1);                                    \