Index: trunk/psLib/src/sys/psConfigure.c
===================================================================
--- trunk/psLib/src/sys/psConfigure.c	(revision 5524)
+++ trunk/psLib/src/sys/psConfigure.c	(revision 7646)
@@ -13,9 +13,14 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-11-16 20:52:23 $
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-06-23 01:59:15 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
  */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "psMemory.h"
+#include "psTrace.h"
 #include "psString.h"
 #include "psTime.h"
@@ -26,4 +31,7 @@
 #include "config.h"
 
+static char *memCheckName = NULL;       // Filename to which to write results of mem check
+static FILE *memCheckFile = NULL;       // File to which to write results of mem check
+
 char* psLibVersion(void)
 {
@@ -31,21 +39,77 @@
     snprintf(version,80,"%s-v%s",PACKAGE_NAME,PACKAGE_VERSION);
 
-    return(psStringCopy(version));
+    return psStringCopy(version);
 }
+
+// Print details of a memory problem to the appropriate file
+static void memoryProblem(const psMemBlock *ptr, // the pointer to the problematic memory block.
+                          const char *file, // the file in which the problem originated
+                          int lineno    // the line number in which the problem originated
+                         )
+{
+    fprintf(memCheckFile,
+            "Memory corruption detected in memBlock %lu\n"
+            "\tFile %s, line %d, size %zd\n"
+            "\tPosts: %p %p %p\n",
+            ptr->id, file, lineno, ptr->userMemorySize, ptr->startblock, ptr->endblock,
+            (ptr + 1 + ptr->userMemorySize));
+}
+
+// Check the memory; intended for use on exit, but might be used elsewhere
+void p_psMemoryCheck(void)
+{
+    if (!memCheckName || strlen(memCheckName) == 0) {
+        return;
+    }
+
+    memCheckFile = fopen(memCheckName, "w"); // File to write leaks to
+    if (!memCheckFile) {
+        psError(PS_ERR_IO, true, "Unable to open leaks file, %s\n", memCheckName);
+        return;
+    }
+
+    int nLeaks = psMemCheckLeaks(0, NULL, memCheckFile, false); // Number of leaks
+    if (nLeaks > 0) {
+        psLogMsg(__func__, PS_LOG_WARN, "%d memory leaks found; list written to %s.\n", nLeaks, memCheckName);
+    } else {
+        psLogMsg(__func__, PS_LOG_INFO, "No memory leaks found.\n");
+    }
+
+    int nCorrupted;                     // Number of corrupted memory blocks
+    (void)psMemProblemCallbackSet((psMemProblemCallback)memoryProblem); // Set callback for corruption
+    nCorrupted = psMemCheckCorruption(false);
+    if (nCorrupted > 0) {
+        psError(PS_ERR_UNKNOWN, true, "%d memory blocks corrupted; list written to %s.\n", nCorrupted);
+    } else {
+        psLogMsg(__func__, PS_LOG_INFO, "No memory corruption found.\n");
+    }
+
+    fclose(memCheckFile);
+
+    return;
+}
+
 
 void psLibInit(const char* timeConfig)
 {
     // XXX: Still needs error codes to be set
-    // XXX: Still needs random number generator initialization
 
-    if(!p_psTimeInit(timeConfig)) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED, "psTime");
-        return;
+    if (timeConfig && strlen(timeConfig) > 0) {
+        if (!p_psTimeInit(timeConfig)) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED, "psTime");
+            return;
+        }
     }
-    if(!p_psEOCInit()) {
+    if (!p_psEOCInit()) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED, "psEOC");
         return;
+    }
+
+    // Does the user want memory checking at exit?
+    memCheckName = getenv("PS_ALLOC_CHECK"); // The value of PS_ALLOC_CHECK
+    if (memCheckName && strlen(memCheckName) > 0) {
+        atexit(&p_psMemoryCheck);
     }
 }
@@ -55,13 +119,26 @@
     // Users of persistent memory should free them in this function
 
-    if(!p_psTimeFinalize()) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+    // Stop timers
+    psTimerStop();
+
+    // Free the time tables
+    if (!p_psTimeFinalize()) {
+        psError(PS_ERR_UNKNOWN, false,
                 PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED, "psTime");
         return;
     }
-    if(!p_psEOCFinalize()) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+
+    // Free the precession tables
+    if (!p_psEOCFinalize()) {
+        psError(PS_ERR_UNKNOWN, false,
                 PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED, "psEOC");
         return;
     }
+
+    // Free the trace system
+    psTraceReset();
+
+    // Free the error system
+    psErrorClear();
+
 }
