Index: trunk/psLib/src/sysUtils/psHash.c
===================================================================
--- trunk/psLib/src/sysUtils/psHash.c	(revision 559)
+++ trunk/psLib/src/sysUtils/psHash.c	(revision 560)
@@ -13,28 +13,12 @@
 #include "psTrace.h"
 
-// A bucket that holds an item of data
-typedef struct HashBucket
-{
-    char *key;    // key for this item of data
-    void *data;    // the data itself
-    struct HashBucket *next;  // list of other possible keys
-}
-HashBucket;
-
-// An entire hash table
-struct HashTable
-{
-    int nbucket;   // number of buckets
-    HashBucket **buckets;  // the buckets themselves
-};
-
-/******************************************************************************
-    Con/Destruct buckets
- *****************************************************************************/
-static HashBucket *hashBucketAlloc(const char *key,
-                                   void *data,
-                                   HashBucket *next)
-{
-    HashBucket *bucket = psAlloc(sizeof(HashBucket));
+/******************************************************************************
+    Construct buckets
+ *****************************************************************************/
+static psHashBucket *hashBucketAlloc(const char *key,
+                                     void *data,
+                                     psHashBucket *next)
+{
+    psHashBucket *bucket = psAlloc(sizeof(psHashBucket));
 
     bucket->key = psStringCopy(key);
@@ -46,10 +30,8 @@
 
 /******************************************************************************
- 
- *****************************************************************************/
-static void hashBucketFree(
-    HashBucket *bucket,   // bucket to free
-    void (*itemFree)(void *item)) // how to free hashed data;
-// or NULL
+    Destruct buckets
+ *****************************************************************************/
+static void hashBucketFree(psHashBucket *bucket,   // bucket to free
+                           void (*itemFree)(void *item)) // how to free data;
 {
     if (bucket == NULL)
@@ -75,5 +57,5 @@
 {
     psHash *table = psAlloc(sizeof(psHash));
-    table->buckets = psAlloc(nbucket*sizeof(HashBucket *));
+    table->buckets = psAlloc(nbucket*sizeof(psHashBucket *));
     table->nbucket = nbucket;
 
@@ -104,7 +86,7 @@
     {
         if (table->buckets[i] != NULL) {
-            HashBucket *ptr = table->buckets[i];
+            psHashBucket *ptr = table->buckets[i];
             while (ptr != NULL) {
-                HashBucket *tmp = ptr->next;
+                psHashBucket *tmp = ptr->next;
                 hashBucketFree(ptr, itemFree);
                 ptr = tmp;
@@ -124,13 +106,12 @@
     N.b. this is NOT a good hash function! See Knuth for some better ones
  *****************************************************************************/
-static void *doHashWork(
-    psHash *table,   // table to insert in
-    const char *key,   // key to use
-    void *data,    // data to insert,
-    // or (if NULL) retrieve/remove
-    int remove
-        ,    // remove the item from the list?
-        void (*itemFree)(void *item)) // how to free hashed data
-    // or NULL
+static void *doHashWork(psHash     *table,   // table to insert in
+                        const char *key,     // key to use
+                        void       *data,    // data to insert,
+                        // or (if NULL) retrieve/remove
+                        int remove
+                            ,          // remove the item from the list?
+                            void (*itemFree)(void *item))
+    // how to free hashed data
 {
     long int hash = 1;
@@ -142,12 +123,11 @@
     hash &= (table->nbucket - 1);
 
-    HashBucket *ptr = table->buckets[hash];
-    /*
-     * We've found the correct hash bucket, now we need to know what to do
-     */
+    psHashBucket *ptr = table->buckets[hash];
+
+    // We've found the correct hash bucket, now we need to know what to do
     if (data == NULL) {   // retrieve/remove
         if (remove
            ) {
-            HashBucket *optr = ptr;
+            psHashBucket *optr = ptr;
             while (ptr != NULL) {
                 if (strcmp(key, ptr->key) == 0) { // found it!
@@ -196,7 +176,6 @@
             }
         }
-        /*
-         * Not found, so insert at the front of the list
-         */
+
+        // Not found, so insert at the front of the list
         table->buckets[hash] = hashBucketAlloc(key, data, table->buckets[hash]);
 
@@ -208,9 +187,8 @@
     Insert a value into a hash table
  *****************************************************************************/
-void *psHashInsert(psHash *table, // table to insert in
+void *psHashInsert(psHash *table,   // table to insert in
                    const char *key, // key to use
-                   void *data,  // data to insert
+                   void *data,      // data to insert
                    void (*itemFree)(void *item)) // how to free hashed data;
-// or NULL
 {
     return doHashWork(table, key, data, 0, itemFree);
@@ -220,5 +198,5 @@
     Lookup a value in a hash table
  *****************************************************************************/
-void *psHashLookup(psHash *table, // table to lookup key in
+void *psHashLookup(psHash *table,   // table to lookup key in
                    const char *key) // key to lookup
 {
@@ -229,5 +207,5 @@
     Remove and return a value from a hash table
  *****************************************************************************/
-void *psHashRemove(psHash *table, // table to lookup key in
+void *psHashRemove(psHash *table,   // table to lookup key in
                    const char *key) // key to lookup
 {
Index: trunk/psLib/src/sysUtils/psHash.h
===================================================================
--- trunk/psLib/src/sysUtils/psHash.h	(revision 559)
+++ trunk/psLib/src/sysUtils/psHash.h	(revision 560)
@@ -8,5 +8,22 @@
 
 /** DO WE NEED TO DEFINE HashTable? */
-typedef struct HashTable psHash; ///< Opaque type for a hash table
+//typedef struct HashTable psHash; ///< Opaque type for a hash table
+// An entire hash table
+
+// A bucket that holds an item of data
+typedef struct psHashBucket
+{
+    char *key;                          // key for this item of data
+    void *data;                         // the data itself
+    struct psHashBucket *next;          // list of other possible keys
+}
+psHashBucket;
+
+typedef struct psHash
+{
+    int nbucket;
+    psHashBucket **buckets;
+}
+psHash;
 
 /** Functions **************************************************************/
@@ -19,12 +36,12 @@
 
 /// Free hash buckets from table.
-void psHashFree(psHash *table,  ///< hash table to be freed
+void psHashFree(psHash *table,               ///< hash table to be freed
                 void (*itemFree)(void *item) ///< how to free hashed data; or NULL
                );
 
 /// Insert entry into table.
-void *psHashInsert(psHash *table, ///< table to insert in
-                   const char *key, ///< key to use
-                   void *data,  ///< data to insert
+void *psHashInsert(psHash *table,               ///< table to insert in
+                   const char *key,             ///< key to use
+                   void *data,                  ///< data to insert
                    void (*itemFree)(void *item) ///< how to free hashed data; or NULL
                   );
Index: trunk/psLib/src/sysUtils/psLogMsg.c
===================================================================
--- trunk/psLib/src/sysUtils/psLogMsg.c	(revision 559)
+++ trunk/psLib/src/sysUtils/psLogMsg.c	(revision 560)
@@ -261,4 +261,5 @@
         head_ptr += strlen(head_ptr);
     }
+
     if (head_ptr > head) {
         *head_ptr++ = '|';
@@ -269,6 +270,10 @@
     case PS_LOG_TO_STDOUT:
         puts(head);
-        vprintf(fmt, ap);
-        if (fmt[strlen(fmt) - 1] != '\n') {
+        if (log_msg) {
+            vprintf(fmt, ap);
+            if (fmt[strlen(fmt) - 1] != '\n') {
+                putc('\n', stdout);
+            }
+        } else {
             putc('\n', stdout);
         }
@@ -277,6 +282,10 @@
     case PS_LOG_TO_STDERR:
         fputs(head, stderr);
-        vfprintf(stderr, fmt, ap);
-        if (fmt[strlen(fmt) - 1] != '\n') {
+        if (log_msg) {
+            vfprintf(stderr, fmt, ap);
+            if (fmt[strlen(fmt) - 1] != '\n') {
+                putc('\n', stderr);
+            }
+        } else {
             putc('\n', stderr);
         }
Index: trunk/psLib/src/sysUtils/psTrace.c
===================================================================
--- trunk/psLib/src/sysUtils/psTrace.c	(revision 559)
+++ trunk/psLib/src/sysUtils/psTrace.c	(revision 560)
@@ -1,21 +1,20 @@
 /*****************************************************************************
-    A simple implementation of a tracing facility for Pan-STARRS
- 
-    Tracing is controlled on a per "component" basis, where a "component" is
-    a name of the form aaa.bbb.ccc where aaa is the most significant part.
-    For example, the utilities library might be called "utils", the
-    doubly-linked list "utils.dlist", and the code to destroy a list
-    "utils.dlist.del".
+    A simple implementation of a tracing facility for Pan-STARRS.  Tracing
+    is controlled on a per "component" basis, where a "component" is a name
+    of the form aaa.bbb.ccc where aaa is the most significant part.
  
     NOTES:
- In the SRD, higher trace levels correspond to a numerically lower
- trace value in the code.  This is a bit confusing.
+ In the SRD, higher trace levels correspond to a numerically lower trace
+ value in the code.  This is a bit confusing.  For example, a high-level
+ message might be something like "Begin Processing".  The module programmer
+ might give that a numerically low trace level, such as 1, so then any
+ non-zero trace level in that code component will display thatmessage.
  
  We build a tree of trace components.  Every node in the tree has a
  depth, which is it's distance from the root.  However, this is not
  not the same thing as a node's "level", which corresponds to the
- trace level of that node.  I should probably rename some variables.
- 
- This code is obduscated by the fact that component names are of the form
+ trace level of that node.
+ 
+ This code is obfuscated by the fact that component names are of the form
  ".a.b.c.d" where "." is always the root of the tree, and for tree that have
  a depth of 3 or higher (including the root ".") the "."  character is also
@@ -24,4 +23,8 @@
  while the last three dots merely act as separators between the node names
  "b", "c", and "d".
+ 
+ I added a function psTraceFree() which frees all nodes in the trace component
+ tree.  Previously, there had been no function in the API which accomplished
+ this purpose.
  *****************************************************************************/
 #include <stdlib.h>
@@ -29,39 +32,11 @@
 #include <string.h>
 #include <stdarg.h>
-/* #include "psLib.h" */
+/* #include "pslib.h" */
 #include "psMemory.h"
 #include "psTrace.h"
 #include "psString.h"
-
-#define CACHE_NAME_LEN 50
-#define NO_CACHE "\a"                     // no name is cached
-/*****************************************************************************
-    A component is a string of the form aaa.bbb.ccc, and may itself contain
-    further subcomponents.  The Component structure doesn't in fact contain
-    it's full name, but only the last part.
- *****************************************************************************/
-typedef struct Component
-{
-    const char *name;                     // last part of name of component
-    int level;                            // trace level for this component
-    int dimen;                            // dimension of subcomponents
-    int n;                                // number of subcomponents
-    struct Component **subcomp;           // next level of subcomponents
-}
-Component;
+#include "psError.h"
 
 static Component *croot = NULL;           // The root of the trace component
-// tree.
-
-// NOTE: the next tree globals exist for optimization purposes only.
-// Consider removing them.
-static int highest_level = 0;             // Highest level requested.  Defining
-// this variable allows us to reduce component-tree searches that tell
-// us if a message should be printed.
-static char cachedName[CACHE_NAME_LEN + 1] = NO_CACHE;
-// last name looked up
-static int cachedLevel;                   // level of last looked up name
-
-
 /*****************************************************************************
     componentAlloc(): allocate memory for a new node, and initialize members.
@@ -70,9 +45,8 @@
                           int level)
 {
-    //printf("Calling componentAlloc(%s, %d)\n", name, level);
     Component *comp = psAlloc(sizeof(Component));
     comp->name = psStringCopy(name);
     comp->level = level;
-    comp->dimen = comp->n = 0;
+    comp->n = 0;
     comp->subcomp = NULL;
     return comp;
@@ -108,16 +82,42 @@
 {
     if (croot == NULL) {
-        croot = componentAlloc(".", UNKNOWN_TRACE_LEVEL);
-    }
-}
-
-
-/*****************************************************************************
-    Free the trace tree information
- *****************************************************************************/
-void psTraceReset(void)
+        croot = componentAlloc(".", DEFAULT_TRACE_LEVEL);
+    }
+}
+
+
+/*****************************************************************************
+    Set all trace levels to zero.
+ *****************************************************************************/
+void p_psTraceReset(Component *currentNode)
+{
+    int i = 0;
+
+    if (NULL == currentNode) {
+        return;
+    }
+
+    currentNode->level = 0;
+    for (i=0;i<currentNode->n;i++) {
+        if (NULL == currentNode->subcomp[i]) {
+            psError(__func__,
+                    "Sub-component %d of node %s in the trace tree is NULL.\n",
+                    i, currentNode->name);
+        } else {
+            p_psTraceReset(currentNode->subcomp[i]);
+        }
+    }
+    return;
+}
+
+void psTraceReset()
+{
+    p_psTraceReset(croot);
+}
+
+
+void psTraceFree()
 {
     componentFree(croot);
-    croot = NULL;
 }
 
@@ -140,5 +140,4 @@
     int        nodeExists = 0;
 
-    // printf("Calling componentAdd(%s, %d)\n", addNodeName, level);
     // Is this the root node?  If so, simply set level and return.
     if (strcmp(".", addNodeName) == 0) {
@@ -185,37 +184,4 @@
 
 /*****************************************************************************
-    setHighestLevel(): traverse the component tree recursively.  For each
- node encountered, if it's trace level is higher than the global
- variable highest_level, then set highest_level to that nodes trace
- level.
-    Input:
- comp
-    Output:
- none
-    Returns:
- NULL
- *****************************************************************************/
-static void setHighestLevel(const Component *comp)
-{
-    int i = 0;
-
-    if (comp == NULL) {
-        printf("ERROR: setHighestLevel(NULL)\n");
-        exit(1);
-    }
-
-    // If this nodes trace level is the max so far, save it in highest_level
-    if (comp->level > highest_level) {
-        highest_level = comp->level;
-    }
-
-    // Do the same for all children nodes.
-    for (i = 0; i < comp->n; i++) {
-        setHighestLevel(comp->subcomp[i]);
-    }
-}
-
-
-/*****************************************************************************
     psSetTraceLevel(): add the component named "comp" to the component tree,
  if it is not already there, and set it's trace level to "level".
@@ -236,21 +202,8 @@
     }
 
-    //printf("Calling psSetTraceLevel(%s, %d)\n", comp, level);
-    // invalidate cache
-    strncpy(cachedName, NO_CACHE, CACHE_NAME_LEN);
-
     // Add the new component to the component tree.
     componentAdd(comp, level);
 
-    // Save this search info in our depth-one cache.
-    if (level > highest_level) {
-        highest_level = level;
-    } else {
-        highest_level = UNKNOWN_TRACE_LEVEL;
-        setHighestLevel(croot);
-    }
-
     // return 0 on success.
-    //printf("Called psSetTraceLevel(%s, %d)\n", comp, level);
     return 0;
 }
@@ -279,4 +232,8 @@
     int        i = 0;
 
+    if (NULL == currentNode) {
+        return(UNKNOWN_TRACE_LEVEL);
+    }
+
     if (strcmp(".", aname) == 0) {
         return(croot->level);
@@ -292,4 +249,10 @@
         firstComponent = strsep(&pname, ".");
         for (i = 0; i < currentNode->n; i++) {
+            if (NULL == currentNode->subcomp[i]) {
+                psError(__func__,
+                        "Sub-component %d of node %s in trace tree is NULL.\n",
+                        i, currentNode->name);
+            }
+
             if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
                 currentNode = currentNode->subcomp[i];
@@ -318,27 +281,10 @@
 int psGetTraceLevel(const char *name)
 {
-    int level = -1;
-
-    //printf("Calling psGetTraceLevel(%s)\n", name);
-    // If the root component tree does not exist, then initialize it.
     if (croot == NULL) {
-        initTrace();
-    }
-
-    // Before we traverse the component tree, check if we just searched for
-    // this name, and if so, return that level.
-    if (strcmp(name, cachedName) == 0) {
-        return cachedLevel;
+        return(UNKNOWN_TRACE_LEVEL);
     }
 
     // Search the component root tree, determine the trace level.
-    level = doGetTraceLevel(name);
-
-    // Save this search info in our depth-one cache.
-    strncpy(cachedName, name, CACHE_NAME_LEN);
-    cachedLevel = level;
-
-    //printf("Called psGetTraceLevel(%s) (level was %d)\n", name, level);
-    return level;
+    return(doGetTraceLevel(name));
 }
 
@@ -392,7 +338,6 @@
 void psPrintTraceLevels(void)
 {
-    // If the root component tree does not exist, then initialize it.
     if (croot == NULL) {
-        initTrace();
+        return;
     }
 
@@ -423,11 +368,12 @@
     int i = 0;
 
-    // We first check if the level of this message is less than the highest
-    // level in the tree.  If so, we don't go any further.  If not, we need
-    // to determine the trace level of comp, and then display the message if
-    // the comp's trace level is high enough.
-
-    if ((level <= highest_level) &&
-            (level <= psGetTraceLevel(comp))) {
+    if (NULL == comp) {
+        psError(__func__,
+                "p_psTrace() called on a NULL trace level tree\n");
+    }
+
+    // Only display this message if it's trace level is less than the level
+    // of it's associatedcomponent.
+    if (level <= psGetTraceLevel(comp)) {
         va_start(ap, level);
 
@@ -444,4 +390,5 @@
         va_end(ap);
     }
+
     // NOTE: should we free *fmt as well?  Read the man page.
 }
Index: trunk/psLib/src/sysUtils/psTrace.h
===================================================================
--- trunk/psLib/src/sysUtils/psTrace.h	(revision 559)
+++ trunk/psLib/src/sysUtils/psTrace.h	(revision 560)
@@ -1,5 +1,6 @@
 #if !defined(PS_TRACE_H)
 #define PS_TRACE_H 1
-#define UNKNOWN_TRACE_LEVEL -9999               // we don't know this name's level
+#define UNKNOWN_TRACE_LEVEL -9999         // we don't know this name's level
+#define DEFAULT_TRACE_LEVEL 0
 
 /** \file psTrace.h
@@ -7,4 +8,18 @@
  *  \ingroup SystemGroup
  */
+
+/*****************************************************************************
+    A component is a string of the form aaa.bbb.ccc, and may itself contain
+    further subcomponents.  The Component structure doesn't in fact contain
+    it's full name, but only the last part.
+ *****************************************************************************/
+typedef struct Component
+{
+    const char *name;                     // last part of name of component
+    int level;                            // trace level for this component
+    int n;                                // number of subcomponents
+    struct Component **subcomp;           // next level of subcomponents
+}
+Component;
 
 /** Functions **************************************************************/
@@ -28,6 +43,10 @@
 ;
 
-/// turn off all tracing, and free trace's allocated memory
-void psTraceReset(void)
+/// Set all trace levels to zero (do not free nodes in the component tree).
+void psTraceReset()
+;
+
+/// Free all nodes in the component tree.
+void psTraceFree()
 ;
 
