=== modified file 'src/libmatrix/Makefile'
--- src/libmatrix/Makefile	2011-01-17 18:15:21 +0000
+++ src/libmatrix/Makefile	2011-06-22 08:59:00 +0000
@@ -1,14 +1,31 @@
-TARGETS = libmatrix.a
-SRCS = mat.cc
-OBJS = $(SRCS:.cc=.o)
 CXXFLAGS = -Wall -Werror -pedantic -O3
-
-default: $(TARGETS)
-
-mat.o : mat.cc mat.h
-
-libmatrix.a : mat.o mat.h stack.h vec.h
-	$(AR) -r $@  $(OBJS)
-
+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: $(LIBMATRIX) $(LIBMATRIX_TESTS) run_tests
+
+# Main library targets here.
+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 $@  $(LIBOBJS)
+
+# Tests and execution targets here.
+$(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: $(LIBMATRIX_TESTS)
+	$(LIBMATRIX_TESTS)
 clean :
-	$(RM) $(OBJS) $(TARGETS)
+	$(RM) $(LIBOBJS) $(TESTOBJS) $(LIBMATRIX) $(LIBMATRIX_TESTS)

=== modified file 'src/libmatrix/mat.h'
--- src/libmatrix/mat.h	2011-04-21 17:49:26 +0000
+++ src/libmatrix/mat.h	2011-06-22 08:59:00 +0000
@@ -11,7 +11,7 @@
 //
 #ifndef MAT_H_
 #define MAT_H_
-
+#include <stdexcept>
 #include <iostream>
 #include <iomanip>
 #include "vec.h"
@@ -61,6 +61,13 @@
         m_[2] = m.m_[2];
         m_[3] = m.m_[3];
     }
+    tmat2(const T& c0r0, const T& c0r1, const T& c1r0, const T& c1r1)
+    {
+        m_[0] = c0r0;
+        m_[1] = c0r1;
+        m_[2] = c1r0;
+        m_[3] = c1r1;
+    }
     ~tmat2() {}
 
     void setIdentity()
@@ -71,11 +78,35 @@
         m_[3] = 1;
     }
 
-    void transpose()
+    tmat2& transpose()
     {
         T tmp_val = m_[1];
         m_[1] = m_[2];
         m_[2] = tmp_val;
+        return *this;
+    }
+
+    T determinant()
+    {
+        return (m_[0] * m_[3]) - (m_[2] * m_[1]);
+    }
+
+    tmat2& inverse() throw(std::runtime_error)
+    {
+        T d(determinant());
+        if (d == static_cast<T>(0))
+        {
+            throw std::runtime_error("Matrix is noninvertible!!!!");
+        }
+        T c0r0(m_[3] / d);
+        T c0r1(-m_[1] / d);
+        T c1r0(-m_[2] / d);
+        T c1r1(m_[0] / d);
+        m_[0] = c0r0;
+        m_[1] = c0r1;
+        m_[2] = c1r0;
+        m_[3] = c1r1;        
+        return *this;
     }
 
     void print() const
@@ -83,20 +114,33 @@
         static const int precision(6);
         // row 0
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][0];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
         std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][1];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
         std::cout << " |" << std::endl;
         // row 1
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][0];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
         std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][1];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
         std::cout << " |" << std::endl;
     }
 
     operator const T*() const { return &m_[0];}
 
+    bool operator==(const tmat2& rhs) const
+    {
+        return m_[0] == rhs.m_[0] &&
+               m_[1] == rhs.m_[1] &&
+               m_[2] == rhs.m_[2] &&
+               m_[3] == rhs.m_[3];
+    }
+
+    bool operator!=(const tmat2& rhs) const
+    {
+        return !(*this == rhs);
+    }
+
     tmat2& operator=(const tmat2& rhs)
     {
         if (this != &rhs)
@@ -249,6 +293,20 @@
         m_[7] = m.m_[7];
         m_[8] = m.m_[8];
     }
+    tmat3(const T& c0r0, const T& c0r1, const T& c0r2,
+           const T& c1r0, const T& c1r1, const T& c1r2,
+           const T& c2r0, const T& c2r1, const T& c2r2)
+    {
+        m_[0] = c0r0;
+        m_[1] = c0r1;
+        m_[2] = c0r2;
+        m_[3] = c1r0;
+        m_[4] = c1r1;
+        m_[5] = c1r2;
+        m_[6] = c2r0;
+        m_[7] = c2r1;
+        m_[8] = c2r2;
+    }
     ~tmat3() {}
 
     void setIdentity()
@@ -264,7 +322,7 @@
         m_[8] = 1;
     }
 
-    void transpose()
+    tmat3& transpose()
     {
         T tmp_val = m_[1];
         m_[1] = m_[3];
@@ -275,6 +333,45 @@
         tmp_val = m_[5];
         m_[5] = m_[7];
         m_[7] = tmp_val;
+        return *this;
+    }
+
+    T determinant()
+    {
+        tmat2<T> minor0(m_[4], m_[5], m_[7], m_[8]);
+        tmat2<T> minor3(m_[1], m_[2], m_[7], m_[8]);
+        tmat2<T> minor6(m_[1], m_[2], m_[4], m_[5]);
+        return (m_[0] * minor0.determinant()) - 
+               (m_[3] * minor3.determinant()) +
+               (m_[6] * minor6.determinant());
+    }
+
+    tmat3& inverse() throw(std::runtime_error)
+    {
+        T d(determinant());
+        if (d == static_cast<T>(0))
+        {
+            throw std::runtime_error("Matrix is noninvertible!!!!");
+        }
+        tmat2<T> minor0(m_[4], m_[5], m_[7], m_[8]);
+        tmat2<T> minor1(m_[7], m_[8], m_[1], m_[2]);
+        tmat2<T> minor2(m_[1], m_[2], m_[4], m_[5]);
+        tmat2<T> minor3(m_[6], m_[8], m_[3], m_[5]);
+        tmat2<T> minor4(m_[0], m_[2], m_[6], m_[8]);
+        tmat2<T> minor5(m_[3], m_[5], m_[0], m_[2]);
+        tmat2<T> minor6(m_[3], m_[4], m_[6], m_[7]);
+        tmat2<T> minor7(m_[6], m_[7], m_[0], m_[1]);
+        tmat2<T> minor8(m_[0], m_[1], m_[3], m_[4]);
+        m_[0] = minor0.determinant() / d;
+        m_[1] = minor1.determinant() / d;
+        m_[2] = minor2.determinant() / d;
+        m_[3] = minor3.determinant() / d;
+        m_[4] = minor4.determinant() / d;
+        m_[5] = minor5.determinant() / d;
+        m_[6] = minor6.determinant() / d;
+        m_[7] = minor7.determinant() / d;
+        m_[8] = minor8.determinant() / d;
+        return *this;       
     }
 
     void print() const
@@ -282,32 +379,50 @@
         static const int precision(6);
         // row 0
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][0];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][1];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][2];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[6];
         std::cout << " |" << std::endl;
         // row 1
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][0];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][1];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][2];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[4];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[7];
         std::cout << " |" << std::endl;
         // row 2
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][0];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][1];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][2];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[5];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[8];
         std::cout << " |" << std::endl;
     }
 
     operator const T*() const { return &m_[0];}
 
+    bool operator==(const tmat3& rhs) const
+    {
+        return m_[0] == rhs.m_[0] &&
+               m_[1] == rhs.m_[1] &&
+               m_[2] == rhs.m_[2] &&
+               m_[3] == rhs.m_[3] &&
+               m_[4] == rhs.m_[4] &&
+               m_[5] == rhs.m_[5] &&
+               m_[6] == rhs.m_[6] &&
+               m_[7] == rhs.m_[7] &&
+               m_[8] == rhs.m_[8];
+    }
+
+    bool operator!=(const tmat3& rhs) const
+    {
+        return !(*this == rhs);
+    }
+
     tmat3& operator=(const tmat3& rhs)
     {
         if (this != &rhs)
@@ -531,7 +646,7 @@
         m_[15] = 1;
     }
 
-    void transpose()
+    tmat4& transpose()
     {
         T tmp_val = m_[1];
         m_[1] = m_[4];
@@ -551,6 +666,64 @@
         tmp_val = m_[11];
         m_[11] = m_[14];
         m_[14] = tmp_val;
+        return *this;
+    }
+
+    T determinant()
+    {
+        tmat3<T> minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+        tmat3<T> minor4(m_[1], m_[2], m_[3], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+        tmat3<T> minor8(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[13], m_[14], m_[15]);
+        tmat3<T> minor12(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[9], m_[10], m_[11]);
+        return (m_[0] * minor0.determinant()) -
+               (m_[4] * minor4.determinant()) +
+               (m_[8] * minor8.determinant()) -
+               (m_[12] * minor12.determinant());
+    }
+
+    tmat4& inverse() throw(std::runtime_error)
+    {
+        T d(determinant());
+        if (d == static_cast<T>(0))
+        {
+            throw std::runtime_error("Matrix is noninvertible!!!!");
+        }
+        tmat3<T> minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+        tmat3<T> minor1(m_[1], m_[2], m_[3], m_[13], m_[14], m_[15], m_[9], m_[10], m_[11]);
+        tmat3<T> minor2(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[13], m_[14], m_[15]);
+        tmat3<T> minor3(m_[1], m_[2], m_[3], m_[9], m_[10], m_[11], m_[5], m_[6], m_[7]);
+
+        tmat3<T> minor4(m_[4], m_[6], m_[7], m_[12], m_[14], m_[15], m_[8], m_[10], m_[11]);
+        tmat3<T> minor5(m_[0], m_[2], m_[3], m_[8], m_[10], m_[11], m_[12], m_[14], m_[15]);
+        tmat3<T> minor6(m_[0], m_[2], m_[3], m_[12], m_[14], m_[15], m_[4], m_[6], m_[7]);
+        tmat3<T> minor7(m_[0], m_[2], m_[3], m_[4], m_[6], m_[7], m_[8], m_[10], m_[11]);
+
+        tmat3<T> minor8(m_[4], m_[5], m_[7], m_[8], m_[9], m_[11], m_[12], m_[13], m_[15]);
+        tmat3<T> minor9(m_[0], m_[1], m_[3], m_[12], m_[13], m_[15], m_[8], m_[9], m_[11]);
+        tmat3<T> minor10(m_[0], m_[1], m_[3], m_[4], m_[5], m_[7], m_[12], m_[13], m_[15]);
+        tmat3<T> minor11(m_[0], m_[1], m_[3], m_[8], m_[9], m_[11], m_[4], m_[5], m_[7]);
+
+        tmat3<T> minor12(m_[4], m_[5], m_[6], m_[12], m_[13], m_[14], m_[8], m_[9], m_[10]);
+        tmat3<T> minor13(m_[0], m_[1], m_[2], m_[8], m_[9], m_[10], m_[12], m_[13], m_[14]);
+        tmat3<T> minor14(m_[0], m_[1], m_[2], m_[12], m_[13], m_[14], m_[4], m_[5], m_[6]);
+        tmat3<T> minor15(m_[0], m_[1], m_[2], m_[4], m_[5], m_[6], m_[8], m_[9], m_[10]);
+        m_[0] = minor0.determinant() / d;
+        m_[1] = minor1.determinant() / d;
+        m_[2] = minor2.determinant() / d;
+        m_[3] = minor3.determinant() / d;
+        m_[4] = minor4.determinant() / d;
+        m_[5] = minor5.determinant() / d;
+        m_[6] = minor6.determinant() / d;
+        m_[7] = minor7.determinant() / d;
+        m_[8] = minor8.determinant() / d;
+        m_[9] = minor9.determinant() / d;
+        m_[10] = minor10.determinant() / d;
+        m_[11] = minor11.determinant() / d;
+        m_[12] = minor12.determinant() / d;
+        m_[13] = minor13.determinant() / d;
+        m_[14] = minor14.determinant() / d;
+        m_[15] = minor15.determinant() / d;
+        return *this;
     }
 
     void print() const
@@ -558,48 +731,73 @@
         static const int precision(6);
         // row 0
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][0];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][1];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][2];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][3];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[4];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[8];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[12];
         std::cout << " |" << std::endl;
         // row 1
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][0];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][1];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][2];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][3];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[5];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[9];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[13];
         std::cout << " |" << std::endl;
         // row 2
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][0];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][1];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][2];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][3];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[6];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[10];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[14];
         std::cout << " |" << std::endl;
         // row 3
         std::cout << "| ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3][0];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3][1];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3][2];
-        std::cout << " ";
-        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3][3];
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[7];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[11];
+        std::cout << " ";
+        std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[15];
         std::cout << " |" << std::endl;
     }
 
     operator const T*() const { return &m_[0];}
 
+    bool operator==(const tmat4& rhs) const
+    {
+        return m_[0] == rhs.m_[0] &&
+               m_[1] == rhs.m_[1] &&
+               m_[2] == rhs.m_[2] &&
+               m_[3] == rhs.m_[3] &&
+               m_[4] == rhs.m_[4] &&
+               m_[5] == rhs.m_[5] &&
+               m_[6] == rhs.m_[6] &&
+               m_[7] == rhs.m_[7] &&
+               m_[8] == rhs.m_[8] &&
+               m_[9] == rhs.m_[9] &&
+               m_[10] == rhs.m_[10] &&
+               m_[11] == rhs.m_[11] &&
+               m_[12] == rhs.m_[12] &&
+               m_[13] == rhs.m_[13] &&
+               m_[14] == rhs.m_[14] &&
+               m_[15] == rhs.m_[15];
+    }
+
+    bool operator!=(const tmat4& rhs) const
+    {
+        return !(*this == rhs);
+    }
+
     tmat4& operator=(const tmat4& rhs)
     {
         if (this != &rhs)

=== renamed file 'src/program.cc' => 'src/libmatrix/program.cc'
--- src/program.cc	2011-06-09 14:50:14 +0000
+++ src/libmatrix/program.cc	2011-06-22 08:59:00 +0000
@@ -1,33 +1,21 @@
-/*
- * Copyright © 2011 Linaro Limited
- *
- * This file is part of glcompbench.
- *
- * glcompbench is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * glcompbench is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with glcompbench.  If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
- *  Jesse Barker <jesse.barker@linaro.org>
- */
-
+//
+// Copyright (c) 2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+//     Jesse Barker - original implementation.
+//     Alexandros Frantzis - local changes for better integration with glcompbench
+//
 #include <string>
 #include <vector>
 #include <sstream>
 #include <fstream>
-
+#include <iostream>
 #include "gl-headers.h"
-
 #include "program.h"
 #include "log.h"
 

=== renamed file 'src/program.h' => 'src/libmatrix/program.h'
--- src/program.h	2011-06-08 16:09:21 +0000
+++ src/libmatrix/program.h	2011-06-22 08:59:00 +0000
@@ -1,26 +1,14 @@
-/*
- * Copyright © 2011 Linaro Limited
- *
- * This file is part of glcompbench.
- *
- * glcompbench is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * glcompbench is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with glcompbench.  If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
- *  Jesse Barker <jesse.barker@linaro.org>
- */
-
+//
+// Copyright (c) 2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+//     Jesse Barker - original implementation.
+//
 #ifndef PROGRAM_H_
 #define PROGRAM_H_
 

=== added directory 'src/libmatrix/test'
=== added file 'src/libmatrix/test/inverse_test.cc'
--- src/libmatrix/test/inverse_test.cc	1970-01-01 00:00:00 +0000
+++ src/libmatrix/test/inverse_test.cc	2011-06-22 08:59:00 +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 'src/libmatrix/test/inverse_test.h'
--- src/libmatrix/test/inverse_test.h	1970-01-01 00:00:00 +0000
+++ src/libmatrix/test/inverse_test.h	2011-06-22 08:59:00 +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_

=== added file 'src/libmatrix/test/libmatrix_test.cc'
--- src/libmatrix/test/libmatrix_test.cc	1970-01-01 00:00:00 +0000
+++ src/libmatrix/test/libmatrix_test.cc	2011-06-22 08:59:00 +0000
@@ -0,0 +1,57 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+//     Jesse Barker - original implementation.
+//
+#include <iostream>
+#include <string>
+#include <vector>
+#include "libmatrix_test.h"
+#include "inverse_test.h"
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+int
+main(int argc, char** argv)
+{
+    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 'src/libmatrix/test/libmatrix_test.h'
--- src/libmatrix/test/libmatrix_test.h	1970-01-01 00:00:00 +0000
+++ src/libmatrix/test/libmatrix_test.h	2011-06-22 08:59:00 +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 'src/libmatrix/test/options.cc'
--- src/libmatrix/test/options.cc	1970-01-01 00:00:00 +0000
+++ src/libmatrix/test/options.cc	2011-06-22 08:59:00 +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;   
+}
+

=== modified file 'src/wscript_build'
--- src/wscript_build	2011-02-07 18:41:00 +0000
+++ src/wscript_build	2011-06-22 08:59:00 +0000
@@ -1,11 +1,3 @@
-bld(
-    features = ['cxx', 'cxxstlib'],
-    source   = bld.path.ant_glob('libmatrix/*.cc'),
-    target   = 'matrix',
-    lib      = ['m'],
-    export_includes = 'libmatrix'
-    )
-
 def is_common(name):
     return name.find('egl') == -1 and name.find('glx') == -1
 
@@ -14,6 +6,28 @@
 glx_sources = ['composite-canvas-glx.cc', 'composite-window-glxpixmap.cc']
 egl_sources = ['composite-canvas-egl.cc', 'composite-window-eglimage.cc']
 
+if bld.env.BUILD_EGL_GL or bld.env.BUILD_GLX:
+    bld(
+        features = ['cxx', 'cxxstlib'],
+        source   = bld.path.ant_glob('libmatrix/*.cc'),
+        target   = 'matrix',
+        lib      = ['m'],
+        includes = ['.'],
+        defines  = ['USE_GL'],
+        export_includes = 'libmatrix'
+        )
+
+if bld.env.BUILD_EGL_ES2:
+    bld(
+        features = ['cxx', 'cxxstlib'],
+        source   = bld.path.ant_glob('libmatrix/*.cc'),
+        target   = 'matrix-es2',
+        lib      = ['m'],
+        includes = ['.'],
+        defines  = ['USE_GLES2'],
+        export_includes = 'libmatrix'
+        )
+
 if bld.env.BUILD_EGL_GL:
     bld(
         features = ['cxx', 'cprogram'],
@@ -31,7 +45,7 @@
         source   = common_sources + egl_sources,
         target   = 'glcompbench-egl-es2',
         uselib   = ['egl', 'glesv2', 'x11', 'xdamage', 'xcomposite'],
-        use      = ['matrix'],
+        use      = ['matrix-es2'],
         lib      = ['m'],
         defines  = ['USE_EGL', 'USE_GLES2']
         )

