Index: /trunk/psLib/src/sys/psTrace.c
===================================================================
--- /trunk/psLib/src/sys/psTrace.c	(revision 4971)
+++ /trunk/psLib/src/sys/psTrace.c	(revision 4972)
@@ -9,6 +9,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.57 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-09-07 00:15:48 $
+ *  @version $Revision: 1.58 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-09-08 00:27:50 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -55,4 +55,9 @@
 static p_psComponent* cRoot = NULL; // The root of the trace component
 static FILE *traceFP = NULL;        // File destination for messages.
+static psBool traceTime = false;     // Flag to include time info
+static psBool traceHost = false;     // Flag to include host info
+static psBool traceLevel = false;    // Flag to include level info
+static psBool traceName = false;     // Flag to include name info
+static psBool traceMsg = true;      // Flag to include message info
 //static int traceFD = 0;
 
@@ -476,4 +481,149 @@
 }
 
+void psTraceV(const char *comp,
+              int level,
+              const char *format,
+              va_list ap)
+{
+    char *fmt = NULL;
+    //    va_list ap;
+    static psS32 first = 1;       // Flag for calling gethostname()
+    static char hostname[256 + 1];
+    char clevel = 0;            // letter-name for level
+    psS32 i = 0;
+    char head[256 + 2]; // the added two are for the ending | and \0
+    char *head_ptr = head;      // where we've got to in head
+    psS32 maxLength = 256;
+    time_t clock = time(NULL);  // The current time.
+    struct tm *utc = gmtime(&clock);    // The current gm time.
+
+    if (traceFP == NULL) {
+        traceFP = stdout;
+    }
+
+    if (NULL == comp) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psTrace_NULL_TRACETREE,
+                __func__);
+        return;
+    }
+
+    if (first) {
+        first = 0;
+        gethostname(hostname, 256);
+    }
+    switch (level) {
+    case PS_LOG_ABORT:
+        clevel = 'A';
+        break;
+
+    case PS_LOG_ERROR:
+        clevel = 'E';
+        break;
+
+    case PS_LOG_WARN:
+        clevel = 'W';
+        break;
+
+    case PS_LOG_INFO:
+        clevel = 'I';
+        break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+        clevel = level + '0';
+        break;
+
+    default:
+        psTrace("utils.logMsg", 2, "Invalid logMsg level: %d (%s)\n", level, format);
+        level = (level < 0) ? 0 : 9;
+        clevel = level + '0';
+        break;
+    }
+
+    // Only display this message if it's trace level is less than the level
+    // of it's associatedcomponent.
+    if (level <= psTraceGetLevel(comp)) {
+        //        va_start(ap, format);
+
+        // Create the various log fields...
+        if (traceTime) {
+            maxLength -= snprintf(head_ptr, maxLength, "%4d:%02d:%02d %02d:%02d:%02dZ",
+                                  utc->tm_year + 1900, utc->tm_mon + 1, utc->tm_mday,
+                                  utc->tm_hour, utc->tm_min, utc->tm_sec) - 1;
+            head_ptr += strlen(head_ptr);
+        }
+        // Hostname should be 20 characters.
+        if (traceHost) {
+            if (head_ptr > head) {
+                *head_ptr++ = '|';
+            }
+            maxLength -= snprintf(head_ptr, maxLength, "%-20s", hostname);
+            head_ptr += strlen(head_ptr);
+        }
+        if (traceLevel) {
+            if (head_ptr > head) {
+                *head_ptr++ = '|';
+            }
+            maxLength -= snprintf(head_ptr, maxLength, "%c", clevel);
+            head_ptr += strlen(head_ptr);
+        }
+        if (traceName) {
+            if (head_ptr > head) {
+                *head_ptr++ = '|';
+            }
+            maxLength -= snprintf(head_ptr, maxLength, "%s", comp);
+
+            head_ptr += strlen(head_ptr);
+        }
+
+        if (head_ptr > head) {
+            *head_ptr++ = '\n';
+        } else if (!traceMsg) {                  // no output desired
+            return;
+        }
+        *head_ptr = '\0';
+
+
+
+        fputs(head, traceFP);
+        if (traceMsg) {
+            // The following functions get the variable list of parameters with
+            // which this function was called, and print them to the standard
+            // output.
+            fmt = va_arg(ap, char *);
+
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                //            fprintf(traceFP, " ");
+                fprintf(traceFP, "%s", format);
+            }
+            vfprintf(traceFP, fmt, ap);
+            //        vfprintf(traceFP, format, ap);
+            //        va_end(ap);
+            /*            char msg[1024];
+                        char* msgPtr;
+                        vsnprintf(msg,1024, format, ap);  // create message
+             
+                        // detect multiple lines in message and indent each line by 4 spaces.
+                        char* line = strtok_r(msg,"\n",&msgPtr);
+                        while (line != NULL) {
+                            fprintf(logDest,"    %s\n",line);
+                            line = strtok_r(NULL,"\n",&msgPtr);
+                        }
+            */
+        } else {
+            fputc('\n', traceFP);
+        }
+
+
+    }
+
+}
+
 /*****************************************************************************
 p_psTrace(): we display the trace message to standard output if the trace
@@ -495,37 +645,8 @@
                ...)                     // arguments
 {
-    char *fmt = NULL;
     va_list ap;
-    psS32 i = 0;
-
-    if (traceFP == NULL) {
-        traceFP = stdout;
-    }
-
-    if (NULL == comp) {
-        psError(PS_ERR_BAD_PARAMETER_NULL, true,
-                PS_ERRORTEXT_psTrace_NULL_TRACETREE,
-                __func__);
-        return;
-    }
-    // Only display this message if it's trace level is less than the level
-    // of it's associatedcomponent.
-    if (level <= psTraceGetLevel(comp)) {
-        va_start(ap, format);
-
-        // The following functions get the variable list of parameters with
-        // which this function was called, and print them to the standard
-        // output.
-        fmt = va_arg(ap, char *);
-
-        // We indent each message one space for each level of the message.
-        for (i = 0; i < level; i++) {
-            //            fprintf(traceFP, " ");
-            fprintf(traceFP, "%s", format);
-        }
-        vfprintf(traceFP, fmt, ap);
-        //        vfprintf(traceFP, format, ap);
-        va_end(ap);
-    }
+    va_start(ap, format);
+    psTraceV(comp, level, format, ap);
+    va_end(ap);
     fflush(traceFP);
 }
@@ -576,3 +697,76 @@
 }
 
+/*****************************************************************************
+psTraceSetFormat(): Set the format of psTrace output.  More precisely,
+    provide a string consisting of the letters {H (host), L (level), M
+    (message), N (name), T (time)}.  The default is "HLMNT".  This string
+    determines whether or not they associated type of information will be
+    included in message traces.  It does not determine the order in which that
+    information will appear (that order is fixed).
+ 
+Input:
+    fmt: a string specifying the format.
+Return:
+    NULL.
+ *****************************************************************************/
+bool psTraceSetFormat(const char *format)
+{
+    // assume none.
+    traceHost = false;
+    traceLevel = false;
+    traceMsg = false;
+    traceName = false;
+    traceTime = false;
+
+    // if fmt is NULL, no logging is desired.
+    if (format == NULL) {
+        return false;
+    }
+
+    // XXX: What is the purpose of this conditional.
+    if (strlen(format) == 0) {
+        format = "THLNM";
+    }
+    // Step through each character in the format string.  For each letter
+    // in that string, set the appropriate logging.
+
+    for (const char *ptr = format; *ptr != '\0'; ptr++) {
+        switch (*ptr) {
+        case 'H':
+        case 'h':
+            traceHost = true;
+            break;
+        case 'L':
+        case 'l':
+            traceLevel = true;
+            break;
+        case 'M':
+        case 'm':
+            traceMsg = true;
+            break;
+        case 'N':
+        case 'n':
+            traceName = true;
+            break;
+        case 'T':
+        case 't':
+            traceTime = true;
+            break;
+        default:
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psLogMsg_UNKNOWN_KEY, *ptr);
+            return false;
+        }
+    }
+
+    // XXX: If one must at least log error messages, why don't we set logMsg = true here?
+    if (!traceMsg) {
+        psTrace("utils.traceMsg", 1, "You must at least trace error messages (You chose \"%s\")", format);
+
+    }
+    return true;
+}
+
+
+
 #endif // #ifndef PS_NO_TRACE
Index: /trunk/psLib/src/sys/psTrace.h
===================================================================
--- /trunk/psLib/src/sys/psTrace.h	(revision 4971)
+++ /trunk/psLib/src/sys/psTrace.h	(revision 4972)
@@ -9,6 +9,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.37 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-09-07 00:15:48 $
+ *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-09-08 00:27:50 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -59,6 +59,19 @@
 p_psComponent;
 
+#ifdef DOXYGEN
+/** This procedure sets the trace format for future trace messages.  The argument
+ *  must be a character string consistsing of the letters H (host), L
+ *  (level), M (message), N (name), and T (time).  The default is "THLNM".
+ *  Deleting a letter from the string will cause the associated information
+ *  to not be logged.  This procedure does not alter the order in which
+ *  the messages are displayed.
+ *
+ *  @return bool:       True if successful, otherwise false.
+ */
+bool psTraceSetFormat(
+    const char *format                 ///< Specifies the system trace format
+);
+
 /** Sends a trace message. */
-#ifdef DOXYGEN
 void psTrace(
     const char *facil,                 ///< facilty of interest
@@ -79,4 +92,12 @@
 #ifndef SWIG
 #define psTrace(facil, level, ...) p_psTrace(facil, level, __VA_ARGS__)
+/** Sends a trace message. */
+void psTraceV(
+    const char *facil,                 ///< facilty of interest
+    int level,                         ///< desired trace level
+    const char *format,                ///< printf-style format command
+    va_list ap                         ///< varargs argument list
+);
+
 #endif /* SWIG */
 
