Index: /trunk/Ohana/src/libohana/Makefile
===================================================================
--- /trunk/Ohana/src/libohana/Makefile	(revision 3902)
+++ /trunk/Ohana/src/libohana/Makefile	(revision 3903)
@@ -23,4 +23,5 @@
 INC1 = \
 $(DESTINC)/Xohana.h  \
+$(DESTINC)/ohana_allocate.h \
 $(DESTINC)/ohana.h
 
@@ -32,4 +33,5 @@
 
 OBJ1 = \
+$(SRC)/ohana_allocate.$(ARCH).o  \
 $(SRC)/version.$(ARCH).o	 \
 $(SRC)/string.$(ARCH).o		 \
Index: /trunk/Ohana/src/libohana/include/ohana.h
===================================================================
--- /trunk/Ohana/src/libohana/include/ohana.h	(revision 3902)
+++ /trunk/Ohana/src/libohana/include/ohana.h	(revision 3903)
@@ -76,23 +76,7 @@
 */
 
-# ifndef ALLOCATE
-# define ALLOCATE(X,T,S)  \
-  X = (T *) malloc ((unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
-  if (X == NULL) { \
-    fprintf(stderr,"failed malloc at %d in %s\n", __LINE__, __FILE__);\
-    exit (10); } 
-# define REALLOCATE(X,T,S) \
-  X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
-  if (X == NULL) { \
-    fprintf(stderr,"failed realloc at %d in %s\n", __LINE__, __FILE__);\
-    exit (10); }
-# define CHECK_REALLOCATE(X,T,S,N,D) \
-  if ((N) >= (S)) { \
-    S += D; \
-    X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
-    if (X == NULL) { \
-      fprintf(stderr,"failed realloc increment at %d in %s\n", __LINE__, __FILE__);\
-      exit (10); } }
-# endif /* ALLOCATE */
+/* ohana_allocate.h provides ohana memory tools.  to use them
+   you must # define OHANA_MEMORY before including ohana.h */
+# include <ohana_allocate.h>
 
 # ifndef FOPEN 
Index: /trunk/Ohana/src/libohana/include/ohana_allocate.h
===================================================================
--- /trunk/Ohana/src/libohana/include/ohana_allocate.h	(revision 3903)
+++ /trunk/Ohana/src/libohana/include/ohana_allocate.h	(revision 3903)
@@ -0,0 +1,60 @@
+# ifndef OHANA_ALLOCATE
+# define OHANA_ALLOCATE
+
+/* default is to use basic system memory functions */
+# ifdef OHANA_MEMORY
+
+void *ohana_malloc (char *file, int line, size_t size);
+void *ohana_realloc (char *file, int line, void *in, size_t size);
+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);
+
+# define ohana_memregister(X) ohana_memregister_func (__FILE__, __LINE__, (X));
+# define ohana_memdump(X) ohana_memdump_func (X);
+
+# define ALLOCATE(X,T,S)  \
+  X = (T *) ohana_malloc (__FILE__, __LINE__, (unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+  if (X == NULL) { \
+    fprintf(stderr,"failed malloc at %d in %s\n", __LINE__, __FILE__);\
+    exit (10); } 
+# define REALLOCATE(X,T,S) \
+  X = (T *) ohana_realloc(__FILE__, __LINE__, X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+  if (X == NULL) { \
+    fprintf(stderr,"failed realloc at %d in %s\n", __LINE__, __FILE__);\
+    exit (10); }
+# define CHECK_REALLOCATE(X,T,S,N,D) \
+  if ((N) >= (S)) { \
+    S += D; \
+    X = (T *) ohana_realloc(__FILE__, __LINE__, X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+    if (X == NULL) { \
+      fprintf(stderr,"failed realloc increment at %d in %s\n", __LINE__, __FILE__);\
+      exit (10); } }
+# define free(X) ohana_free(__FILE__, __LINE__, X)
+
+# else 
+# define ohana_memregister(X) /* NOP */
+# define ohana_memdump(X) /* NOP */
+# endif /* OHANA_MEMORY */
+
+# ifndef ALLOCATE
+# define ALLOCATE(X,T,S)  \
+  X = (T *) malloc ((unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+  if (X == NULL) { \
+    fprintf(stderr,"failed malloc at %d in %s\n", __LINE__, __FILE__);\
+    exit (10); } 
+# define REALLOCATE(X,T,S) \
+  X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+  if (X == NULL) { \
+    fprintf(stderr,"failed realloc at %d in %s\n", __LINE__, __FILE__);\
+    exit (10); }
+# define CHECK_REALLOCATE(X,T,S,N,D) \
+  if ((N) >= (S)) { \
+    S += D; \
+    X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+    if (X == NULL) { \
+      fprintf(stderr,"failed realloc increment at %d in %s\n", __LINE__, __FILE__);\
+      exit (10); } }
+# endif /* ALLOCATE */
+
+# endif /* OHANA_ALLOCATE */
Index: /trunk/Ohana/src/libohana/src/ohana_allocate.c
===================================================================
--- /trunk/Ohana/src/libohana/src/ohana_allocate.c	(revision 3903)
+++ /trunk/Ohana/src/libohana/src/ohana_allocate.c	(revision 3903)
@@ -0,0 +1,160 @@
+# include <stdio.h>
+# include <stdlib.h>
+# include <stdarg.h>
+
+/* need an internal version that does not use ohana_memory functions */
+# define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
+# define OHANA_ALLOCATE(X,T,S)  \
+  X = (T *) malloc ((unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+  if (X == NULL) { \
+    fprintf(stderr,"failed malloc at %d in %s\n", __LINE__, __FILE__);\
+    exit (10); } 
+# define OHANA_REALLOCATE(X,T,S) \
+  X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+  if (X == NULL) { \
+    fprintf(stderr,"failed realloc at %d in %s\n", __LINE__, __FILE__);\
+    exit (10); }
+# define OHANA_CHECK_REALLOCATE(X,T,S,N,D) \
+  if ((N) >= (S)) { \
+    S += D; \
+    X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
+    if (X == NULL) { \
+      fprintf(stderr,"failed realloc increment at %d in %s\n", __LINE__, __FILE__);\
+      exit (10); } }
+# define OHANA_FREE(X) free(X)
+
+# define STATE_ALLOC   0
+# define STATE_REALLOC 1
+# define STATE_FREE    2
+
+typedef struct {
+  char *file;
+  int   line;
+  void *ptr;
+  int   state;
+} Memlist;
+
+static Memlist *memlist = NULL;
+int Nmemlist = 0;
+int NMEMLIST = 0;
+
+void ohana_meminit () {
+  Nmemlist = 0;
+  NMEMLIST = 1000;
+  OHANA_ALLOCATE (memlist, Memlist, NMEMLIST);
+}
+
+void ohana_memabort (char *format, ...) {
+  va_list argp;  
+
+  va_start (argp, format);
+  vfprintf (stderr, format, argp);
+  va_end (argp);
+  exit (5);
+}
+
+void *ohana_malloc (char *file, int line, size_t size) {
+
+  void *ptr;
+
+  if (memlist == NULL) ohana_meminit ();
+
+  ptr = malloc (size);
+  if (ptr == NULL) ohana_memabort ("failed to allocate memory (%s, %d)\n", file, line);
+
+  /* new memory, add to stack */
+  memlist[Nmemlist].ptr  = ptr;
+  memlist[Nmemlist].file = file;
+  memlist[Nmemlist].line = line;
+  memlist[Nmemlist].state = STATE_ALLOC;
+  Nmemlist ++;
+  if (Nmemlist == NMEMLIST) {
+    NMEMLIST += 1000;
+    OHANA_REALLOCATE (memlist, Memlist, NMEMLIST);
+  }
+  return (ptr);
+}
+
+/* register externally allocated memory with ohana memory manager */
+void ohana_memregister_func (char *file, int line, void *ptr) {
+
+  if (memlist == NULL) ohana_meminit ();
+
+  /* add to stack */
+  memlist[Nmemlist].ptr  = ptr;
+  memlist[Nmemlist].file = file;
+  memlist[Nmemlist].line = line;
+  memlist[Nmemlist].state = STATE_ALLOC;
+  Nmemlist ++;
+  if (Nmemlist == NMEMLIST) {
+    NMEMLIST += 1000;
+    OHANA_REALLOCATE (memlist, Memlist, NMEMLIST);
+  }
+  return;
+}
+
+void *ohana_realloc (char *file, int line, void *in, size_t size) {
+
+  int i;
+  void *ptr;
+
+  if (memlist == NULL) ohana_memabort ("REALLOCATE before ALLOCATE");
+
+  /* find old entry, update ptr, file, line */
+  for (i = 0; i < Nmemlist; i++) {
+    if (memlist[i].state == STATE_FREE) continue;
+    if (memlist[i].ptr == in) {
+      /* ask for new memory */
+      ptr = realloc (in, size);
+      if (ptr == NULL) ohana_memabort ("failed to reallocate memory (%s, %d)\n", file, line);
+      /* if new memory is same as old, just return it */
+      if (in == ptr) return (ptr);
+      /* otherwise, update with new location */
+      memlist[i].ptr = ptr;
+      memlist[i].file = file;
+      memlist[i].line = line;
+      memlist[i].state = STATE_REALLOC;
+      return (ptr);
+    }
+  }
+
+  ohana_memabort ("allocated memory not found for realloc (%s, %d)\n", file, line);
+  return (NULL);
+}
+
+void ohana_free (char *file, int line, void *in) {
+
+  int i;
+  if (memlist == NULL) ohana_memabort ("FREE before ALLOCATE");
+
+  /* find old entry, set state */
+  for (i = 0; i < Nmemlist; i++) {
+    if (memlist[i].state == STATE_FREE) continue;
+    if (memlist[i].ptr == in) {
+      memlist[i].state = STATE_FREE;
+      return;
+    }
+  }
+
+  ohana_memabort ("allocated memory not found for free (%s, %d)\n", file, line);
+  return;
+}
+
+void ohana_memdump_func (int allmemory) {
+
+  int i;
+  char state;
+
+  if (Nmemlist == 0) {
+    fprintf (stderr, "no memory allocated\n");
+    return;
+  }
+
+  for (i = 0; i < Nmemlist; i++) {
+    if ((allmemory == 0) && (memlist[i].state == STATE_FREE)) continue;
+    if (memlist[i].state == STATE_ALLOC)   state = 'A';
+    if (memlist[i].state == STATE_REALLOC) state = 'R';
+    if (memlist[i].state == STATE_FREE)    state = 'F';
+    fprintf (stderr, "%c %s %d\n", state, memlist[i].file, memlist[i].line);
+  }
+}
