=== modified file 'src/libmatrix/Makefile'
--- src/libmatrix/Makefile	2012-01-26 19:36:28 +0000
+++ src/libmatrix/Makefile	2012-05-22 09:55:39 +0000
@@ -21,7 +21,7 @@
 program.o: program.cc program.h mat.h vec.h
 log.o: log.cc log.h
 util.o: util.cc util.h
-shader-source.o: shader-source.cc shader-source.h mat.h vec.h
+shader-source.o: shader-source.cc shader-source.h mat.h vec.h util.h
 libmatrix.a : mat.o stack.h program.o log.o util.o shader-source.o
 	$(AR) -r $@  $(LIBOBJS)
 

=== modified file 'src/libmatrix/util.cc'
--- src/libmatrix/util.cc	2012-01-27 22:21:17 +0000
+++ src/libmatrix/util.cc	2012-05-22 09:55:39 +0000
@@ -22,21 +22,58 @@
 #include "log.h"
 #include "util.h"
 
-/**
- * Splits a string using a delimiter
- *
- * @param s the string to split
- * @param delim the delimitir to use
- * @param elems the string vector to populate
- */
+using std::string;
+using std::vector;
+
 void
-Util::split(const std::string &s, char delim, std::vector<std::string> &elems)
+Util::split(const string& src, char delim, vector<string>& elementVec, bool fuzzy)
 {
-    std::stringstream ss(s);
-
-    std::string item;
-    while(std::getline(ss, item, delim))
-        elems.push_back(item);
+    // Trivial rejection
+    if (src.empty())
+    {
+        return;
+    }
+
+    // Simple case: we want to enforce the value of 'delim' strictly 
+    if (!fuzzy)
+    {
+        std::stringstream ss(src);
+        string item;
+        while(std::getline(ss, item, delim))
+            elementVec.push_back(item);
+        return;
+    }
+
+    // Fuzzy case: Initialize our delimiter string based upon the caller's plus
+    // a space to allow for more flexibility.
+    string delimiter(" ");
+    delimiter += delim;
+    // Starting index into the string of the first token (by definition, if
+    // we're parsing a string, there is at least one token).
+    string::size_type startPos(0);
+    // string::find_first_of() looks for any character in the string provided,
+    // it is not treated as a sub-string, so regardless of where the space or
+    // comma is or how many there are, the result is the same.
+    string str(src);
+    string::size_type endPos = str.find_first_of(delimiter);
+    while (endPos != string::npos)
+    {
+        // Push back the current element starting at startPos for
+        // (endPos - startPos) characters.  std::string takes care of
+        // terminators, etc.
+        elementVec.push_back(string(str, startPos, endPos - startPos));
+        // Index of the next element after any delimiter characters.  Same
+        // caveat applies to find_first_not_of() that applies to
+        // find_first_of(); endPos tells it where to start the search. 
+        string::size_type nextPos = str.find_first_not_of(delimiter, endPos);
+        // Erase the part of the string we've already parsed.
+        str = str.erase(startPos, nextPos - startPos);
+        // Look for the next delimiter.  If there isn't one, we bail out.
+        endPos = str.find_first_of(delimiter);
+    }
+    // Regardless of whether we initially had one element or many, 'str' now
+    // only contains one.
+    elementVec.push_back(str);
 }
 
 uint64_t

=== modified file 'src/libmatrix/util.h'
--- src/libmatrix/util.h	2012-01-27 22:21:17 +0000
+++ src/libmatrix/util.h	2012-05-22 09:55:39 +0000
@@ -24,10 +24,53 @@
 #endif
 
 struct Util {
-    static void split(const std::string &s, char delim, std::vector<std::string> &elems);
+    /**
+     * split() - Splits a string into elements using a provided delimiter
+     *
+     * @s:          the string to split
+     * @delim:      the delimiter to use
+     * @elems:      the string vector to populate
+     * @fuzzy:      (optional) enable/disable strict handling of @delim
+     *
+     * Using @delim to determine field boundaries, splits @s into separate
+     * string elements.  These elements are returned in the string vector
+     * @elems.  If @fuzzy is true, then the handling of @delim allows for
+     * spaces and multiple consecutive occurences of @delim in determining
+     * field boundaries.  As long as @s is non-empty, there will be at least
+     * one element in @elems.
+     */
+    static void split(const std::string &s, char delim, std::vector<std::string> &elems, bool fuzzy = false);
+    /**
+     * get_timestamp_us() - Returns the current time in microseconds
+     */
     static uint64_t get_timestamp_us();
+    /**
+     * get_resource() - Gets an input filestream for a given file.
+     *
+     * @path:       the path to the file
+     *
+     * Returns a pointer to an input stream, which must be deleted when no
+     * longer in use.
+     */
     static std::istream *get_resource(const std::string &path);
+    /**
+     * list_files() - Get a list of the files in a given directory.
+     *
+     * @dirName:    the directory path to be listed.
+     * @fileVec:    the string vector to populate.
+     *
+     * Obtains a list of the files in @dirName, and returns them in the string
+     * vector @fileVec.
+     */
     static void list_files(const std::string& dirName, std::vector<std::string>& fileVec);
+    /**
+     * dispose_pointer_vector() - cleans up a vector of pointers
+     *
+     * @vec:        vector of pointers to objects or plain-old-data
+     *
+     * Iterates across @vec and deletes the data pointed to by each of the
+     * elements.  Clears the vector, resetting it for reuse.
+     */
     template <class T> static void dispose_pointer_vector(std::vector<T*> &vec)
     {
         for (typename std::vector<T*>::const_iterator iter = vec.begin();
@@ -39,16 +82,25 @@
 
         vec.clear();
     }
+    /**
+     * toString() - Converts a string to a plain-old-data type.
+     *
+     * @asString:   a string representation of plain-old-data.
+     */
     template<typename T>
     static T
     fromString(const std::string& asString)
     {
         std::stringstream ss(asString);
-        T retVal;
+        T retVal = T();
         ss >> retVal;
         return retVal;
     }
-
+    /**
+     * toString() - Converts a plain-old-data type to a string.
+     *
+     * @t:      a simple value to be converted to a string
+     */
     template<typename T>
     static std::string
     toString(const T t)
@@ -57,6 +109,13 @@
         ss << t;
         return ss.str();
     }
+    /**
+     * appname_from_path() - get the name of an executable from an absolute path
+     *
+     * @path:   absolute path of the running application (argv[0])
+     *
+     * Returns the last portion of @path (everything after the final '/').
+     */
     static std::string
     appname_from_path(const std::string& path);
 

