=== modified file 'Makefile'
--- Makefile	2011-06-17 16:37:04 +0000
+++ Makefile	2011-06-21 22:37:41 +0000
@@ -1,24 +1,31 @@
-TARGETS = libmatrix.a
-TESTS = matrix_inverse_test
-SRCS = mat.cc program.cc matrix_inverse_test.cc
-OBJS = $(SRCS:.cc=.o)
 CXXFLAGS = -Wall -Werror -pedantic -O3
+LIBMATRIX = libmatrix.a
+LIBSRCS = mat.cc program.cc
+LIBOBJS = $(LIBSRCS:.cc=.o)
+TESTDIR = test
+LIBMATRIX_TESTS = $(TESTDIR)/libmatrix_test
+TESTSRCS = $(TESTDIR)/options.cc \
+           $(TESTDIR)/inverse_test.cc \
+           $(TESTDIR)/libmatrix_test.cc
+TESTOBJS = $(TESTSRCS:.cc=.o)
 
 # Make sure to build both the library targets and the tests, and generate 
 # a make failure if the tests don't pass.
-default: $(TARGETS) $(TESTS) run_tests
+default: $(LIBMATRIX) $(LIBMATRIX_TESTS) run_tests
 
 # Main library targets here.
-mat.o : mat.cc mat.h
-program.o: program.cc program.h
+mat.o : mat.cc mat.h vec.h
+program.o: program.cc program.h mat.h vec.h
 libmatrix.a : mat.o mat.h stack.h vec.h program.o program.h
-	$(AR) -r $@  $(OBJS)
+	$(AR) -r $@  $(LIBOBJS)
 
 # Tests and execution targets here.
-matrix_inverse_test.o: matrix_inverse_test.cc mat.h
-matrix_inverse_test: matrix_inverse_test.o libmatrix.a
+$(TESTDIR)/options.o: $(TESTDIR)/options.cc $(TESTDIR)/libmatrix_test.h
+$(TESTDIR)/libmatrix_test.o: $(TESTDIR)/libmatrix_test.cc $(TESTDIR)/libmatrix_test.h $(TESTDIR)/inverse_test.h
+$(TESTDIR)/inverse_test.o: $(TESTDIR)/inverse_test.cc $(TESTDIR)/inverse_test.h $(TESTDIR)/libmatrix_test.h mat.h
+$(TESTDIR)/libmatrix_test: $(TESTDIR)/options.o $(TESTDIR)/libmatrix_test.o $(TESTDIR)/inverse_test.o libmatrix.a
 	$(CXX) -o $@ $?
-run_tests: $(TESTS)
-	./matrix_inverse_test
+run_tests: $(LIBMATRIX_TESTS)
+	$(LIBMATRIX_TESTS)
 clean :
-	$(RM) $(OBJS) $(TARGETS)
+	$(RM) $(LIBOBJS) $(TESTOBJS) $(LIBMATRIX) $(LIBMATRIX_TESTS)

=== added directory 'test'
=== added file 'test/inverse_test.cc'
--- test/inverse_test.cc	1970-01-01 00:00:00 +0000
+++ test/inverse_test.cc	2011-06-21 22:37:41 +0000
@@ -0,0 +1,161 @@
+#include <iostream>
+#include "libmatrix_test.h"
+#include "inverse_test.h"
+#include "../mat.h"
+
+using LibMatrix::mat2;
+using LibMatrix::mat3;
+using LibMatrix::mat4;
+using std::cout;
+using std::endl;
+
+void
+MatrixTest2x2Inverse::run(const Options& options)
+{
+    mat2 m;
+
+    if (options.beVerbose())
+    {
+        cout << "Starting with mat2 (should be identity): " << endl << endl;
+        m.print();
+    }
+
+    m[0][1] = -2.5;
+    
+    if (options.beVerbose())
+    {
+        cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl;
+        m.print();
+    }
+    
+    mat2 mi(m);
+
+    if (options.beVerbose())
+    {
+        cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl;
+        mi.print();
+    }
+
+    mi.inverse();
+
+    if (options.beVerbose())
+    {
+        cout << endl << "Inverse of copy: " << endl << endl;
+        mi.print();
+    }
+
+    mat2 i = m * mi;
+
+    if (options.beVerbose())
+    {
+        cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
+        i.print();
+    }
+
+    mat2 ident;
+    if (i == ident)
+    {
+        pass_ = true;
+    }
+}
+
+void
+MatrixTest3x3Inverse::run(const Options& options)
+{
+    mat3 m;
+
+    if (options.beVerbose())
+    {
+        cout << "Starting with mat3 (should be identity): " << endl << endl;
+        m.print();
+    }
+
+    m[1][2] = -2.5;
+    
+    if (options.beVerbose())
+    {
+        cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl;
+        m.print();
+    }
+
+    mat3 mi(m);
+
+    if (options.beVerbose())
+    {
+        cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl;
+        mi.print();
+    }
+
+    mi.inverse();
+
+    if (options.beVerbose())
+    {
+        cout << endl << "Inverse of copy: " << endl << endl;
+        mi.print();
+    }
+
+    mat3 i = m * mi;
+
+    if (options.beVerbose())
+    {
+        cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
+        i.print();
+    }
+
+    mat3 ident;
+    if (i == ident)
+    {
+        pass_ = true;
+    }
+}
+
+void
+MatrixTest4x4Inverse::run(const Options& options)
+{
+    mat4 m;
+
+    if (options.beVerbose())
+    {
+        cout << "Starting with mat4 (should be identity): " << endl << endl;
+        m.print();
+    }
+
+    m[2][3] = -2.5;
+    
+    if (options.beVerbose())
+    {
+        cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl;
+        m.print();
+    }
+
+    mat4 mi(m);
+
+    if (options.beVerbose())
+    {
+        cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl;
+        mi.print();
+    }
+
+    mi.inverse();
+
+    if (options.beVerbose())
+    {
+        cout << endl << "Inverse of copy: " << endl << endl;
+        mi.print();
+    }
+
+    mat4 i = m * mi;
+
+    if (options.beVerbose())
+    {
+        cout << endl <<  "Product of original and inverse (should be identity): " << endl << endl;
+        i.print();
+    }
+
+    mat4 ident;
+    if (i == ident)
+    {
+        pass_ = true;
+    }
+}
+

=== added file 'test/inverse_test.h'
--- test/inverse_test.h	1970-01-01 00:00:00 +0000
+++ test/inverse_test.h	2011-06-21 22:37:41 +0000
@@ -0,0 +1,28 @@
+#ifndef INVERSE_TEST_H_
+#define INVERSE_TEST_H_
+
+class MatrixTest;
+class Options;
+
+class MatrixTest2x2Inverse : public MatrixTest
+{
+public:
+    MatrixTest2x2Inverse() : MatrixTest("mat2::inverse") {}
+    virtual void run(const Options& options);
+};
+
+class MatrixTest3x3Inverse : public MatrixTest
+{
+public:
+    MatrixTest3x3Inverse() : MatrixTest("mat3::inverse") {}
+    virtual void run(const Options& options);
+};
+
+class MatrixTest4x4Inverse : public MatrixTest
+{
+public:
+    MatrixTest4x4Inverse() : MatrixTest("mat4::inverse") {}
+    virtual void run(const Options& options);
+};
+
+#endif // INVERSE_TEST_H_

=== renamed file 'matrix_inverse_test.cc' => 'test/libmatrix_test.cc'
--- matrix_inverse_test.cc	2011-06-16 22:37:59 +0000
+++ test/libmatrix_test.cc	2011-06-21 22:37:41 +0000
@@ -10,143 +10,48 @@
 //     Jesse Barker - original implementation.
 //
 #include <iostream>
-#include "mat.h"
+#include <string>
+#include <vector>
+#include "libmatrix_test.h"
+#include "inverse_test.h"
 
-using LibMatrix::mat4;
-using LibMatrix::mat3;
-using LibMatrix::mat2;
 using std::cerr;
 using std::cout;
 using std::endl;
 
-bool mat2OK()
-{
-    mat2 m;
-    cout << "Starting with mat2 (should be identity): " << endl << endl;
-    m.print();
-
-    m[0][1] = -2.5;
-    
-    cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl;
-    m.print();
-    
-    mat2 mi(m);
-
-    cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl;
-    mi.print();
-
-    mi.inverse();
-
-    cout << endl << "Inverse of copy: " << endl << endl;
-    mi.print();
-
-    mat2 i = m * mi;
-
-    cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
-    i.print();
-
-    mat2 ident;
-    if (i != ident)
-    {
-        return false;
-    }
-
-    return true;
-}
-
-bool mat3OK()
-{
-    mat3 m;
-    cout << "Starting with mat3 (should be identity): " << endl << endl;
-    m.print();
-
-    m[1][2] = -2.5;
-    
-    cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl;
-    m.print();
-    
-    mat3 mi(m);
-
-    cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl;
-    mi.print();
-
-    mi.inverse();
-
-    cout << endl << "Inverse of copy: " << endl << endl;
-    mi.print();
-
-    mat3 i = m * mi;
-
-    cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
-    i.print();
-
-    mat3 ident;
-    if (i != ident)
-    {
-        return false;
-    }
-
-    return true;
-}
-
-bool mat4OK()
-{
-    mat4 m;
-    cout << "Starting with mat4 (should be identity): " << endl << endl;
-    m.print();
-
-    m[2][3] = -2.5;
-    
-    cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl;
-    m.print();
-    
-    mat4 mi(m);
-
-    cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl;
-    mi.print();
-
-    mi.inverse();
-
-    cout << endl << "Inverse of copy: " << endl << endl;
-    mi.print();
-
-    mat4 i = m * mi;
-
-    cout << endl <<  "Product of original and inverse (should be identity): " << endl << endl;
-    i.print();
-
-    mat4 ident;
-    if (i != ident)
-    {
-        return false;
-    }
-
-    return true;
-}
-
 int
 main(int argc, char** argv)
 {
-    if (!mat2OK())
-    {
-        cerr << "mat2::inverse() does not work!" << endl;
-        return 1;
-    }
-    cout << "mat2::inverse() is okay!" << endl << endl;
-
-    if (!mat3OK())
-    {
-        cerr << "mat3::inverse() does not work!" << endl;
-        return 1;
-    }
-    cout << "mat3::inverse() is okay!" << endl << endl;
-
-    if (!mat4OK())
-    {
-        cerr << "mat4::inverse() does not work!" << endl;
-        return 1;
-    }
-    cout << "mat4::inverse() is okay!" << endl << endl;
+    Options testOptions("matrix_test");
+    testOptions.parseArgs(argc, argv);
+    if (testOptions.showHelp())
+    {
+        testOptions.printUsage();
+        return 0;
+    }
+
+    using std::vector;
+    vector<MatrixTest*> testVec;
+    testVec.push_back(new MatrixTest2x2Inverse());
+    testVec.push_back(new MatrixTest3x3Inverse());
+    testVec.push_back(new MatrixTest4x4Inverse());
+
+    for (vector<MatrixTest*>::iterator testIt = testVec.begin();
+         testIt != testVec.end();
+         testIt++)
+    {
+        MatrixTest* curTest = *testIt;
+        curTest->run(testOptions);
+        if (!curTest->passed())
+        {
+            cerr << curTest->name() << " does not work!" << endl;
+            return 1;
+        }
+        if (testOptions.beVerbose())
+        {
+            cout << curTest->name() << " is okay!" << endl;
+        }
+    }
 
     return 0;
 }

=== added file 'test/libmatrix_test.h'
--- test/libmatrix_test.h	1970-01-01 00:00:00 +0000
+++ test/libmatrix_test.h	2011-06-21 22:37:41 +0000
@@ -0,0 +1,40 @@
+#ifndef LIBMATRIX_TEST_H_
+#define LIBMATRIX_TEST_H_
+
+class Options
+{
+    Options();
+    static const std::string verbose_name_;
+    static const std::string help_name_;
+    std::string app_name_;
+    bool show_help_;
+    bool verbose_;
+public:
+    Options(const std::string& app_name) :
+        app_name_(app_name),
+        show_help_(false),
+        verbose_(false) {}
+    ~Options() {}
+    bool beVerbose() const { return verbose_; }
+    bool showHelp() const { return show_help_; }
+    void parseArgs(int argc, char** argv);
+    void printUsage();
+};
+
+class MatrixTest
+{
+    std::string name_;
+protected:
+    bool pass_;
+    MatrixTest();
+public:
+    MatrixTest(const std::string& name) : 
+        name_(name),
+        pass_(false) {}
+    ~MatrixTest();
+    const std::string& name() const { return name_; }
+    virtual void run(const Options& options) = 0;
+    const bool passed() const { return pass_; }
+};
+
+#endif // LIBMATRIX_TEST_H_

=== added file 'test/options.cc'
--- test/options.cc	1970-01-01 00:00:00 +0000
+++ test/options.cc	2011-06-21 22:37:41 +0000
@@ -0,0 +1,56 @@
+#include <iostream>
+#include <iomanip>
+#include <getopt.h>
+#include "libmatrix_test.h"
+
+using std::cout;
+using std::endl;
+
+const std::string Options::verbose_name_("verbose");
+const std::string Options::help_name_("help");
+
+void
+Options::parseArgs(int argc, char** argv)
+{
+    static struct option long_options[] = {
+        {"verbose", 0, 0, 0},
+        {"help", 0, 0, 0},
+        {0, 0, 0, 0}
+    };
+    int option_index(0);
+    int c =  getopt_long(argc, argv, "", long_options, &option_index);
+    while (c != -1) 
+    {
+        std::string optname(long_options[option_index].name);
+
+        if (optname == verbose_name_)
+        {
+            verbose_ = true;
+        }
+        else if (optname == help_name_)
+        {
+            show_help_ = true;
+        }
+        c = getopt_long(argc, argv, "",
+                        long_options, &option_index);
+    }
+}
+
+
+static void
+emitColumnOne(const std::string& text)
+{
+    cout << std::setw(16) << text;
+}
+
+void
+Options::printUsage()
+{
+    cout << app_name_ << ": directed functional test utility for libmatrix." << endl;
+    cout << "Options:" << endl;
+    emitColumnOne("--verbose"); 
+    cout << std::setw(0) << " Enable verbose output during test runs." << endl;
+    emitColumnOne("--help");
+    cout << std::setw(0) << " Print this usage text." << endl;   
+}
+

