Index: trunk/psLib/src/sys/Makefile.am
===================================================================
--- trunk/psLib/src/sys/Makefile.am	(revision 7300)
+++ trunk/psLib/src/sys/Makefile.am	(revision 7380)
@@ -9,4 +9,5 @@
 	psError.c      \
 	psErrorCodes.c \
+	psLine.c       \
 	psLogMsg.c     \
 	psMemory.c     \
@@ -32,4 +33,5 @@
 	psError.h      \
 	psErrorCodes.h \
+	psLine.h       \
 	psLogMsg.h     \
 	psMemory.h     \
Index: trunk/psLib/src/sys/psLine.c
===================================================================
--- trunk/psLib/src/sys/psLine.c	(revision 7380)
+++ trunk/psLib/src/sys/psLine.c	(revision 7380)
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "psMemory.h"
+#include "psConstants.h"
+#include "psLine.h"
+
+static void lineFree(psLine *line)
+{
+
+    if (!line) {
+        return;
+    }
+
+    psFree (line->line);
+    return;
+}
+
+// allocate a psLine structrue
+psLine *psLineAlloc(long Nline)
+{
+    psLine *line = psAlloc(sizeof(psLine));
+    psMemSetDeallocator(line, (psFreeFunc)lineFree);
+    line->Nline = 0;
+    line->NLINE = Nline;
+    line->line = psAlloc(Nline);
+
+    return line;
+}
+
+bool psLineInit(psLine *line)
+{
+    if (!line) {
+        return false;
+    }
+
+    line->Nline = 0;
+    return true;
+}
+
+bool psLineAdd(psLine *line, const char *format, ...)
+{
+    if (!line) {
+        return false;
+    }
+
+    long nMax = line->NLINE - line->Nline;
+
+    va_list ap;
+    va_start(ap, format);
+    long Nchar = vsnprintf(&line->line[line->Nline], nMax, format, ap);
+    line->Nline += PS_MIN(nMax - 1, Nchar);
+    va_end(ap);
+
+    if (Nchar >= nMax) {
+        return false;
+    }
+    return true;
+}
Index: trunk/psLib/src/sys/psLine.h
===================================================================
--- trunk/psLib/src/sys/psLine.h	(revision 7380)
+++ trunk/psLib/src/sys/psLine.h	(revision 7380)
@@ -0,0 +1,27 @@
+/** @file  psLine.h
+ *
+ * the psLine functions allow manipulation of fixed-length lines
+ */
+
+#ifndef PS_LINE_H
+#define PS_LINE_H
+
+// structure to carry a dynamic string
+typedef struct
+{
+    long NLINE;                 // allocated length
+    long Nline;                 // current length
+    char *line;                 // character string data
+}
+psLine;
+
+// allocate a line object of length Nline
+psLine *psLineAlloc(long Nline);
+
+// (re-)init the line
+bool psLineInit(psLine *line);
+
+// add the new string segment to the line
+bool psLineAdd(psLine *line, const char *format, ...);
+
+#endif /* PS_LINE_H */
Index: trunk/psLib/src/sys/psString.c
===================================================================
--- trunk/psLib/src/sys/psString.c	(revision 7300)
+++ trunk/psLib/src/sys/psString.c	(revision 7380)
@@ -13,6 +13,6 @@
  *  @author David Robbins, MHPCC
  *
- *  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-05-31 20:56:37 $
+ *  @version $Revision: 1.31 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-06-07 03:22:06 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -31,9 +31,9 @@
 psString psStringCopy(const char *string)
 {
-    PS_ASSERT_PTR_NON_NULL(string, NULL);
+    // Pass through NULL values!
+
     // Allocate memory using psAlloc function
     // Copy input string to memory just allocated
     // Return the copy
-    // Pass through NULL values
     return string ? strcpy(psAlloc(strlen(string) + 1), string) : NULL;
 }
@@ -218,18 +218,15 @@
 // given the input string, search for all copies of the key, and replace with the replacement value
 // the input string may be freed if not needed
-char *psStringSubstitute (char *input, char *replace, char *key)
-{
-
-    char *p;
-
-    if (key == NULL)
+char *psStringSubstitute(char *input, const char *replace, const char *key)
+{
+    if (key == NULL || strlen(key) == 0) {
         return input;
-    if (strlen(key) == 0)
-        return input;
+    }
 
     while (true) {
-        p = strstr (input, key);
-        if (p == NULL)
+        char *p = strstr (input, key);
+        if (!p) {
             return input;
+        }
 
         // we have input = xxxkeyxxx
@@ -241,15 +238,14 @@
 
         // copy the first segement into 'output'
-        strncpy (output, input, Nc);
+        strncpy(output, input, Nc);
 
         // copy the key replacement to the start of the key
-
-        strcpy (&output[Nc], replace);
+        strcpy(&output[Nc], replace);
         Nc += strlen (replace);
 
         // copy the remainder to the end of the replacement
-        strcpy (&output[Nc], p + strlen(key));
-
-        psFree (input);
+        strcpy(&output[Nc], p + strlen(key));
+
+        psFree(input);
         input = output;
     }
@@ -257,2 +253,35 @@
 }
 
+psArray *psStringSplitArray(const char *string, const char *splitters, bool multi)
+{
+
+    psList *list = psStringSplit(string, splitters, multi);
+    psArray *array = psListToArray(list);
+    psFree (list);
+    return array;
+}
+
+#ifndef whitespace
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
+#endif
+
+/* Strip whitespace from the start and end of STRING. */
+size_t psStringStrip(char *string)
+{
+    long i;
+
+    if (!string || strlen(string) == 0) {
+        return 0;
+    }
+
+    for (i = 0; i < strlen(string) && whitespace(string[i]); i++)
+        ; // No action
+    if (i) {
+        memmove (string, string + i, strlen(string+i)+1);
+    }
+    for (i = strlen (string) - 1; (i > 0) && whitespace(string[i]); i--)
+        ; // No action
+    string[++i] = 0;
+
+    return i;
+}
Index: trunk/psLib/src/sys/psString.h
===================================================================
--- trunk/psLib/src/sys/psString.h	(revision 7300)
+++ trunk/psLib/src/sys/psString.h	(revision 7380)
@@ -14,6 +14,6 @@
  *  @author David Robbins, MHPCC
  *
- *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-06-02 21:33:34 $
+ *  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-06-07 03:22:06 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -107,11 +107,20 @@
 );
 
-// given the input string, search for all copies of the key, and replace with the replacement value
+// Same as psStringSplit, but return result as an array
+psArray *psStringSplitArray(const char *string, // String to split
+                            const char *splitters, // Characters on which to split
+                            bool multipleAreSignificant // Are multiple occurences significant?
+                           );
+
+// Given the input string, search for all copies of the key, and replace with the replacement value
 // the input string may be freed if not needed
-char *psStringSubstitute (
-    char *input,    ///< input string to be modified
-    char *replace,    ///< replacement value
-    char *key    ///< string to be replaced in input
-);
+char *psStringSubstitute (char *input,  ///< input string to be modified
+                          const char *replace, ///< replacement value
+                          const char *key ///< string to be replaced in input
+                         );
+
+// strip whitespace from head and tail of string
+size_t psStringStrip(char *string);
+
 
 /** @} */// Doxygen - End of SystemGroup Functions
