Index: /branches/eam_branches/ipp-20110505/Ohana/src/libohana/Makefile
===================================================================
--- /branches/eam_branches/ipp-20110505/Ohana/src/libohana/Makefile	(revision 31590)
+++ /branches/eam_branches/ipp-20110505/Ohana/src/libohana/Makefile	(revision 31591)
@@ -50,9 +50,13 @@
 
 TEST = \
-$(TESTDIR)/string.$(ARCH)
+$(TESTDIR)/memtest.$(ARCH)
+# $(TESTDIR)/string.$(ARCH)
 
 testcode: install $(TEST)
 test:
 	make testcode
+	for i in $(TEST); do $$i; done
+
+quicktest: 
 	for i in $(TEST); do $$i; done
 
Index: /branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana.h
===================================================================
--- /branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana.h	(revision 31590)
+++ /branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana.h	(revision 31591)
@@ -19,4 +19,5 @@
 # include <readline/readline.h>
 
+// comment this out to avoid the internal Ohana memory management code
 # define OHANA_MEMORY
 
Index: /branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana_allocate.h
===================================================================
--- /branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana_allocate.h	(revision 31590)
+++ /branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana_allocate.h	(revision 31591)
@@ -1,37 +1,56 @@
 # ifndef OHANA_ALLOCATE
 # define OHANA_ALLOCATE
+
+typedef struct {
+  int    exists; // has the memory management system been created?
+  size_t Ntotal; // number of blocks currently allocated
+  size_t Nbytes; // number of bytes currently allocated
+  size_t Ngood;  // number of good blocks
+  size_t Nbad;   // number of bad blocks
+} OhanaMemstats;
+
+OhanaMemstats ohana_memstats (int mode);
 
 /* default is to use basic system memory functions */
 # ifdef OHANA_MEMORY
 
-void *ohana_malloc (char *file, int line, char *func, int Nelem, size_t esize);
-void *ohana_realloc (char *file, int line, char *func, void *in, int Nelem, size_t esize);
-void  ohana_free (char *file, int line, char *func, void *in);
+void *ohana_malloc (const char *file, int line, const char *func, int Nelem, size_t esize);
+void *ohana_realloc (const char *file, int line, const char *func, void *in, int Nelem, size_t esize);
+void  ohana_free (const char *file, int line, const char *func, void *in);
 void  ohana_memdump_func (int mode);
 void  ohana_memcheck_func (int mode);
+void  real_free (void *in);
 
 # 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__, __func__, (SIZE), sizeof(TYPE)) }
-# define ALLOCATE_ZERO(PTR,TYPE,SIZE)					\
-  { PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, __func__, (SIZE), sizeof(TYPE)); memset (PTR, 0, (SIZE)*sizeof(TYPE)); }
-# define REALLOCATE(PTR,TYPE,SIZE) \
-  { PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, __func__, PTR, (SIZE), sizeof(TYPE)); }
-# define CHECK_REALLOCATE(PTR,TYPE,SIZE,NCURR,DELTA) {			\
-  if ((NCURR) >= (SIZE)) { SIZE += DELTA;				\
-    PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, __func__, PTR, (SIZE), sizeof(TYPE)); } }
+# define ALLOCATE(PTR,TYPE,SIZE) { \
+    PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, __func__, (SIZE), sizeof(TYPE)); \
+  }
+
+# define ALLOCATE_ZERO(PTR,TYPE,SIZE) { \
+    PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, __func__, (SIZE), sizeof(TYPE)); \
+    memset (PTR, 0, (SIZE)*sizeof(TYPE)); \
+  }
+
+# define REALLOCATE(PTR,TYPE,SIZE) { \
+    PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, __func__, PTR, (SIZE), sizeof(TYPE)); \
+  }
+
+# define CHECK_REALLOCATE(PTR,TYPE,SIZE,NCURR,DELTA) { \
+  if ((NCURR) >= (SIZE)) { \
+    SIZE += DELTA; \
+    PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, __func__, PTR, (SIZE), sizeof(TYPE)); \
+  } }
+
 # define FREE(PTR) { if (PTR != NULL) { ohana_free (__FILE__, __LINE__, __func__, PTR); } }
-# define free(PTR) { ohana_free(__FILE__, __LINE__, PTR); }
-# define real_free(PTR) { if (PTR) { free(PTR); }}
+# define free(PTR) { ohana_free(__FILE__, __LINE__, __func__, PTR); }
 
-# else  /* OHANA_MEMORY */
+# else  /* below: not OHANA_MEMORY */
 
 # define ohana_memcheck(X) /* NOP */
 # define ohana_memdump(X) /* NOP */
-# define real_free(PTR) { if (PTR) { free(PTR); }}
+void  real_free (void *in);
 
-# ifndef ALLOCATE
 # define ALLOCATE(PTR,TYPE,SIZE) {					\
   PTR = (TYPE *) malloc ((size_t)(MAX(((SIZE)*((int)sizeof(TYPE))),1))); \
@@ -62,5 +81,4 @@
 
 # define FREE(PTR) { if (PTR != NULL) { free (PTR); } }
-# endif /* ALLOCATE */
 # endif /* OHANA_MEMORY */
 
Index: /branches/eam_branches/ipp-20110505/Ohana/src/libohana/src/ohana_allocate.c
===================================================================
--- /branches/eam_branches/ipp-20110505/Ohana/src/libohana/src/ohana_allocate.c	(revision 31590)
+++ /branches/eam_branches/ipp-20110505/Ohana/src/libohana/src/ohana_allocate.c	(revision 31591)
@@ -4,4 +4,5 @@
 # include <stdint.h>
 # include <pthread.h>
+# include "ohana_allocate.h"
 
 /* need an internal version that does not use ohana_memory functions */
@@ -17,6 +18,6 @@
   struct Memblock *nextBlock; // next allocated memory
   size_t size;		      // size of memory
-  char *file;		      // file (re)allocated 
-  char *func;		      // func (re)allocated 
+  const char *file;	      // file (re)allocated 
+  const char *func;	      // func (re)allocated 
   int line;		      // line (re)allocated
   uint32_t endblock;	      // endpost marker
@@ -40,5 +41,5 @@
 }
 
-void *ohana_malloc (char *file, int line, char *func, size_t Nelem, size_t esize) {
+void *ohana_malloc (const char *file, int line, const char *func, size_t Nelem, size_t esize) {
 
   void *ptr;		      // actual user memory allocated
@@ -94,5 +95,5 @@
 }
 
-void *ohana_realloc (char *file, int line, char *func, void *in, size_t Nelem, size_t esize) {
+void *ohana_realloc (const char *file, int line, const char *func, void *in, size_t Nelem, size_t esize) {
 
   void *ptr;		      // actual user memory allocated
@@ -158,6 +159,13 @@
 }
 
+void real_free (void *in) {
+
+  if (!in) return;
+  free (in);
+  return;
+}
+
 // this is very slow.  should we speed this up by indexing on the ptr?
-void ohana_free (char *file, int line, char *func, void *in) {
+void ohana_free (const char *file, int line, const char *func, void *in) {
 
   Memblock *ref;
@@ -278,2 +286,43 @@
   return;
 }
+
+OhanaMemstats ohana_memstats (int allmemory) {
+
+  OhanaMemstats memstats;
+
+  memstats.exists = 0;
+  memstats.Ntotal = 0;
+  memstats.Nbytes = 0;
+  memstats.Ngood = 0;
+  memstats.Nbad = 0;
+  
+  Memblock *thisBlock = lastBlock;
+
+  while (thisBlock) {
+
+    memstats.exists = TRUE;
+
+    int good = TRUE;
+    
+    if (thisBlock->startblock != OHANA_MEMMAGIC) good = FALSE;
+    if (thisBlock->endblock != OHANA_MEMMAGIC) good = FALSE;
+
+    // pointer to the start of the user memory
+    char *ptr = (char *)(thisBlock + 1) + thisBlock->size;
+    uint32_t endpost = *(uint32_t *)ptr;
+    if (endpost != OHANA_MEMMAGIC) good = FALSE;
+
+    memstats.Ntotal ++;
+    memstats.Nbytes += thisBlock->size;
+
+    if (good) {
+      memstats.Ngood ++;
+    } else {
+      memstats.Nbad ++;
+    }
+
+    thisBlock = thisBlock->prevBlock;
+  }
+
+  return memstats;
+}
Index: /branches/eam_branches/ipp-20110505/Ohana/src/libohana/test/memtest.c
===================================================================
--- /branches/eam_branches/ipp-20110505/Ohana/src/libohana/test/memtest.c	(revision 31591)
+++ /branches/eam_branches/ipp-20110505/Ohana/src/libohana/test/memtest.c	(revision 31591)
@@ -0,0 +1,188 @@
+# include "ohana.h"
+# include "tap_ohana.h"
+
+int main (void) {
+
+  plan_tests (64);
+
+  diag ("libohana memtest.c tests");
+
+  {
+    // int status;
+    char *data;
+    OhanaMemstats memstats;
+
+    // does ALLOCATE work?
+    ALLOCATE (data, char, 100);
+    memstats = ohana_memstats(0);
+
+    skip_start (!memstats.exists, 16, "skipping all tests : memory management not enabled");
+
+    ok (memstats.Ntotal ==   1, "allocated a block");
+    ok (memstats.Nbytes == 100, "allocated correct amount");
+    ok (memstats.Ngood  ==   1, "block is good");
+    ok (memstats.Nbad   ==   0, "no blocks are bad");
+    
+    // does REALLOCATE work?
+    REALLOCATE (data, char, 1000);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    1, "allocated a block");
+    ok (memstats.Nbytes == 1000, "allocated correct amount");
+    ok (memstats.Ngood  ==    1, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    // does FREE work?
+    free (data);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==   0, "freed block");
+    ok (memstats.Nbytes ==   0, "kept correct amount");
+    ok (memstats.Ngood  ==   0, "block is good");
+    ok (memstats.Nbad   ==   0, "no blocks are bad");
+    
+    skip_end();
+  }
+
+  {
+    // int status;
+    char *data1, *data2, *data3, *data4;
+    OhanaMemstats memstats;
+
+    // does ALLOCATE work?
+    ALLOCATE (data1, char, 100);
+    ALLOCATE (data2, char, 100);
+    ALLOCATE (data3, char, 100);
+    ALLOCATE (data4, char, 100);
+    memstats = ohana_memstats(0);
+
+    skip_start (!memstats.exists, 16, "skipping all tests : memory management not enabled");
+
+    ok (memstats.Ntotal ==   4, "allocated a block");
+    ok (memstats.Nbytes == 400, "allocated correct amount");
+    ok (memstats.Ngood  ==   4, "block is good");
+    ok (memstats.Nbad   ==   0, "no blocks are bad");
+    
+    // does REALLOCATE work?
+    REALLOCATE (data1, char, 1000);
+    REALLOCATE (data2, char, 1000);
+    REALLOCATE (data3, char, 1000);
+    REALLOCATE (data4, char, 1000);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    4, "allocated a block");
+    ok (memstats.Nbytes == 4000, "allocated correct amount");
+    ok (memstats.Ngood  ==    4, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    // does FREE work?
+    free (data1);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    3, "freed block");
+    ok (memstats.Nbytes == 3000, "kept correct amount");
+    ok (memstats.Ngood  ==    3, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    free (data2);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    2, "freed block");
+    ok (memstats.Nbytes == 2000, "kept correct amount");
+    ok (memstats.Ngood  ==    2, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    free (data3);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    1, "freed block");
+    ok (memstats.Nbytes == 1000, "kept correct amount");
+    ok (memstats.Ngood  ==    1, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    free (data4);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    0, "freed block");
+    ok (memstats.Nbytes ==    0, "kept correct amount");
+    ok (memstats.Ngood  ==    0, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    skip_end();
+  }
+
+  {
+    // int status;
+    char *data1, *data2, *data3, *data4;
+    OhanaMemstats memstats;
+
+    // does ALLOCATE work?
+    ALLOCATE (data1, char, 100);
+    ALLOCATE (data2, char, 100);
+    ALLOCATE (data3, char, 100);
+    ALLOCATE (data4, char, 100);
+    memstats = ohana_memstats(0);
+
+    skip_start (!memstats.exists, 16, "skipping all tests : memory management not enabled");
+
+    ok (memstats.Ntotal ==   4, "allocated a block");
+    ok (memstats.Nbytes == 400, "allocated correct amount");
+    ok (memstats.Ngood  ==   4, "block is good");
+    ok (memstats.Nbad   ==   0, "no blocks are bad");
+    
+    // damage some data
+    data1[101] = 111;
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    4, "allocated a block");
+    ok (memstats.Nbytes ==  400, "allocated correct amount");
+    ok (memstats.Ngood  ==    3, "3 blocks are good");
+    ok (memstats.Nbad   ==    1, "one block is bad");
+    
+    // damage some other data
+    data2[-2] = 111;
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    4, "allocated a block");
+    ok (memstats.Nbytes ==  400, "allocated correct amount");
+    ok (memstats.Ngood  ==    2, "3 blocks are good");
+    ok (memstats.Nbad   ==    2, "one block is bad");
+    
+    // does FREE work?
+    free (data1);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    3, "freed block");
+    ok (memstats.Nbytes ==  300, "kept correct amount");
+    ok (memstats.Ngood  ==    2, "block is good");
+    ok (memstats.Nbad   ==    1, "no blocks are bad");
+    
+    free (data2);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    2, "freed block");
+    ok (memstats.Nbytes ==  200, "kept correct amount");
+    ok (memstats.Ngood  ==    2, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    free (data3);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    1, "freed block");
+    ok (memstats.Nbytes ==  100, "kept correct amount");
+    ok (memstats.Ngood  ==    1, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    free (data4);
+    memstats = ohana_memstats(0);
+
+    ok (memstats.Ntotal ==    0, "freed block");
+    ok (memstats.Nbytes ==    0, "kept correct amount");
+    ok (memstats.Ngood  ==    0, "block is good");
+    ok (memstats.Nbad   ==    0, "no blocks are bad");
+    
+    skip_end();
+  }
+
+  return exit_status();
+}
Index: /branches/eam_branches/ipp-20110505/Ohana/src/opihi/lib.shell/CommandOps.c
===================================================================
--- /branches/eam_branches/ipp-20110505/Ohana/src/opihi/lib.shell/CommandOps.c	(revision 31590)
+++ /branches/eam_branches/ipp-20110505/Ohana/src/opihi/lib.shell/CommandOps.c	(revision 31591)
@@ -106,4 +106,19 @@
 }  
 
+/* we need a strcreate function that does NOT use the ohana memory management
+ * system to interact with some external libraries (which themselves free the memory)
+ */
+char *strcreate_sans_ohana (char *string) {
+
+  char *line;
+
+  if (string == (char *) NULL) return ((char *) NULL);
+  
+  line = malloc (MAX (1, strlen(string)) + 1);
+  line = strcpy (line, string);
+
+  return (line);
+}
+
 /* generate a command completion list for readline */
 /**** these probably do not interact well with OHANA memory!!! ****/
@@ -122,7 +137,9 @@
   for (i++; i < Ncommands; i++) {
     if (!len) 
-      return (strcreate(commands[i].name));
+
+
+      return (strcreate_sans_ohana(commands[i].name));
     if (!strncmp (commands[i].name, text, len)) {
-      return (strcreate(commands[i].name));
+      return (strcreate_sans_ohana(commands[i].name));
     }
   }
