summaryrefslogtreecommitdiffstats
path: root/Utilities/cmxmlrpc/mallocvar.h
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmxmlrpc/mallocvar.h')
-rw-r--r--Utilities/cmxmlrpc/mallocvar.h80
1 files changed, 80 insertions, 0 deletions
diff --git a/Utilities/cmxmlrpc/mallocvar.h b/Utilities/cmxmlrpc/mallocvar.h
new file mode 100644
index 0000000..f2022e9
--- /dev/null
+++ b/Utilities/cmxmlrpc/mallocvar.h
@@ -0,0 +1,80 @@
+/* These are some dynamic memory allocation facilities. They are essentially
+ an extension to C, as they do allocations with a cognizance of C
+ variables. You can use them to make C read more like a high level
+ language.
+*/
+
+#ifndef MALLOCVAR_INCLUDED
+#define MALLOCVAR_INCLUDED
+
+#include <limits.h>
+#include <stdlib.h>
+
+static __inline__ void
+mallocProduct(void ** const resultP,
+ unsigned int const factor1,
+ unsigned int const factor2) {
+/*----------------------------------------------------------------------------
+ malloc a space whose size in bytes is the product of 'factor1' and
+ 'factor2'. But if that size cannot be represented as an unsigned int,
+ return NULL without allocating anything. Also return NULL if the malloc
+ fails.
+
+ Note that malloc() actually takes a size_t size argument, so the
+ proper test would be whether the size can be represented by size_t,
+ not unsigned int. But there is no reliable indication available to
+ us, like UINT_MAX, of what the limitations of size_t are. We
+ assume size_t is at least as expressive as unsigned int and that
+ nobody really needs to allocate more than 4GB of memory.
+-----------------------------------------------------------------------------*/
+ if (UINT_MAX / factor2 < factor1)
+ *resultP = NULL; \
+ else
+ *resultP = malloc(factor1 * factor2);
+}
+
+
+
+static __inline__ void
+reallocProduct(void ** const blockP,
+ unsigned int const factor1,
+ unsigned int const factor2) {
+
+ if (UINT_MAX / factor2 < factor1)
+ *blockP = NULL; \
+ else
+ *blockP = realloc(*blockP, factor1 * factor2);
+}
+
+
+
+#define MALLOCARRAY(arrayName, nElements) \
+ mallocProduct((void **)&arrayName, nElements, sizeof(arrayName[0]))
+
+#define REALLOCARRAY(arrayName, nElements) \
+ reallocProduct((void **)&arrayName, nElements, sizeof(arrayName[0]))
+
+
+#define MALLOCARRAY_NOFAIL(arrayName, nElements) \
+do { \
+ MALLOCARRAY(arrayName, nElements); \
+ if ((arrayName) == NULL) \
+ abort(); \
+} while(0)
+
+#define REALLOCARRAY_NOFAIL(arrayName, nElements) \
+do { \
+ REALLOCARRAY(arrayName, nElements); \
+ if ((arrayName) == NULL) \
+ abort(); \
+} while(0)
+
+
+#define MALLOCVAR(varName) \
+ varName = malloc(sizeof(*varName))
+
+#define MALLOCVAR_NOFAIL(varName) \
+ do {if ((varName = malloc(sizeof(*varName))) == NULL) abort();} while(0)
+
+#endif
+