// use '#define DEBUG' to switch to "debug" versions of macros

#ifdef DEBUG

#define FREE(x)  { if (x) { \
   { free((void *)(x)); \
        (x) = NULL; } \ 
     if (_fheapchk() != _HEAPOK) \
         error ("Heap corrupted"); }
                     
#define MALLOC(p,n) { \
    if (!(p=(n *) malloc((size_t)sizeof(n)))) \
        error("malloc: out of memory"); \
    if (_fheapchk() != _HEAPOK) \
        error ("Heap corrupted"); }
                            
#define CALLOC(p,n,s) { \
    if (!(n)) \
        (p)=NULL; \
    else if (!((p)=(s*)calloc((size_t)(n),sizeof(s)))) \
        error("calloc: out of memory"); \
    if (_fheapchk() != _HEAPOK) \
        error ("Heap corrupted"); }

#define REALLOC(p,n,s)  { \
    if (!(p)) \
        CALLOC (p,n,s) \
    else if (!(n)) \
        (p)=0; \
    else { if (!(p=(s*)realloc((void *)p, (size_t) (sizeof(s)*(n))))) \
            error ("realloc: out of memory"); } \
    if (_fheapchk() != _HEAPOK) \
        error ("Heap corrupted"); }

#else
#define FREE(x)  { if (x) { free((void *)(x)); (x) = NULL; } }

#define MALLOC (p,n) { while (!(p=(n *)malloc((size_t)sizeof(n))) && \
                                error("Out of memory\n"));}

#define CALLOC (p,n,s)  { \
    if (!(n)) \
        (p)=0; \
    else while (!(p=(s*)calloc((size_t)(n),sizeof(s))) && \
            error("Out of memory\n")); }

#define REALLOC(p,n,s)  { \
    if (!(p)) \
        CALLOC (p,n,s) \
    else    if (!(n)) \
        (p)=0; \
    else while (!(p=(s*)realloc((void *)p, (size_t)(sizeof(s)*(n)))) \
            && error ("Out of memeory\n")); }
#endif
