# ifndef OHANA_ALLOCATE
# define OHANA_ALLOCATE

/* default is to use basic system memory functions */
# ifdef OHANA_MEMORY

void *ohana_malloc (char *file, int line, int Nelem, size_t esize);
void *ohana_realloc (char *file, int line, void *in, int Nelem, size_t esize);
void  ohana_free (char *file, int line, void *in);
void  ohana_memregister_func (char *file, int line, void *ptr);
void  ohana_memdump_func (int mode);
void  ohana_memcheck_func (int mode);

# define ohana_memregister(X) ohana_memregister_func (__FILE__, __LINE__, (X));
# define ohana_memcheck(X) ohana_memcheck_func (X);
# define ohana_memdump(X) ohana_memdump_func (X);

# define ALLOCATE(PTR,TYPE,SIZE) \
  PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, (SIZE), sizeof(TYPE))
# define REALLOCATE(PTR,TYPE,SIZE) \
  PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, PTR, (SIZE), sizeof(TYPE));
# define CHECK_REALLOCATE(PTR,TYPE,SIZE,NCURR,DELTA) \
  if ((NCURR) >= (SIZE)) { SIZE += DELTA; \
  PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, PTR, (SIZE), sizeof(TYPE)); }
# define FREE(PTR) if (PTR != NULL) { ohana_free (__FILE__, __LINE__, PTR); }
# define free(PTR) ohana_free(__FILE__, __LINE__, PTR)

# else 
# define ohana_memregister(X) /* NOP */
# define ohana_memcheck(X) /* NOP */
# define ohana_memdump(X) /* NOP */
# endif /* OHANA_MEMORY */

# ifndef ALLOCATE
# define ALLOCATE(PTR,TYPE,SIZE)  \
  PTR = (TYPE *) malloc ((unsigned)(MAX(((SIZE)*((int)sizeof(TYPE))),1))); \
  if (PTR == NULL) { \
    fprintf(stderr,"failed malloc at %d in %s\n", __LINE__, __FILE__);\
    exit (10); } 
# define REALLOCATE(PTR,TYPE,SIZE) \
  PTR = (TYPE *) realloc(PTR,(unsigned)(MAX(((SIZE)*((int)sizeof(TYPE))),1))); \
  if (PTR == NULL) { \
    fprintf(stderr,"failed realloc at %d in %s\n", __LINE__, __FILE__);\
    exit (10); }
# define CHECK_REALLOCATE(PTR,TYPE,SIZE,NCURR,DELTA) \
  if ((NCURR) >= (SIZE)) { \
    SIZE += DELTA; \
    PTR = (TYPE *) realloc(PTR,(unsigned)(MAX(((SIZE)*((int)sizeof(TYPE))),1))); \
    if (PTR == NULL) { \
      fprintf(stderr,"failed realloc increment at %d in %s\n", __LINE__, __FILE__);\
      exit (10); } }
# define FREE(PTR) if (PTR != NULL) { free (PTR); }
# endif /* ALLOCATE */

# endif /* OHANA_ALLOCATE */
