Initial import of eigen 3.1.1

Added a README.android and a MODULE_LICENSE_MPL2 file.
Added empty Android.mk and CleanSpec.mk to optimize Android build.
Non MPL2 license code is disabled in ./Eigen/src/Core/util/NonMPL2.h.
Trying to include such files will lead to an error.

Change-Id: I0e148b7c3e83999bcc4dfaa5809d33bfac2aac32
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
new file mode 100644
index 0000000..0d9a631
--- /dev/null
+++ b/scripts/CMakeLists.txt
@@ -0,0 +1,6 @@
+get_property(EIGEN_TESTS_LIST GLOBAL PROPERTY EIGEN_TESTS_LIST)
+configure_file(buildtests.in ${CMAKE_BINARY_DIR}/buildtests.sh @ONLY)
+
+configure_file(check.in ${CMAKE_BINARY_DIR}/check.sh COPYONLY)
+configure_file(debug.in ${CMAKE_BINARY_DIR}/debug.sh COPYONLY)
+configure_file(release.in ${CMAKE_BINARY_DIR}/release.sh COPYONLY)
diff --git a/scripts/buildtests.in b/scripts/buildtests.in
new file mode 100755
index 0000000..7026373
--- /dev/null
+++ b/scripts/buildtests.in
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+if [[ $# != 1 || $1 == *help ]]
+then
+  echo "usage: ./check regexp"
+  echo "  Builds tests matching the regexp."
+  echo "  The EIGEN_MAKE_ARGS environment variable allows to pass args to 'make'."
+  echo "    For example, to launch 5 concurrent builds, use EIGEN_MAKE_ARGS='-j5'"
+  exit 0
+fi
+
+TESTSLIST="@EIGEN_TESTS_LIST@"
+targets_to_make=`echo "$TESTSLIST" | egrep "$1" | xargs echo`
+
+if [ -n "${EIGEN_MAKE_ARGS:+x}" ]
+then
+  make $targets_to_make ${EIGEN_MAKE_ARGS}
+else
+  make $targets_to_make
+fi
+exit $?
+
diff --git a/scripts/check.in b/scripts/check.in
new file mode 100755
index 0000000..a90061a
--- /dev/null
+++ b/scripts/check.in
@@ -0,0 +1,21 @@
+#!/bin/bash
+# check : shorthand for make and ctest -R
+
+if [[ $# != 1 || $1 == *help ]]
+then
+  echo "usage: ./check regexp"
+  echo "  Builds and runs tests matching the regexp."
+  echo "  The EIGEN_MAKE_ARGS environment variable allows to pass args to 'make'."
+  echo "    For example, to launch 5 concurrent builds, use EIGEN_MAKE_ARGS='-j5'"
+  echo "  The EIGEN_CTEST_ARGS environment variable allows to pass args to 'ctest'."
+  echo "    For example, with CTest 2.8, you can use EIGEN_CTEST_ARGS='-j5'."
+  exit 0
+fi
+
+if [ -n "${EIGEN_CTEST_ARGS:+x}" ]
+then
+  ./buildtests.sh "$1" && ctest -R "$1" ${EIGEN_CTEST_ARGS}
+else
+  ./buildtests.sh "$1" && ctest -R "$1"
+fi
+exit $?
diff --git a/scripts/debug.in b/scripts/debug.in
new file mode 100755
index 0000000..d339d3d
--- /dev/null
+++ b/scripts/debug.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+cmake -DCMAKE_BUILD_TYPE=Debug .
diff --git a/scripts/eigen_gen_credits.cpp b/scripts/eigen_gen_credits.cpp
new file mode 100644
index 0000000..f2e8163
--- /dev/null
+++ b/scripts/eigen_gen_credits.cpp
@@ -0,0 +1,232 @@
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <map>
+#include <list>
+
+using namespace std;
+
+// this function takes a line that may contain a name and/or email address,
+// and returns just the name, while fixing the "bad cases".
+std::string contributor_name(const std::string& line)
+{
+  string result;
+
+  // let's first take care of the case of isolated email addresses, like
+  // "[email protected]" entries
+  if(line.find("[email protected]") != string::npos)
+  {
+    return "Mark Borgerding";
+  }
+
+  if(line.find("[email protected]") != string::npos)
+  {
+    return "Guillaume Saupin";
+  }
+
+  // from there on we assume that we have a entry of the form
+  // either:
+  //   Bla bli Blurp
+  // or:
+  //   Bla bli Blurp <[email protected]>
+  
+  size_t position_of_email_address = line.find_first_of('<');
+  if(position_of_email_address != string::npos)
+  {
+    // there is an e-mail address in <...>.
+    
+    // Hauke once committed as "John Smith", fix that.
+    if(line.find("hauke.heibel") != string::npos)
+      result = "Hauke Heibel";
+    else
+    {
+      // just remove the e-mail address
+      result = line.substr(0, position_of_email_address);
+    }
+  }
+  else
+  {
+    // there is no e-mail address in <...>.
+    
+    if(line.find("convert-repo") != string::npos)
+      result = "";
+    else
+      result = line;
+  }
+
+  // remove trailing spaces
+  size_t length = result.length();
+  while(length >= 1 && result[length-1] == ' ') result.erase(--length);
+
+  return result;
+}
+
+// parses hg churn output to generate a contributors map.
+map<string,int> contributors_map_from_churn_output(const char *filename)
+{
+  map<string,int> contributors_map;
+
+  string line;
+  ifstream churn_out;
+  churn_out.open(filename, ios::in);
+  while(!getline(churn_out,line).eof())
+  {
+    // remove the histograms "******" that hg churn may draw at the end of some lines
+    size_t first_star = line.find_first_of('*');
+    if(first_star != string::npos) line.erase(first_star);
+    
+    // remove trailing spaces
+    size_t length = line.length();
+    while(length >= 1 && line[length-1] == ' ') line.erase(--length);
+
+    // now the last space indicates where the number starts
+    size_t last_space = line.find_last_of(' ');
+    
+    // get the number (of changesets or of modified lines for each contributor)
+    int number;
+    istringstream(line.substr(last_space+1)) >> number;
+
+    // get the name of the contributor
+    line.erase(last_space);    
+    string name = contributor_name(line);
+    
+    map<string,int>::iterator it = contributors_map.find(name);
+    // if new contributor, insert
+    if(it == contributors_map.end())
+      contributors_map.insert(pair<string,int>(name, number));
+    // if duplicate, just add the number
+    else
+      it->second += number;
+  }
+  churn_out.close();
+
+  return contributors_map;
+}
+
+// find the last name, i.e. the last word.
+// for "van den Schbling" types of last names, that's not a problem, that's actually what we want.
+string lastname(const string& name)
+{
+  size_t last_space = name.find_last_of(' ');
+  if(last_space >= name.length()-1) return name;
+  else return name.substr(last_space+1);
+}
+
+struct contributor
+{
+  string name;
+  int changedlines;
+  int changesets;
+  string url;
+  string misc;
+  
+  contributor() : changedlines(0), changesets(0) {}
+  
+  bool operator < (const contributor& other)
+  {
+    return lastname(name).compare(lastname(other.name)) < 0;
+  }
+};
+
+void add_online_info_into_contributors_list(list<contributor>& contributors_list, const char *filename)
+{
+  string line;
+  ifstream online_info;
+  online_info.open(filename, ios::in);
+  while(!getline(online_info,line).eof())
+  {
+    string hgname, realname, url, misc;
+    
+    size_t last_bar = line.find_last_of('|');
+    if(last_bar == string::npos) continue;
+    if(last_bar < line.length())
+      misc = line.substr(last_bar+1);
+    line.erase(last_bar);
+    
+    last_bar = line.find_last_of('|');
+    if(last_bar == string::npos) continue;
+    if(last_bar < line.length())
+      url = line.substr(last_bar+1);
+    line.erase(last_bar);
+
+    last_bar = line.find_last_of('|');
+    if(last_bar == string::npos) continue;
+    if(last_bar < line.length())
+      realname = line.substr(last_bar+1);
+    line.erase(last_bar);
+
+    hgname = line;
+    
+    // remove the example line
+    if(hgname.find("MercurialName") != string::npos) continue;
+    
+    list<contributor>::iterator it;
+    for(it=contributors_list.begin(); it != contributors_list.end() && it->name != hgname; ++it)
+    {}
+    
+    if(it == contributors_list.end())
+    {
+      contributor c;
+      c.name = realname;
+      c.url = url;
+      c.misc = misc;
+      contributors_list.push_back(c);
+    }
+    else
+    {
+      it->name = realname;
+      it->url = url;
+      it->misc = misc;
+    }
+  }
+}
+
+int main()
+{
+  // parse the hg churn output files
+  map<string,int> contributors_map_for_changedlines = contributors_map_from_churn_output("churn-changedlines.out");
+  //map<string,int> contributors_map_for_changesets = contributors_map_from_churn_output("churn-changesets.out");
+  
+  // merge into the contributors list
+  list<contributor> contributors_list;
+  map<string,int>::iterator it;
+  for(it=contributors_map_for_changedlines.begin(); it != contributors_map_for_changedlines.end(); ++it)
+  {
+    contributor c;
+    c.name = it->first;
+    c.changedlines = it->second;
+    c.changesets = 0; //contributors_map_for_changesets.find(it->first)->second;
+    contributors_list.push_back(c);
+  }
+  
+  add_online_info_into_contributors_list(contributors_list, "online-info.out");
+  
+  contributors_list.sort();
+  
+  cout << "{| cellpadding=\"5\"\n";
+  cout << "!\n";
+  cout << "! Lines changed\n";
+  cout << "!\n";
+
+  list<contributor>::iterator itc;
+  int i = 0;
+  for(itc=contributors_list.begin(); itc != contributors_list.end(); ++itc)
+  {
+    if(itc->name.length() == 0) continue;
+    if(i%2) cout << "|-\n";
+    else cout << "|- style=\"background:#FFFFD0\"\n";
+    if(itc->url.length())
+      cout << "| [" << itc->url << " " << itc->name << "]\n";
+    else
+      cout << "| " << itc->name << "\n";
+    if(itc->changedlines)
+      cout << "| " << itc->changedlines << "\n";
+    else
+      cout << "| (no information)\n";
+    cout << "| " << itc->misc << "\n";
+    i++;
+  }
+  cout << "|}" << endl;
+}
diff --git a/scripts/eigen_gen_docs b/scripts/eigen_gen_docs
new file mode 100644
index 0000000..921d600
--- /dev/null
+++ b/scripts/eigen_gen_docs
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# configuration
+# You should call this script with USER set as you want, else some default
+# will be used
+USER=${USER:-'orzel'}
+
+#ulimit -v 1024000
+
+# step 1 : build
+mkdir build -p
+(cd build && cmake .. && make doc) || { echo "make failed"; exit 1; }
+
+#step 2 : upload
+# (the '/' at the end of path is very important, see rsync documentation)
+rsync -az --no-p --delete build/doc/html/ [email protected]:eigen/eigen.tuxfamily.org-web/htdocs/dox-devel/ || { echo "upload failed"; exit 1; }
+
+#step 3 : fix the perm
+ssh [email protected] 'chmod -R g+w /home/eigen/eigen.tuxfamily.org-web/htdocs/dox-devel' || { echo "perm failed"; exit 1; }
+
+echo "Uploaded successfully"
+
diff --git a/scripts/release.in b/scripts/release.in
new file mode 100755
index 0000000..db2d9d9
--- /dev/null
+++ b/scripts/release.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+cmake -DCMAKE_BUILD_TYPE=Release .
diff --git a/scripts/relicense.py b/scripts/relicense.py
new file mode 100644
index 0000000..8a5265f
--- /dev/null
+++ b/scripts/relicense.py
@@ -0,0 +1,69 @@
+# This file is part of Eigen, a lightweight C++ template library
+# for linear algebra.
+#
+# Copyright (C) 2012 Keir Mierle <[email protected]>
+#
+# This Source Code Form is subject to the terms of the Mozilla
+# Public License v. 2.0. If a copy of the MPL was not distributed
+# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# Author: [email protected] (Keir Mierle)
+#
+# Make the long-awaited conversion to MPL.
+
+lgpl3_header = '''
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, 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 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen 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 Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+'''
+
+mpl2_header = """
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+"""
+
+import os
+import sys
+
+exclusions = set(['relicense.py'])
+
+def update(text):
+  if text.find(lgpl3_header) == -1:
+    return text, False
+  return text.replace(lgpl3_header, mpl2_header), True
+
+rootdir = sys.argv[1]
+for root, sub_folders, files in os.walk(rootdir):
+    for basename in files:
+        if basename in exclusions:
+          print 'SKIPPED', filename
+          continue
+        filename = os.path.join(root, basename)
+        fo = file(filename)
+        text = fo.read()
+        fo.close()
+
+        text, updated = update(text)
+        if updated:
+          fo = file(filename, "w")
+          fo.write(text)
+          fo.close()
+          print 'UPDATED', filename
+        else:
+          print '       ', filename