Linkloader improvement: mclinker.
Change-Id: I8805e39ccbc2ee204234fb3e71c70c906f3990bb
diff --git a/unittests/BinTreeTest.cpp b/unittests/BinTreeTest.cpp
new file mode 100644
index 0000000..bce4b24
--- /dev/null
+++ b/unittests/BinTreeTest.cpp
@@ -0,0 +1,275 @@
+//===- BinTreeTest.cpp ----------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "BinTreeTest.h"
+
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/MC/MCLDInputTree.h"
+#include <string>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+BinTreeTest::BinTreeTest()
+{
+ // create testee. modify it if need
+ m_pTestee = new BinaryTree<int>();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+BinTreeTest::~BinTreeTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void BinTreeTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void BinTreeTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+
+/// General
+TEST_F( BinTreeTest,Two_non_null_tree_merge)
+{
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+ m_pTestee->join<TreeIteratorBase::Rightward>(pos,0);
+ --pos;
+ m_pTestee->join<TreeIteratorBase::Rightward>(pos,1);
+ m_pTestee->join<TreeIteratorBase::Leftward>(pos,1);
+ --pos;
+ m_pTestee->join<TreeIteratorBase::Rightward>(pos,2);
+ m_pTestee->join<TreeIteratorBase::Leftward>(pos,2);
+
+ BinaryTree<int> *mergeTree = new BinaryTree<int>;
+ BinaryTree<int>::iterator pos2 = mergeTree->root();
+ mergeTree->join<TreeIteratorBase::Rightward>(pos2,1);
+ --pos2;
+ mergeTree->join<TreeIteratorBase::Rightward>(pos2,1);
+ mergeTree->join<TreeIteratorBase::Leftward>(pos2,1);
+
+ m_pTestee->merge<TreeIteratorBase::Rightward>(pos,*mergeTree);
+ delete mergeTree;
+ EXPECT_TRUE(m_pTestee->size()==8);
+}
+
+/// ---- TEST - 2 ----
+TEST_F( BinTreeTest, A_null_tree_merge_a_non_null_tree)
+{
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+
+ BinaryTree<int> *mergeTree = new BinaryTree<int>;
+ mergeTree->join<TreeIteratorBase::Rightward>(pos,0);
+ --pos;
+ mergeTree->join<TreeIteratorBase::Rightward>(pos,1);
+ mergeTree->join<TreeIteratorBase::Leftward>(pos,1);
+ --pos;
+ mergeTree->join<TreeIteratorBase::Rightward>(pos,2);
+ mergeTree->join<TreeIteratorBase::Leftward>(pos,2);
+
+ m_pTestee->merge<TreeIteratorBase::Rightward>(pos,*mergeTree);
+
+ delete mergeTree;
+ EXPECT_TRUE(m_pTestee->size()==5);
+}
+
+TEST_F( BinTreeTest, A_non_null_tree_merge_a_null_tree)
+{
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+ m_pTestee->join<TreeIteratorBase::Rightward>(pos,0);
+ --pos;
+ m_pTestee->join<TreeIteratorBase::Rightward>(pos,1);
+ m_pTestee->join<TreeIteratorBase::Leftward>(pos,1);
+ --pos;
+ m_pTestee->join<TreeIteratorBase::Rightward>(pos,2);
+ m_pTestee->join<TreeIteratorBase::Leftward>(pos,2);
+
+ BinaryTree<int> *mergeTree = new BinaryTree<int>;
+ BinaryTree<int>::iterator pos2 = mergeTree->root();
+ mergeTree->merge<TreeIteratorBase::Rightward>(pos2,*m_pTestee);
+
+ //delete m_pTestee;
+ EXPECT_TRUE(mergeTree->size()==5);
+ delete mergeTree;
+}
+
+TEST_F( BinTreeTest, Two_null_tree_merge)
+{
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+
+ BinaryTree<int> *mergeTree = new BinaryTree<int>;
+ BinaryTree<int>::iterator pos2 = mergeTree->root();
+
+ mergeTree->merge<TreeIteratorBase::Rightward>(pos2,*m_pTestee);
+
+ //delete m_pTestee;
+ EXPECT_TRUE(mergeTree->size()==0);
+ delete mergeTree;
+}
+
+TEST_F( BinTreeTest, DFSIterator_BasicTraversal)
+{
+ int a = 111;
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+
+ m_pTestee->join<InputTree::Inclusive>(pos,a);
+ pos.move<InputTree::Inclusive>();
+ m_pTestee->join<InputTree::Positional>(pos,10);
+ m_pTestee->join<InputTree::Inclusive>(pos,9);
+ pos.move<InputTree::Inclusive>();
+ m_pTestee->join<InputTree::Positional>(pos,8);
+ m_pTestee->join<InputTree::Inclusive>(pos,7);
+
+ BinaryTree<int>::dfs_iterator dfs_it = m_pTestee->dfs_begin();
+ BinaryTree<int>::dfs_iterator dfs_end = m_pTestee->dfs_end();
+
+ ASSERT_EQ(111, **dfs_it);
+ ++dfs_it;
+ ASSERT_EQ(9, **dfs_it);
+ ++dfs_it;
+ ASSERT_EQ(7, **dfs_it);
+ ++dfs_it;
+ ASSERT_EQ(8, **dfs_it);
+ ++dfs_it;
+ ASSERT_EQ(10, **dfs_it);
+ ++dfs_it;
+ ASSERT_TRUE( dfs_it == dfs_end);
+ BinaryTree<int>::bfs_iterator bfs_it = m_pTestee->bfs_begin();
+ BinaryTree<int>::bfs_iterator bfs_end = m_pTestee->bfs_end();
+}
+
+TEST_F( BinTreeTest, DFSIterator_RightMostTree)
+{
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+ m_pTestee->join<InputTree::Inclusive>(pos,0);
+ pos.move<InputTree::Inclusive>();
+ m_pTestee->join<InputTree::Positional>(pos,1);
+ pos.move<InputTree::Positional>();
+ m_pTestee->join<InputTree::Positional>(pos,2);
+ pos.move<InputTree::Positional>();
+ m_pTestee->join<InputTree::Positional>(pos,3);
+ pos.move<InputTree::Positional>();
+ m_pTestee->join<InputTree::Positional>(pos,4);
+
+ BinaryTree<int>::dfs_iterator dfs_it = m_pTestee->dfs_begin();
+ BinaryTree<int>::dfs_iterator dfs_end = m_pTestee->dfs_end();
+
+ ASSERT_EQ(0, **dfs_it);
+ ++dfs_it;
+ ASSERT_EQ(1, **dfs_it);
+ ++dfs_it;
+ ASSERT_EQ(2, **dfs_it);
+ ++dfs_it;
+ ASSERT_EQ(3, **dfs_it);
+ ++dfs_it;
+ ASSERT_EQ(4, **dfs_it);
+ ++dfs_it;
+ ASSERT_TRUE( dfs_it == dfs_end);
+}
+
+
+TEST_F( BinTreeTest, DFSIterator_SingleNode)
+{
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+ m_pTestee->join<InputTree::Inclusive>(pos,0);
+ BinaryTree<int>::dfs_iterator dfs_it = m_pTestee->dfs_begin();
+ BinaryTree<int>::dfs_iterator dfs_end = m_pTestee->dfs_end();
+ int counter = 0;
+ while( dfs_it != dfs_end ) {
+ ++counter;
+ ++dfs_it;
+ }
+ ASSERT_EQ(1, counter);
+}
+
+TEST_F( BinTreeTest, BFSIterator_BasicTraversal)
+{
+ int a = 111;
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+
+ m_pTestee->join<InputTree::Inclusive>(pos,a);
+ pos.move<InputTree::Inclusive>();
+ m_pTestee->join<InputTree::Positional>(pos,10);
+ m_pTestee->join<InputTree::Inclusive>(pos,9);
+ pos.move<InputTree::Inclusive>();
+ m_pTestee->join<InputTree::Positional>(pos,8);
+ m_pTestee->join<InputTree::Inclusive>(pos,7);
+
+ BinaryTree<int>::bfs_iterator bfs_it = m_pTestee->bfs_begin();
+ BinaryTree<int>::bfs_iterator bfs_end = m_pTestee->bfs_end();
+
+ ASSERT_EQ(111, **bfs_it);
+ ++bfs_it;
+ ASSERT_EQ(10, **bfs_it);
+ ++bfs_it;
+ ASSERT_EQ(9, **bfs_it);
+ ++bfs_it;
+ ASSERT_EQ(8, **bfs_it);
+ ++bfs_it;
+ ASSERT_EQ(7, **bfs_it);
+ ++bfs_it;
+ ASSERT_TRUE(bfs_it == bfs_end);
+ bfs_it = m_pTestee->bfs_begin();
+ bfs_end = m_pTestee->bfs_end();
+}
+
+TEST_F( BinTreeTest, BFSIterator_RightMostTree)
+{
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+ m_pTestee->join<InputTree::Inclusive>(pos,0);
+ pos.move<InputTree::Inclusive>();
+ m_pTestee->join<InputTree::Positional>(pos,1);
+ pos.move<InputTree::Positional>();
+ m_pTestee->join<InputTree::Positional>(pos,2);
+ pos.move<InputTree::Positional>();
+ m_pTestee->join<InputTree::Positional>(pos,3);
+ pos.move<InputTree::Positional>();
+ m_pTestee->join<InputTree::Positional>(pos,4);
+
+ BinaryTree<int>::bfs_iterator bfs_it = m_pTestee->bfs_begin();
+ BinaryTree<int>::bfs_iterator bfs_end = m_pTestee->bfs_end();
+
+ ASSERT_EQ(0, **bfs_it);
+ ++bfs_it;
+ ASSERT_EQ(1, **bfs_it);
+ ++bfs_it;
+ ASSERT_EQ(2, **bfs_it);
+ ++bfs_it;
+ ASSERT_EQ(3, **bfs_it);
+ ++bfs_it;
+ ASSERT_EQ(4, **bfs_it);
+ ++bfs_it;
+ ASSERT_TRUE( bfs_it == bfs_end);
+}
+
+
+TEST_F( BinTreeTest, BFSIterator_SingleNode)
+{
+ BinaryTree<int>::iterator pos = m_pTestee->root();
+ m_pTestee->join<InputTree::Inclusive>(pos,0);
+ BinaryTree<int>::bfs_iterator bfs_it = m_pTestee->bfs_begin();
+ BinaryTree<int>::bfs_iterator bfs_end = m_pTestee->bfs_end();
+ int counter = 0;
+ while( bfs_it != bfs_end ) {
+ ++counter;
+ ++bfs_it;
+ }
+ ASSERT_EQ(1, counter);
+}
+
+
diff --git a/unittests/BinTreeTest.h b/unittests/BinTreeTest.h
new file mode 100644
index 0000000..3e8fab4
--- /dev/null
+++ b/unittests/BinTreeTest.h
@@ -0,0 +1,52 @@
+//===- BinTreeTest.h ------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef BINTREE_TEST_H
+#define BINTREE_TEST_H
+
+#include "mcld/ADT/BinTree.h"
+
+#include <gtest.h>
+
+namespace mcld
+{
+class BinTree;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class BinTreeTest
+ * \brief Make sure the interface of BinTree , such as insert , traversal , etc..
+ *
+ * \see BinTree
+ */
+class BinTreeTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ BinTreeTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~BinTreeTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::BinaryTree<int>* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/DirIteratorTest.cpp b/unittests/DirIteratorTest.cpp
new file mode 100644
index 0000000..f319172
--- /dev/null
+++ b/unittests/DirIteratorTest.cpp
@@ -0,0 +1,64 @@
+//===- DirIteratorTest.cpp ------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/Directory.h"
+#include "DirIteratorTest.h"
+#include "errno.h"
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+DirIteratorTest::DirIteratorTest()
+{
+ //FIXME:Some bugs modifies the global value "errno" to non-zero.
+ // This makes readir() failed when daily build system runs unittest
+ // Remove this after fixing those bugs
+ errno = 0;
+
+ // create testee. modify it if need
+ m_pDir = new mcld::sys::fs::Directory(".");
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+DirIteratorTest::~DirIteratorTest()
+{
+ delete m_pDir;
+}
+
+// SetUp() will be called immediately before each test.
+void DirIteratorTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void DirIteratorTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( DirIteratorTest, open_dir ) {
+ ASSERT_TRUE( m_pDir->isGood() );
+
+ Directory::iterator entry = m_pDir->begin();
+ Directory::iterator enEnd = m_pDir->end();
+
+ size_t size = 0;
+ while( entry!=enEnd ) {
+ if (0 != entry.path())
+ size = entry.path()->native().size();
+
+ ++entry;
+ }
+}
+
+
diff --git a/unittests/DirIteratorTest.h b/unittests/DirIteratorTest.h
new file mode 100644
index 0000000..1f6e616
--- /dev/null
+++ b/unittests/DirIteratorTest.h
@@ -0,0 +1,52 @@
+//===- DirIteratorTest.h --------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DIR_ITERATOR_TEST_H
+#define MCLD_DIR_ITERATOR_TEST_H
+
+#include <gtest.h>
+
+namespace mcld {
+namespace sys {
+namespace fs {
+class Directory;
+class DirIterator;
+}
+}
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class DirIteratorTest
+ * \brief
+ *
+ * \see DirIterator
+ */
+class DirIteratorTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ DirIteratorTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~DirIteratorTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+protected:
+ mcld::sys::fs::Directory *m_pDir;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/FactoriesTest.cpp b/unittests/FactoriesTest.cpp
new file mode 100644
index 0000000..9301fb9
--- /dev/null
+++ b/unittests/FactoriesTest.cpp
@@ -0,0 +1,220 @@
+//===- FactoriesTest.cpp --------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <cstdlib>
+#include "FactoriesTest.h"
+#include <string>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+FactoriesTest::FactoriesTest()
+{
+ m_pNodeAlloc = new NodeAlloc();
+ m_pFileAlloc = new FileAlloc();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+FactoriesTest::~FactoriesTest()
+{
+ delete m_pNodeAlloc;
+ delete m_pFileAlloc;
+}
+
+// SetUp() will be called immediately before each test.
+void FactoriesTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void FactoriesTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( FactoriesTest, node_produce ) {
+ NodeAlloc::NodeType* node = m_pNodeAlloc->produce();
+ ASSERT_EQ(1, m_pNodeAlloc->size());
+ ASSERT_FALSE(m_pNodeAlloc->empty());
+ node = m_pNodeAlloc->produce();
+ ASSERT_EQ(2, m_pNodeAlloc->size());
+ ASSERT_FALSE(m_pNodeAlloc->empty());
+ node = m_pNodeAlloc->produce();
+ ASSERT_EQ(3, m_pNodeAlloc->size());
+ ASSERT_FALSE(m_pNodeAlloc->empty());
+}
+
+TEST_F( FactoriesTest, node_iterate ) {
+ NodeAlloc::NodeType* node = 0;
+ for (int i=0 ; i<100; ++i) {
+ node = m_pNodeAlloc->produce();
+ node->data = (int*)malloc(sizeof(int));
+ *(node->data) = i;
+ }
+
+ int counter = 0;
+ NodeAlloc::iterator data = m_pNodeAlloc->begin();
+ NodeAlloc::iterator dEnd = m_pNodeAlloc->end();
+ for (; data!=dEnd; ++data) {
+ ASSERT_EQ(counter, *(*data).data );
+ free((*data).data);
+ (*data).data = 0;
+ ++counter;
+ }
+}
+
+TEST_F( FactoriesTest, node_delegate_empty ) {
+ NodeAlloc::NodeType* node = 0;
+ for (int i=0 ; i<100; ++i) {
+ node = m_pNodeAlloc->produce();
+ node->data = (int*)malloc(sizeof(int));
+ *(node->data) = i;
+ }
+ NodeAlloc* delegatee = new NodeAlloc();
+ m_pNodeAlloc->delegate(*delegatee);
+ ASSERT_EQ(100, m_pNodeAlloc->size());
+ int counter = 0;
+ NodeAlloc::iterator data = m_pNodeAlloc->begin();
+ NodeAlloc::iterator dEnd = m_pNodeAlloc->end();
+ for (; data!=dEnd; ++data) {
+ ASSERT_EQ(counter, *(*data).data );
+ free((*data).data);
+ (*data).data = 0;
+ ++counter;
+ }
+ delete delegatee;
+}
+
+TEST_F( FactoriesTest, node_empty_delegate ) {
+ NodeAlloc::NodeType* node = 0;
+ NodeAlloc* delegatee = new NodeAlloc();
+ for (int i=0 ; i<100; ++i) {
+ node = delegatee->produce();
+ node->data = (int*)malloc(sizeof(int));
+ *(node->data) = i;
+ }
+ m_pNodeAlloc->delegate(*delegatee);
+ ASSERT_EQ(100, m_pNodeAlloc->size());
+ int counter = 0;
+ NodeAlloc::iterator data = m_pNodeAlloc->begin();
+ NodeAlloc::iterator dEnd = m_pNodeAlloc->end();
+ for (; data!=dEnd; ++data) {
+ ASSERT_EQ(counter, *(*data).data );
+ free((*data).data);
+ (*data).data = 0;
+ ++counter;
+ }
+ ASSERT_EQ(0, delegatee->size());
+ ASSERT_TRUE(delegatee->empty());
+ delete delegatee;
+}
+
+TEST_F( FactoriesTest, node_delegate ) {
+ NodeAlloc::NodeType* node = 0;
+ NodeAlloc* delegatee = new NodeAlloc();
+ int counter = 0;
+ // produce agent
+ for (int i=0 ; i<100; ++i) {
+ node = m_pNodeAlloc->produce();
+ node->data = (int*)malloc(sizeof(int));
+ *(node->data) = counter;
+ ++counter;
+ }
+
+ // produce delegatee
+ for (int i=0 ; i<100; ++i) {
+ node = delegatee->produce();
+ node->data = (int*)malloc(sizeof(int));
+ *(node->data) = counter;
+ ++counter;
+ }
+
+ m_pNodeAlloc->delegate(*delegatee);
+ ASSERT_EQ(200, m_pNodeAlloc->size());
+ ASSERT_FALSE(m_pNodeAlloc->empty());
+ NodeAlloc::iterator data = m_pNodeAlloc->begin();
+ NodeAlloc::iterator dEnd = m_pNodeAlloc->end();
+ for ( counter = 0; data!=dEnd; ++data) {
+ ASSERT_EQ(counter, *(*data).data );
+ free((*data).data);
+ (*data).data = 0;
+ ++counter;
+ }
+ ASSERT_EQ(0, delegatee->size());
+ ASSERT_TRUE(delegatee->empty());
+ delete delegatee;
+}
+
+TEST_F( FactoriesTest, node_delegate_self ) {
+ NodeAlloc::NodeType* node = 0;
+ for (int i=0 ; i<100; ++i) {
+ node = m_pNodeAlloc->produce();
+ node->data = (int*)malloc(sizeof(int));
+ *(node->data) = i;
+ }
+ ASSERT_EQ(100, m_pNodeAlloc->size());
+ m_pNodeAlloc->delegate(*m_pNodeAlloc);
+ ASSERT_EQ(100, m_pNodeAlloc->size());
+ ASSERT_FALSE(m_pNodeAlloc->empty());
+}
+
+TEST_F( FactoriesTest, file_produce ) {
+ int counter = 0;
+ for (counter=1; counter<1000; ++counter) {
+ MCLDFile* file = m_pFileAlloc->produce();
+ ASSERT_EQ(counter, m_pFileAlloc->size());
+ ASSERT_FALSE(m_pFileAlloc->empty());
+ }
+}
+
+TEST_F( FactoriesTest, file_produce_by_params ) {
+ int counter = 0;
+ for (counter=1; counter<1000; ++counter) {
+ char name[100];
+ sprintf(name, "file %d", counter);
+ char path_name[100];
+ sprintf(path_name, "/proj/mtk%d", counter);
+ MCLDFile* file = m_pFileAlloc->produce( string(name),
+ sys::fs::Path(string(path_name)),
+ MCLDFile::Archive);
+ ASSERT_EQ(counter, m_pFileAlloc->size());
+ ASSERT_FALSE(m_pFileAlloc->empty());
+ ASSERT_TRUE(file->isRecognized());
+ ASSERT_STREQ(name, file->name().data());
+ }
+}
+
+TEST_F( FactoriesTest, file_iterate ) {
+ int counter = 0;
+ for (counter=1; counter<1000; ++counter) {
+ char name[100];
+ sprintf(name, "file %d", counter);
+ char path_name[100];
+ sprintf(path_name, "/proj/mtk%d", counter);
+ MCLDFile* file = m_pFileAlloc->produce( string(name),
+ sys::fs::Path(string(path_name)),
+ MCLDFile::Archive);
+ }
+
+ ASSERT_EQ(counter-1, m_pFileAlloc->size());
+ ASSERT_FALSE(m_pFileAlloc->empty());
+
+ MCLDFileFactory::iterator file = m_pFileAlloc->begin();
+ MCLDFileFactory::iterator fEnd = m_pFileAlloc->end();
+
+ while (file!=fEnd) {
+ ASSERT_TRUE((*file).isRecognized());
+ ASSERT_FALSE((*file).name().empty());
+ ++file;
+ }
+}
+
diff --git a/unittests/FactoriesTest.h b/unittests/FactoriesTest.h
new file mode 100644
index 0000000..ee7badf
--- /dev/null
+++ b/unittests/FactoriesTest.h
@@ -0,0 +1,49 @@
+//===- FactoriesTest.h ----------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef FACTORIES_TEST_H
+#define FACTORIES_TEST_H
+#include <gtest.h>
+#include "mcld/ADT/TreeAllocator.h"
+#include "mcld/MC/MCLDFile.h"
+
+namespace mcldtest
+{
+
+/** \class FactoriesTest
+ * \brief Test cases for factories - NodeFactory and MCLDFileFactory.
+ *
+ * \see Factories
+ */
+class FactoriesTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ FactoriesTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~FactoriesTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ typedef mcld::NodeFactory<int> NodeAlloc;
+ typedef mcld::MCLDFileFactory FileAlloc;
+protected:
+ NodeAlloc* m_pNodeAlloc;
+ FileAlloc *m_pFileAlloc;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/GCFactoryListTraitsTest.cpp b/unittests/GCFactoryListTraitsTest.cpp
new file mode 100644
index 0000000..e99d42c
--- /dev/null
+++ b/unittests/GCFactoryListTraitsTest.cpp
@@ -0,0 +1,123 @@
+//===- GCFactoryListTraitsTest.cpp ----------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "GCFactoryListTraitsTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+// Constructor can do set-up work for all test here.
+GCFactoryListTraitsTest::GCFactoryListTraitsTest()
+{
+ // Allocate the nodes.
+ m_pNodesAlloc = new Node* [10];
+#define ALLOCATE_NODE(i) m_pNodesAlloc[(i)] = m_NodeFactory.produce(i);
+ ALLOCATE_NODE(0);
+ ALLOCATE_NODE(1);
+ ALLOCATE_NODE(2);
+ ALLOCATE_NODE(3);
+ ALLOCATE_NODE(4);
+ ALLOCATE_NODE(5);
+ ALLOCATE_NODE(6);
+ ALLOCATE_NODE(7);
+ ALLOCATE_NODE(8);
+ ALLOCATE_NODE(9);
+#undef ALLOCATE_NODE
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+GCFactoryListTraitsTest::~GCFactoryListTraitsTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void GCFactoryListTraitsTest::SetUp()
+{
+ // Reset the node value and (re)insert into the iplist.
+ for (unsigned i = 0; i < 10; i++) {
+ m_pNodesAlloc[i]->setValue(m_pNodesAlloc[i]->getInitialValue());
+ m_pNodeList.push_back(m_pNodesAlloc[i]);
+ }
+}
+
+// TearDown() will be called immediately after each test.
+void GCFactoryListTraitsTest::TearDown()
+{
+ // Erasing of llvm::iplist won't destroy the allocation of the nodes managed
+ // by the GCFactory (i.e., NodeFactory.)
+ m_pNodeList.clear();
+}
+
+//==========================================================================//
+// Testcases
+//
+
+#define CHECK_NODE_VALUE(v_) do { \
+ ASSERT_EQ(v_, it->getValue()); \
+ it++; \
+} while (false)
+
+#define CHECK_LIST_VALUE(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) do { \
+ llvm::iplist<Node>::const_iterator it = m_pNodeList.begin(); \
+ CHECK_NODE_VALUE(v1); \
+ CHECK_NODE_VALUE(v2); \
+ CHECK_NODE_VALUE(v3); \
+ CHECK_NODE_VALUE(v4); \
+ CHECK_NODE_VALUE(v5); \
+ CHECK_NODE_VALUE(v6); \
+ CHECK_NODE_VALUE(v7); \
+ CHECK_NODE_VALUE(v8); \
+ CHECK_NODE_VALUE(v9); \
+ CHECK_NODE_VALUE(v10); \
+} while (false)
+
+TEST_F( GCFactoryListTraitsTest, Basic) {
+ ASSERT_EQ(10, m_pNodeList.size());
+ CHECK_LIST_VALUE(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+}
+
+TEST_F( GCFactoryListTraitsTest, BasicAgain) {
+ ASSERT_EQ(10, m_pNodeList.size());
+ CHECK_LIST_VALUE(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+}
+
+TEST_F( GCFactoryListTraitsTest, Clear) {
+ m_pNodeList.clear();
+ ASSERT_EQ(0, m_pNodeList.size());
+}
+
+TEST_F( GCFactoryListTraitsTest, PushThenPop) {
+ Node *NewNode = m_NodeFactory.produce(11);
+ m_pNodeList.push_back(NewNode);
+ ASSERT_EQ(11, m_pNodeList.size());
+ m_pNodeList.pop_back();
+ ASSERT_EQ(10, m_pNodeList.size());
+}
+
+TEST_F( GCFactoryListTraitsTest, CodeIterator) {
+ // to test whether there's compilation error for const template
+ for (llvm::iplist<Node>::const_iterator I = m_pNodeList.begin(),
+ E = m_pNodeList.end(); I != E; I++)
+ I->getValue();
+}
+
+TEST_F( GCFactoryListTraitsTest, Empty) {
+ ASSERT_FALSE(m_pNodeList.empty());
+ m_pNodeList.clear();
+ ASSERT_TRUE(m_pNodeList.empty());
+}
+
+TEST_F( GCFactoryListTraitsTest, EraseAndSize) {
+ ASSERT_FALSE(m_pNodeList.empty());
+ m_pNodeList.erase(m_pNodeList.begin());
+ m_pNodeList.erase(m_pNodeList.begin());
+ ASSERT_TRUE(m_pNodeList.size() == 8);
+}
+
+#undef CHECK_LIST_VALUE
+#undef CHECK_NODE_VALUE
diff --git a/unittests/GCFactoryListTraitsTest.h b/unittests/GCFactoryListTraitsTest.h
new file mode 100644
index 0000000..7067907
--- /dev/null
+++ b/unittests/GCFactoryListTraitsTest.h
@@ -0,0 +1,98 @@
+//===- GCFactoryListTraitsTest.h ------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GC_FACTORY_LIST_TRAITS_TEST_H
+#define MCLD_GC_FACTORY_LIST_TRAITS_TEST_H
+
+#include <gtest.h>
+
+#include <mcld/Support/GCFactoryListTraits.h>
+
+#include <llvm/ADT/ilist_node.h>
+
+#include <mcld/Support/GCFactory.h>
+
+namespace mcldtest
+{
+
+/** \class GCFactoryListTraitsTest
+ * \brief
+ *
+ * \see GCFactoryListTraits
+ */
+class GCFactoryListTraitsTest : public ::testing::Test
+{
+public:
+ /** \class GCFactoryListTraitsTest
+ * \brief Node used in the test
+ *
+ */
+ class NodeFactory;
+
+ class Node : public llvm::ilist_node<Node>
+ {
+ friend class NodeFactory;
+ private:
+ unsigned m_Init;
+ unsigned m_Value;
+
+ private:
+ Node(unsigned pInit) : m_Init(pInit), m_Value(pInit) { }
+
+ public:
+ unsigned getInitialValue() const {
+ return m_Init;
+ }
+
+ inline unsigned getValue() const
+ { return m_Value; }
+
+ inline void setValue(unsigned pValue)
+ { m_Value = pValue; }
+ };
+
+ class NodeFactory : public mcld::GCFactory<Node, 0> {
+ public:
+ NodeFactory() : mcld::GCFactory<Node, 0>(16) { }
+
+ Node *produce(unsigned pInit) {
+ Node *result = allocate();
+ new (result) Node(pInit);
+ return result;
+ }
+ };
+
+ // Constructor can do set-up work for all test here.
+ GCFactoryListTraitsTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~GCFactoryListTraitsTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+ const llvm::iplist<Node, mcld::GCFactoryListTraits<Node> > &getNodeList() const
+ { return m_pNodeList; }
+
+ llvm::iplist<Node, mcld::GCFactoryListTraits<Node> > &getNodeList()
+ { return m_pNodeList; }
+
+protected:
+ NodeFactory m_NodeFactory;
+ Node **m_pNodesAlloc;
+
+ llvm::iplist<Node, mcld::GCFactoryListTraits<Node> > m_pNodeList;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/HashTableTest.cpp b/unittests/HashTableTest.cpp
new file mode 100644
index 0000000..4106641
--- /dev/null
+++ b/unittests/HashTableTest.cpp
@@ -0,0 +1,327 @@
+//===- HashTableTest.cpp --------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HashTableTest.h"
+#include "mcld/ADT/HashEntry.h"
+#include "mcld/ADT/HashTable.h"
+#include <cstdlib>
+
+using namespace std;
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+HashTableTest::HashTableTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+HashTableTest::~HashTableTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void HashTableTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void HashTableTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+struct IntCompare
+{
+ bool operator()(int X, int Y) const
+ { return (X==Y); }
+};
+
+struct PtrCompare
+{
+ bool operator()(const int* X, const int* Y) const
+ { return (X==Y); }
+};
+
+struct PtrHash
+{
+ size_t operator()(const int* pKey) const
+ {
+ return (unsigned((uintptr_t)pKey) >> 4) ^
+ (unsigned((uintptr_t)pKey) >> 9);
+ }
+};
+
+struct IntHash
+{
+ size_t operator()(int pKey) const
+ { return pKey; }
+};
+
+struct IntMod3Hash
+{
+ size_t operator()(int pKey) const
+ { return pKey % 3; }
+};
+
+TEST_F( HashTableTest, ptr_entry ) {
+ int A = 1;
+ int* pA = &A;
+
+ typedef HashEntry<int*, int, PtrCompare> HashEntryType;
+ typedef HashTable<HashEntryType, PtrHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy(0);
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+
+ entry = hashTable->insert(pA, exist);
+
+ EXPECT_FALSE(hashTable->empty());
+
+ HashTableTy::iterator iter;
+ iter = hashTable->find(NULL);
+ EXPECT_TRUE(iter==hashTable->end());
+ delete hashTable;
+}
+
+TEST_F( HashTableTest, constructor ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > hashTable(16);
+ EXPECT_EQ(17, hashTable.numOfBuckets());
+ EXPECT_TRUE(hashTable.empty());
+ EXPECT_EQ(0, hashTable.numOfEntries());
+}
+
+TEST_F( HashTableTest, allocattion ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy(22);
+
+ bool exist;
+ int key = 100;
+ HashTableTy::entry_type* val = hashTable->insert(key, exist);
+ val->setValue(999);
+ EXPECT_FALSE(hashTable->empty());
+ EXPECT_FALSE(exist);
+ EXPECT_FALSE(NULL == val);
+ HashTableTy::iterator entry = hashTable->find(key);
+ EXPECT_EQ(999, entry.getEntry()->value());
+ delete hashTable;
+}
+
+TEST_F( HashTableTest, alloc100 ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy(22);
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+ for (unsigned int key=0; key<100; ++key) {
+ entry = hashTable->insert(key, exist);
+ EXPECT_FALSE(hashTable->empty());
+ EXPECT_FALSE(exist);
+ EXPECT_FALSE(NULL == entry);
+ EXPECT_EQ(key, entry->key());
+ entry->setValue(key+10);
+ }
+
+ EXPECT_FALSE(hashTable->empty());
+ EXPECT_EQ(100, hashTable->numOfEntries());
+ EXPECT_EQ(197, hashTable->numOfBuckets());
+ delete hashTable;
+}
+
+TEST_F( HashTableTest, erase100 ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy(0);
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+ for (unsigned int key=0; key<100; ++key)
+ entry = hashTable->insert(key, exist);
+
+ EXPECT_FALSE(hashTable->empty());
+
+ int count;
+ HashTableTy::iterator iter;
+ for (unsigned int key=0; key<100; ++key) {
+ count = hashTable->erase(key);
+ EXPECT_EQ(1, count);
+ iter = hashTable->find(key);
+ EXPECT_TRUE(iter == hashTable->end());
+ }
+
+ EXPECT_TRUE(hashTable->empty());
+ delete hashTable;
+}
+
+TEST_F( HashTableTest, clear) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy(22);
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+ for (unsigned int key=0; key<100; ++key) {
+ entry = hashTable->insert(key, exist);
+ }
+
+ hashTable->clear();
+
+ int count;
+ HashTableTy::iterator iter;
+ for (unsigned int key=0; key<100; ++key) {
+ iter = hashTable->find(key);
+ EXPECT_TRUE(iter == hashTable->end());
+ }
+
+ EXPECT_TRUE(hashTable->empty());
+ delete hashTable;
+}
+
+TEST_F( HashTableTest, tombstone ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, IntMod3Hash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy();
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+ for (unsigned int key=0; key<100; ++key) {
+ entry = hashTable->insert(key, exist);
+ }
+ EXPECT_FALSE(hashTable->empty());
+
+ int count;
+ HashTableTy::iterator iter;
+ for (unsigned int key=0; key<20; ++key) {
+ count = hashTable->erase(key);
+ EXPECT_EQ(1, count);
+ iter = hashTable->find(key);
+ EXPECT_TRUE(iter == hashTable->end());
+ }
+ EXPECT_EQ(80, hashTable->numOfEntries());
+
+ for (unsigned int key=20; key<100; ++key) {
+ iter = hashTable->find(key);
+ EXPECT_TRUE(iter != hashTable->end());
+ }
+
+ for (unsigned int key=0; key<20; ++key) {
+ entry = hashTable->insert(key, exist);
+ }
+ EXPECT_EQ(100, hashTable->numOfEntries());
+ EXPECT_EQ(197, hashTable->numOfBuckets());
+
+ delete hashTable;
+}
+
+TEST_F( HashTableTest, rehash_test ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy(0);
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+ for (unsigned int key=0; key<400000; ++key) {
+ entry = hashTable->insert(key, exist);
+ entry->setValue(key+10);
+ }
+
+ HashTableTy::iterator iter;
+ for (unsigned int key=0; key<400000; ++key) {
+ iter = hashTable->find(key);
+ EXPECT_EQ((key+10), iter.getEntry()->value());
+ }
+
+ delete hashTable;
+}
+
+TEST_F( HashTableTest, bucket_iterator ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy(0);
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+ for (unsigned int key=0; key<400000; ++key) {
+ entry = hashTable->insert(key, exist);
+ entry->setValue(key+10);
+ }
+
+ HashTableTy::iterator iter, iEnd = hashTable->end();
+ unsigned int counter = 0;
+ for (iter = hashTable->begin(); iter != iEnd; ++iter) {
+ EXPECT_EQ(iter.getEntry()->key()+10, iter.getEntry()->value());
+ ++counter;
+ }
+ EXPECT_EQ(400000, counter);
+ delete hashTable;
+}
+
+
+TEST_F( HashTableTest, chain_iterator_single ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy();
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+ for (unsigned int key=0; key<16; ++key) {
+ entry = hashTable->insert(key*37, exist);
+ entry->setValue(key+10);
+ }
+ for (unsigned int key=0; key<16; ++key) {
+ unsigned int counter = 0;
+ HashTableTy::chain_iterator iter, iEnd = hashTable->end(key*37);
+ for (iter = hashTable->begin(key*37); iter != iEnd; ++iter) {
+ EXPECT_EQ(key+10, iter.getEntry()->value());
+ ++counter;
+ }
+ EXPECT_EQ(1, counter);
+ }
+ delete hashTable;
+}
+
+struct FixHash
+{
+ size_t operator()(int pKey) const {
+ return 10;
+ }
+};
+
+
+TEST_F( HashTableTest, chain_iterator_list ) {
+ typedef HashEntry<int, int, IntCompare> HashEntryType;
+ typedef HashTable<HashEntryType, FixHash, EntryFactory<HashEntryType> > HashTableTy;
+ HashTableTy *hashTable = new HashTableTy();
+
+ bool exist;
+ HashTableTy::entry_type* entry = 0;
+ for (unsigned int key=0; key<16; ++key) {
+ entry = hashTable->insert(key, exist);
+ ASSERT_FALSE(exist);
+ entry->setValue(key);
+ }
+ ASSERT_EQ(16, hashTable->numOfEntries());
+ ASSERT_EQ(37, hashTable->numOfBuckets());
+
+ unsigned int key = 0;
+ unsigned int count = 0;
+ HashTableTy::chain_iterator iter, iEnd = hashTable->end(key);
+ for (iter = hashTable->begin(key); iter != iEnd; ++iter) {
+ count++;
+ }
+ ASSERT_EQ(16, count);
+ delete hashTable;
+}
diff --git a/unittests/HashTableTest.h b/unittests/HashTableTest.h
new file mode 100644
index 0000000..4bf2c50
--- /dev/null
+++ b/unittests/HashTableTest.h
@@ -0,0 +1,42 @@
+//===- HashTableTest.h ----------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_HASH_TABLE_TEST_H
+#define MCLD_HASH_TABLE_TEST_H
+
+#include <gtest.h>
+
+namespace mcldtest
+{
+
+/** \class HashTableTest
+ * \brief Testcase for HashTable
+ *
+ * \see HashTable
+ */
+class HashTableTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ HashTableTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~HashTableTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/InputTreeTest.cpp b/unittests/InputTreeTest.cpp
new file mode 100644
index 0000000..060eaad
--- /dev/null
+++ b/unittests/InputTreeTest.cpp
@@ -0,0 +1,143 @@
+//===- InputTreeTest.cpp --------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDInputTree.h"
+#include "mcld/MC/MCLDInfo.h"
+#include <InputTreeTest.h>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+InputTreeTest::InputTreeTest()
+{
+ // create testee. modify it if need
+ m_pAttr = new mcld::AttributeFactory(2);
+ m_pAlloc = new mcld::InputFactory(10, *m_pAttr);
+ m_pTestee = new InputTree(*m_pAlloc);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+InputTreeTest::~InputTreeTest()
+{
+ delete m_pTestee;
+ delete m_pAlloc;
+ delete m_pAttr;
+}
+
+// SetUp() will be called immediately before each test.
+void InputTreeTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void InputTreeTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( InputTreeTest, Basic_operation ) {
+ InputTree::iterator node = m_pTestee->root();
+ m_pTestee->insert<InputTree::Inclusive>(node, "FileSpec", "path1");
+
+ InputTree::const_iterator const_node = node;
+
+ ASSERT_TRUE(isGroup(node));
+ ASSERT_TRUE(isGroup(const_node));
+ ASSERT_TRUE(m_pTestee->hasInput());
+ ASSERT_EQ(1, m_pTestee->numOfInputs());
+
+ --node;
+
+ m_pTestee->enterGroup(node, InputTree::Downward);
+
+ InputTree::const_iterator const_node2 = node;
+
+ ASSERT_FALSE(node.isRoot());
+
+ ASSERT_FALSE(isGroup(node));
+ ASSERT_FALSE(isGroup(const_node2));
+ ASSERT_TRUE(m_pTestee->hasInput());
+ ASSERT_FALSE(m_pTestee->numOfInputs()==0);
+
+ ASSERT_TRUE(m_pTestee->size()==2);
+}
+
+TEST_F( InputTreeTest, forLoop_TEST ) {
+ InputTree::iterator node = m_pTestee->root();
+
+
+ m_pTestee->insert<InputTree::Inclusive>(node, "FileSpec", "path1");
+ InputTree::const_iterator const_node = node;
+ --node;
+
+ for(int i=0 ; i<100 ; ++i)
+ {
+ m_pTestee->insert<InputTree::Inclusive>(node,"FileSpec", "path1");
+ ++node;
+ }
+
+ m_pTestee->enterGroup(node, InputTree::Downward);
+ --node;
+
+ ASSERT_FALSE(node.isRoot());
+ ASSERT_TRUE(isGroup(node));
+ ASSERT_TRUE(m_pTestee->hasInput());
+ ASSERT_FALSE(m_pTestee->numOfInputs()==100);
+
+ ASSERT_TRUE(m_pTestee->size()==102);
+}
+
+TEST_F( InputTreeTest, Nesting_Case ) {
+ InputTree::iterator node = m_pTestee->root();
+
+ for(int i=0 ; i<50 ; ++i)
+ {
+ m_pTestee->enterGroup(node, InputTree::Downward);
+ --node;
+
+ m_pTestee->insert(node, InputTree::Afterward, "FileSpec", "path1");
+ ++node;
+ }
+
+ ASSERT_FALSE(node.isRoot());
+ ASSERT_FALSE(isGroup(node));
+ ASSERT_TRUE(m_pTestee->hasInput());
+ ASSERT_TRUE(m_pTestee->numOfInputs()==50);
+ ASSERT_TRUE(m_pTestee->size()==100);
+}
+
+TEST_F( InputTreeTest, DFSIterator_BasicTraversal)
+{
+
+ InputTree::iterator node = m_pTestee->root();
+ m_pTestee->insert<InputTree::Inclusive>(node, "111", "/");
+ node.move<InputTree::Inclusive>();
+
+ m_pTestee->insert<InputTree::Positional>(node, "10", "/");
+ m_pTestee->enterGroup<InputTree::Inclusive>(node);
+ node.move<InputTree::Inclusive>();
+ m_pTestee->insert<InputTree::Inclusive>(node, "7", "/");
+ m_pTestee->insert<InputTree::Positional>(node, "8", "/");
+
+ InputTree::dfs_iterator dfs_it = m_pTestee->dfs_begin();
+ InputTree::dfs_iterator dfs_end = m_pTestee->dfs_end();
+ ASSERT_STREQ("111", (*dfs_it)->name().c_str());
+ ++dfs_it;
+ ASSERT_STREQ("7", (**dfs_it).name().c_str());
+ ++dfs_it;
+ ASSERT_STREQ("8", (**dfs_it).name().c_str());
+ ++dfs_it;
+ ASSERT_STREQ("10", (**dfs_it).name().c_str());
+ ++dfs_it;
+ ASSERT_TRUE(dfs_it == dfs_end);
+}
+
diff --git a/unittests/InputTreeTest.h b/unittests/InputTreeTest.h
new file mode 100644
index 0000000..2ffef9c
--- /dev/null
+++ b/unittests/InputTreeTest.h
@@ -0,0 +1,54 @@
+//===- InputTreeTest.h ----------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef INPUTTREE_TEST_H
+#define INPUTTREE_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class InputTree;
+class InputFactory;
+class AttributeFactory;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class InputTreeTest
+ * \brief
+ *
+ * \see InputTree
+ */
+class InputTreeTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ InputTreeTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~InputTreeTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::AttributeFactory *m_pAttr;
+ mcld::InputFactory *m_pAlloc;
+ mcld::InputTree* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/LDSymbolTest.cpp b/unittests/LDSymbolTest.cpp
new file mode 100644
index 0000000..c414fa0
--- /dev/null
+++ b/unittests/LDSymbolTest.cpp
@@ -0,0 +1,42 @@
+//===- LDSymbolTest.cpp ---------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mcld/LD/LDSymbol.h"
+#include "LDSymbolTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+LDSymbolTest::LDSymbolTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+LDSymbolTest::~LDSymbolTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void LDSymbolTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void LDSymbolTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( LDSymbolTest, produce ) {
+}
+
diff --git a/unittests/LDSymbolTest.h b/unittests/LDSymbolTest.h
new file mode 100644
index 0000000..43d6b8a
--- /dev/null
+++ b/unittests/LDSymbolTest.h
@@ -0,0 +1,46 @@
+//===- LDSymbolTest.h -----------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LDSYMBOL_TEST_H
+#define LDSYMBOL_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class LDSymbol;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class LDSymbolTest
+ */
+class LDSymbolTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ LDSymbolTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~LDSymbolTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/LEB128Test.cpp b/unittests/LEB128Test.cpp
new file mode 100644
index 0000000..1f1467f
--- /dev/null
+++ b/unittests/LEB128Test.cpp
@@ -0,0 +1,531 @@
+//===- implTest.cpp -------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Support/LEB128.h>
+#include "LEB128Test.h"
+
+#include <ctime>
+#include <cstdlib>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+LEB128Test::LEB128Test()
+{
+ // Initialize the seed for random number generator using during the tests.
+ ::srandom(::time(NULL));
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+LEB128Test::~LEB128Test()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void LEB128Test::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void LEB128Test::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F( LEB128Test, EncodeULEB_Example_from_Dwarf3_Figure22_Using_32bits) {
+ leb128::ByteType buffer[2];
+ leb128::ByteType *result;
+ size_t size;
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 2);
+ ASSERT_EQ(buffer[0], 2);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 127);
+ ASSERT_EQ(buffer[0], 127);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 128);
+ ASSERT_EQ(buffer[0], 0 + 0x80);
+ ASSERT_EQ(buffer[1], 1);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 129);
+ ASSERT_EQ(buffer[0], 1 + 0x80);
+ ASSERT_EQ(buffer[1], 1);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 130);
+ ASSERT_EQ(buffer[0], 2 + 0x80);
+ ASSERT_EQ(buffer[1], 1);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 12857);
+ ASSERT_EQ(buffer[0], 57 + 0x80);
+ ASSERT_EQ(buffer[1], 100);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+}
+
+TEST_F( LEB128Test, EncodeULEB_Example_from_Dwarf3_Figure22_Using_64bits) {
+ leb128::ByteType buffer[2];
+ leb128::ByteType *result;
+ size_t size;
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 2);
+ ASSERT_EQ(buffer[0], 2);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 127);
+ ASSERT_EQ(buffer[0], 127);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 128);
+ ASSERT_EQ(buffer[0], 0 + 0x80);
+ ASSERT_EQ(buffer[1], 1);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 129);
+ ASSERT_EQ(buffer[0], 1 + 0x80);
+ ASSERT_EQ(buffer[1], 1);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 130);
+ ASSERT_EQ(buffer[0], 2 + 0x80);
+ ASSERT_EQ(buffer[1], 1);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 12857);
+ ASSERT_EQ(buffer[0], 57 + 0x80);
+ ASSERT_EQ(buffer[1], 100);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+}
+
+TEST_F( LEB128Test, EncodeSLEB_Example_from_Dwarf3_Figure22) {
+ leb128::ByteType buffer[2];
+ leb128::ByteType *result;
+ size_t size;
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, 2);
+ ASSERT_EQ(buffer[0], 2);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, -2);
+ ASSERT_EQ(buffer[0], 0x7e);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, 127);
+ ASSERT_EQ(buffer[0], 127 + 0x80);
+ ASSERT_EQ(buffer[1], 0);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, -127);
+ ASSERT_EQ(buffer[0], 1 + 0x80);
+ ASSERT_EQ(buffer[1], 0x7f);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, 128);
+ ASSERT_EQ(buffer[0], 0 + 0x80);
+ ASSERT_EQ(buffer[1], 1);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, -128);
+ ASSERT_EQ(buffer[0], 0 + 0x80);
+ ASSERT_EQ(buffer[1], 0x7f);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, 129);
+ ASSERT_EQ(buffer[0], 1 + 0x80);
+ ASSERT_EQ(buffer[1], 1);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, -129);
+ ASSERT_EQ(buffer[0], 0x7f + 0x80);
+ ASSERT_EQ(buffer[1], 0x7e);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+}
+
+TEST_F( LEB128Test, DecodeULEB_Example_from_Dwarf3_Figure22) {
+ leb128::ByteType buffer[2];
+ size_t size;
+
+ buffer[0] = 2;
+ buffer[1] = 0;
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 2);
+ ASSERT_EQ(size, 1);
+
+ buffer[0] = 127;
+ buffer[1] = 0;
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 127);
+ ASSERT_EQ(size, 1);
+
+ buffer[0] = 0 + 0x80;
+ buffer[1] = 1;
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 128);
+ ASSERT_EQ(size, 2);
+
+ buffer[0] = 1 + 0x80;
+ buffer[1] = 1;
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 129);
+ ASSERT_EQ(size, 2);
+
+ buffer[0] = 2 + 0x80;
+ buffer[1] = 1;
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 130);
+ ASSERT_EQ(size, 2);
+
+ buffer[0] = 57 + 0x80;
+ buffer[1] = 100;
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 12857);
+ ASSERT_EQ(size, 2);
+
+}
+
+TEST_F( LEB128Test, DecodeSLEB_Example_from_Dwarf3_Figure22) {
+ leb128::ByteType buffer[2];
+ size_t size;
+
+ buffer[0] = 2;
+ buffer[1] = 0;
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, size), 2);
+ ASSERT_EQ(size, 1);
+
+ buffer[0] = 0x7e;
+ buffer[1] = 0;
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, size), -2);
+ ASSERT_EQ(size, 1);
+
+ buffer[0] = 127 + 0x80;
+ buffer[1] = 0;
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, size), 127);
+ ASSERT_EQ(size, 2);
+
+ buffer[0] = 1 + 0x80;
+ buffer[1] = 0x7f;
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, size), -127);
+ ASSERT_EQ(size, 2);
+
+ buffer[0] = 0 + 0x80;
+ buffer[1] = 1;
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, size), 128);
+ ASSERT_EQ(size, 2);
+
+ buffer[0] = 0 + 0x80;
+ buffer[1] = 0x7f;
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, size), -128);
+ ASSERT_EQ(size, 2);
+
+ buffer[0] = 1 + 0x80;
+ buffer[1] = 1;
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, size), 129);
+ ASSERT_EQ(size, 2);
+
+ buffer[0] = 0x7f + 0x80;
+ buffer[1] = 0x7e;
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, size), -129);
+ ASSERT_EQ(size, 2);
+}
+
+TEST_F( LEB128Test, DecodeULEB_Tests_Found_in_Android_dalvik_dx) {
+ leb128::ByteType content[2];
+ const leb128::ByteType *p;
+
+ content[0] = 0;
+ p = content;
+ ASSERT_EQ(leb128::decode<uint64_t>(p), 0);
+ ASSERT_EQ(p, content + 1);
+
+ content[0] = 1;
+ p = content;
+ ASSERT_EQ(leb128::decode<uint64_t>(p), 1);
+ ASSERT_EQ(p, content + 1);
+
+ content[0] = 0x80;
+ content[1] = 0x7f;
+ p = content;
+ ASSERT_EQ(leb128::decode<uint64_t>(p), 16256);
+ ASSERT_EQ(p, content + 2);
+}
+
+TEST_F( LEB128Test, EncodeULEB_Tests_Found_in_Android_dalvik_dx) {
+ leb128::ByteType buffer[5];
+ leb128::ByteType *result;
+ size_t size;
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 0);
+ ASSERT_EQ(buffer[0], 0);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 0);
+ ASSERT_EQ(buffer[0], 0);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 1);
+ ASSERT_EQ(buffer[0], 1);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 1);
+ ASSERT_EQ(buffer[0], 1);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 16256);
+ ASSERT_EQ(buffer[0], 0x80);
+ ASSERT_EQ(buffer[1], 0x7f);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 16256);
+ ASSERT_EQ(buffer[0], 0x80);
+ ASSERT_EQ(buffer[1], 0x7f);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 0x3b4);
+ ASSERT_EQ(buffer[0], 0xb4);
+ ASSERT_EQ(buffer[1], 0x07);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 0x3b4);
+ ASSERT_EQ(buffer[0], 0xb4);
+ ASSERT_EQ(buffer[1], 0x07);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 0x40c);
+ ASSERT_EQ(buffer[0], 0x8c);
+ ASSERT_EQ(buffer[1], 0x08);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 0x40c);
+ ASSERT_EQ(buffer[0], 0x8c);
+ ASSERT_EQ(buffer[1], 0x08);
+ ASSERT_EQ(result, buffer + 2);
+ ASSERT_EQ(size, 2);
+
+ result = buffer;
+ size = leb128::encode<uint32_t>(result, 0xffffffff);
+ ASSERT_EQ(buffer[0], 0xff);
+ ASSERT_EQ(buffer[1], 0xff);
+ ASSERT_EQ(buffer[2], 0xff);
+ ASSERT_EQ(buffer[3], 0xff);
+ ASSERT_EQ(buffer[4], 0xf);
+ ASSERT_EQ(result, buffer + 5);
+ ASSERT_EQ(size, 5);
+
+ result = buffer;
+ size = leb128::encode<uint64_t>(result, 0xffffffff);
+ ASSERT_EQ(buffer[0], 0xff);
+ ASSERT_EQ(buffer[1], 0xff);
+ ASSERT_EQ(buffer[2], 0xff);
+ ASSERT_EQ(buffer[3], 0xff);
+ ASSERT_EQ(buffer[4], 0xf);
+ ASSERT_EQ(result, buffer + 5);
+ ASSERT_EQ(size, 5);
+}
+
+TEST_F( LEB128Test, DecodeSLEB_Tests_Found_in_Android_dalvik_dx) {
+ leb128::ByteType content[2];
+ const leb128::ByteType *p;
+
+ content[0] = 0;
+ p = content;
+ ASSERT_EQ(leb128::decode<int64_t>(p), 0);
+ ASSERT_EQ(p, content + 1);
+
+ content[0] = 1;
+ p = content;
+ ASSERT_EQ(leb128::decode<int64_t>(p), 1);
+ ASSERT_EQ(p, content + 1);
+
+ content[0] = 0x7f;
+ p = content;
+ ASSERT_EQ(leb128::decode<int64_t>(p), -1);
+ ASSERT_EQ(p, content + 1);
+
+ content[0] = 0x3c;
+ p = content;
+ ASSERT_EQ(leb128::decode<int64_t>(p), 0x3c);
+ ASSERT_EQ(p, content + 1);
+}
+
+TEST_F( LEB128Test, EncodeSLEB_Tests_Found_in_Android_dalvik_dx) {
+ leb128::ByteType buffer[5];
+ leb128::ByteType *result;
+ size_t size;
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, 0);
+ ASSERT_EQ(buffer[0], 0);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<int64_t>(result, 0);
+ ASSERT_EQ(buffer[0], 0);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, 1);
+ ASSERT_EQ(buffer[0], 1);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<int64_t>(result, 1);
+ ASSERT_EQ(buffer[0], 1);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<int32_t>(result, -1);
+ ASSERT_EQ(buffer[0], 0x7f);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+
+ result = buffer;
+ size = leb128::encode<int64_t>(result, -1);
+ ASSERT_EQ(buffer[0], 0x7f);
+ ASSERT_EQ(result, buffer + 1);
+ ASSERT_EQ(size, 1);
+}
+
+TEST_F( LEB128Test, Random_Regression_Test) {
+ leb128::ByteType buffer[5];
+
+ for (int i = 0; i < 20; i++) {
+ long int value = random();
+ uint64_t value2 = value * value;
+ leb128::ByteType *result;
+ size_t encode_size, decode_size;
+
+ // Test encode<uint32_t> and decode<uint64_t> on value
+ result = buffer;
+ encode_size = leb128::encode<uint32_t>(result, value);
+ ASSERT_EQ(result, buffer + encode_size);
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, decode_size), value);
+ ASSERT_EQ(encode_size, decode_size);
+
+ // Test encode<uint64_t> and decode<uint64_t> on (value * value)
+ result = buffer;
+ encode_size = leb128::encode<uint64_t>(result, value2);
+ ASSERT_EQ(result, buffer + encode_size);
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, decode_size), value2);
+ ASSERT_EQ(encode_size, decode_size);
+
+ // Test encode<uint64_t> and decode<uint64_t> on (value * value)
+ result = buffer;
+ encode_size = leb128::encode<int64_t>(result, value2);
+ ASSERT_EQ(result, buffer + encode_size);
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, decode_size), value2);
+ ASSERT_EQ(encode_size, decode_size);
+
+ // Test encode<uint64_t> and decode<uint64_t> on -(value * value)
+ result = buffer;
+ encode_size = leb128::encode<int64_t>(result, -value2);
+ ASSERT_EQ(result, buffer + encode_size);
+ ASSERT_EQ(leb128::decode<int64_t>(buffer, decode_size), -value2);
+ ASSERT_EQ(encode_size, decode_size);
+ }
+}
+
+TEST_F( LEB128Test, Other_Test) {
+ leb128::ByteType buffer[5];
+ leb128::ByteType *result;
+ size_t size;
+
+ result = buffer;
+ leb128::encode<uint64_t>(result, 154452);
+ ASSERT_EQ(result, buffer + 3);
+ ASSERT_EQ(buffer[0], 0xd4);
+ ASSERT_EQ(buffer[1], 0xb6);
+ ASSERT_EQ(buffer[2], 0x9);
+
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 154452);
+ ASSERT_EQ(size, 3);
+}
+
+TEST_F( LEB128Test, Type_Conversion_Test) {
+ char buffer[5];
+ char *result;
+ size_t size;
+
+ result = buffer;
+ leb128::encode<uint64_t>(result, 154452);
+ ASSERT_EQ(result, buffer + 3);
+ ASSERT_EQ(buffer[0], '\xd4');
+ ASSERT_EQ(buffer[1], '\xb6');
+ ASSERT_EQ(buffer[2], '\x09');
+
+ ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 154452);
+ ASSERT_EQ(size, 3);
+
+ const char *p = buffer;
+ ASSERT_EQ(leb128::decode<uint64_t>(p), 154452);
+ ASSERT_EQ(p, buffer + 3);
+}
diff --git a/unittests/LEB128Test.h b/unittests/LEB128Test.h
new file mode 100644
index 0000000..f0a87e3
--- /dev/null
+++ b/unittests/LEB128Test.h
@@ -0,0 +1,41 @@
+//===- LEB128Test.h -------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LEB128_TEST_H
+#define MCLD_LEB128_TEST_H
+
+#include <gtest.h>
+
+namespace mcldtest
+{
+
+/** \class LEB128Test
+ * \brief
+ *
+ * \see LEB
+ */
+class LEB128Test : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ LEB128Test();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~LEB128Test();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/LinearAllocatorTest.cpp b/unittests/LinearAllocatorTest.cpp
new file mode 100644
index 0000000..9100160
--- /dev/null
+++ b/unittests/LinearAllocatorTest.cpp
@@ -0,0 +1,139 @@
+//===- LinearAllocatorTest.cpp --------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "LinearAllocatorTest.h"
+#include "mcld/Support/Allocators.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+LinearAllocatorTest::LinearAllocatorTest()
+{
+ // create testee. modify it if need
+ m_pTestee = new LinearAllocator<Data, CHUNK_SIZE>();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+LinearAllocatorTest::~LinearAllocatorTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void LinearAllocatorTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void LinearAllocatorTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( LinearAllocatorTest, allocateN ) {
+ Data* pointer = m_pTestee->allocate(10);
+ ASSERT_FALSE(0 == pointer);
+ ASSERT_EQ(CHUNK_SIZE, m_pTestee->max_size());
+ ASSERT_FALSE(m_pTestee->empty());
+}
+
+TEST_F( LinearAllocatorTest, allocate ) {
+ Data* pointer = m_pTestee->allocate();
+ ASSERT_FALSE(0 == pointer);
+ ASSERT_EQ(CHUNK_SIZE, m_pTestee->max_size());
+ ASSERT_FALSE(m_pTestee->empty());
+}
+
+TEST_F( LinearAllocatorTest, allocateOver ) {
+ Data* pointer = m_pTestee->allocate(CHUNK_SIZE+1);
+ ASSERT_TRUE(0 == pointer);
+ ASSERT_EQ(0, m_pTestee->max_size());
+ ASSERT_TRUE(m_pTestee->empty());
+}
+
+TEST_F( LinearAllocatorTest, alloc_construct ) {
+ Data* pointer = m_pTestee->allocate();
+ m_pTestee->construct(pointer);
+ ASSERT_EQ(1, pointer->one);
+ ASSERT_EQ(2, pointer->two);
+ ASSERT_EQ(3, pointer->three);
+ ASSERT_EQ(4, pointer->four);
+}
+
+TEST_F( LinearAllocatorTest, alloc_constructCopy ) {
+ Data* pointer = m_pTestee->allocate();
+ Data data(7, 7, 7, 7);
+ m_pTestee->construct(pointer, data);
+
+ ASSERT_EQ(7, pointer->one);
+ ASSERT_EQ(7, pointer->two);
+ ASSERT_EQ(7, pointer->three);
+ ASSERT_EQ(7, pointer->four);
+}
+
+TEST_F( LinearAllocatorTest, allocN_construct ) {
+ Data* pointer = m_pTestee->allocate(10);
+ m_pTestee->construct(pointer);
+ ASSERT_EQ(1, pointer->one);
+ ASSERT_EQ(2, pointer->two);
+ ASSERT_EQ(3, pointer->three);
+ ASSERT_EQ(4, pointer->four);
+}
+
+TEST_F( LinearAllocatorTest, allocN_constructCopy ) {
+ Data* pointer = m_pTestee->allocate(10);
+ Data data(7, 7, 7, 7);
+ m_pTestee->construct(pointer, data);
+
+ ASSERT_EQ(7, pointer->one);
+ ASSERT_EQ(7, pointer->two);
+ ASSERT_EQ(7, pointer->three);
+ ASSERT_EQ(7, pointer->four);
+}
+
+TEST_F( LinearAllocatorTest, multi_alloc_ctor_iterate ) {
+ for (int i=0; i<101; ++i) {
+ Data* pointer = m_pTestee->allocate();
+ m_pTestee->construct(pointer);
+ pointer->one = i;
+ }
+/**
+ Alloc::iterator data, dEnd = m_pTestee->end();
+ int counter = 0;
+ for (data=m_pTestee->begin(); data!=dEnd; ++data) {
+ ASSERT_EQ(counter, (*data).one);
+ ++counter;
+ }
+**/
+}
+
+TEST_F( LinearAllocatorTest, multi_allocN_ctor_iterate ) {
+ int counter = 0;
+ for (int i=0; i<10000; ++i) {
+ Data* pointer = m_pTestee->allocate(10);
+ for (int j=0; j<10; ++j) {
+ m_pTestee->construct(pointer);
+ pointer->one = counter;
+ ++pointer;
+ ++counter;
+ }
+ }
+/**
+ Alloc::iterator data, dEnd = m_pTestee->end();
+ counter = 0;
+ for (data=m_pTestee->begin(); data!=dEnd; ++data) {
+ ASSERT_EQ(counter, (*data).one);
+ ++counter;
+ }
+**/
+}
+
diff --git a/unittests/LinearAllocatorTest.h b/unittests/LinearAllocatorTest.h
new file mode 100644
index 0000000..9e9b2ab
--- /dev/null
+++ b/unittests/LinearAllocatorTest.h
@@ -0,0 +1,75 @@
+//===- LinearAllocatorTest.h ----------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LINEAR_ALLOCATOR_TEST_H
+#define LINEAR_ALLOCATOR_TEST_H
+
+#include <gtest.h>
+#include "mcld/Support/Allocators.h"
+
+namespace mcldtest
+{
+
+/** \class LinearAllocatorTest
+ * \brief The testcase for LinearAllocator
+ *
+ * \see LinearAllocator
+ */
+class LinearAllocatorTest : public ::testing::Test
+{
+public:
+ struct Data {
+ Data()
+ : one(1), two(2), three(3), four(4)
+ { }
+
+ Data( unsigned int pOne, unsigned int pTwo, unsigned char pThree, unsigned char pFour)
+ {
+ one = pOne;
+ two = pTwo;
+ three = pThree;
+ four = pFour;
+ }
+
+ ~Data()
+ {
+ one = -1;
+ two = -2;
+ three = -3;
+ four = -4;
+ }
+
+ unsigned int one;
+ unsigned int two;
+ unsigned char three;
+ unsigned char four;
+ };
+public:
+ // Constructor can do set-up work for all test here.
+ LinearAllocatorTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~LinearAllocatorTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ enum { CHUNK_SIZE = 32 };
+ typedef mcld::LinearAllocator<Data, CHUNK_SIZE> Alloc;
+protected:
+ Alloc* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/MCFragmentRefTest.cpp b/unittests/MCFragmentRefTest.cpp
new file mode 100644
index 0000000..556fbdd
--- /dev/null
+++ b/unittests/MCFragmentRefTest.cpp
@@ -0,0 +1,70 @@
+//===- MCFragmentRefTest --------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mcld/MC/MCFragmentRef.h"
+#include "mcld/MC/MCRegionFragment.h"
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "mcld/Support/Path.h"
+#include "MCFragmentRefTest.h"
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+using namespace mcld::sys::fs::detail;
+using namespace mcldtest;
+
+// Constructor can do set-up work for all test here.
+MCFragmentRefTest::MCFragmentRefTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+MCFragmentRefTest::~MCFragmentRefTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void MCFragmentRefTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void MCFragmentRefTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( MCFragmentRefTest, ) {
+ Path path(TOPDIR);
+ path.append("unittests/test3.txt");
+ MemoryAreaFactory* areaFactory = new MemoryAreaFactory(1);
+ MemoryArea* area = areaFactory->produce(path, MemoryArea::ReadWrite);
+
+ MemoryRegion* region = area->request(0, 4096);
+ MCRegionFragment *frag = new MCRegionFragment(*region);
+ MCFragmentRef *ref = new MCFragmentRef(*frag);
+
+ ASSERT_EQ('H', region->getBuffer()[0]);
+ ASSERT_EQ(4096, region->size());
+ ASSERT_EQ('H', frag->getRegion().getBuffer()[0]);
+ ASSERT_EQ(4096, frag->getRegion().size());
+ ASSERT_EQ(frag, ref->frag());
+ ASSERT_EQ('H', static_cast<MCRegionFragment*>(ref->frag())->getRegion().getBuffer()[0]);
+ ASSERT_EQ(4096, static_cast<MCRegionFragment*>(ref->frag())->getRegion().size());
+ ASSERT_EQ('H', ref->deref()[0]);
+
+ ASSERT_FALSE(llvm::MCDataFragment::classof(frag));
+ ASSERT_TRUE(MCRegionFragment::classof(frag));
+
+ delete ref;
+ delete frag;
+ delete areaFactory;
+}
+
diff --git a/unittests/MCFragmentRefTest.h b/unittests/MCFragmentRefTest.h
new file mode 100644
index 0000000..c0b23f3
--- /dev/null
+++ b/unittests/MCFragmentRefTest.h
@@ -0,0 +1,48 @@
+//===- MCFragmentRefTest.h ------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_MCFRAGMENT_REF_TEST_H
+#define MCLD_MCFRAGMENT_REF_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class MCFragmentRef;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class MCFragmentRefTest
+ * \brief Reference Test
+ *
+ * \see MCFragmentRef
+ */
+class MCFragmentRefTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ MCFragmentRefTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~MCFragmentRefTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/MCRegionFragmentTest.cpp b/unittests/MCRegionFragmentTest.cpp
new file mode 100644
index 0000000..842ddf9
--- /dev/null
+++ b/unittests/MCRegionFragmentTest.cpp
@@ -0,0 +1,74 @@
+//===- MCRegionFragmentTest.cpp - MCRegionFragment implementation ---------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCRegionFragmentTest.h"
+
+#include "mcld/MC/MCRegionFragment.h"
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "mcld/Support/Path.h"
+
+using namespace mcld;
+using namespace mcldtest;
+using namespace mcld::sys::fs;
+
+
+// Constructor can do set-up work for all test here.
+MCRegionFragmentTest::MCRegionFragmentTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+MCRegionFragmentTest::~MCRegionFragmentTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void MCRegionFragmentTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void MCRegionFragmentTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F( MCRegionFragmentTest, classof_explicit ) {
+ Path path(TOPDIR);
+ path.append("unittests/test3.txt");
+ MemoryAreaFactory* areaFactory = new MemoryAreaFactory(1);
+ MemoryArea* area = areaFactory->produce(path, MemoryArea::ReadWrite);
+
+ MemoryRegion* region = area->request(0, 4096);
+ MCRegionFragment *frag = new MCRegionFragment(*region);
+
+ ASSERT_FALSE(llvm::MCDataFragment::classof(frag));
+ ASSERT_TRUE(MCRegionFragment::classof(frag));
+ delete frag;
+ delete areaFactory;
+}
+
+TEST_F( MCRegionFragmentTest, classof_implicit ) {
+ Path path(TOPDIR);
+ path.append("unittests/test3.txt");
+ MemoryAreaFactory* areaFactory = new MemoryAreaFactory(1);
+ MemoryArea* area = areaFactory->produce(path, MemoryArea::ReadWrite);
+
+ MemoryRegion* region = area->request(0, 4096);
+ llvm::MCFragment *frag = new MCRegionFragment(*region);
+
+ ASSERT_FALSE(llvm::MCDataFragment::classof(frag));
+ ASSERT_TRUE(MCRegionFragment::classof(frag));
+ delete frag;
+ delete areaFactory;
+}
+
diff --git a/unittests/MCRegionFragmentTest.h b/unittests/MCRegionFragmentTest.h
new file mode 100644
index 0000000..15434fd
--- /dev/null
+++ b/unittests/MCRegionFragmentTest.h
@@ -0,0 +1,51 @@
+//===- MCRegionFragment.h - unittest for MCRegionFragment -----------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCREGIONFRAGMENT_TEST_H
+#define MCREGIONFRAGMENT_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class MCRegionFragment;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class MCRegionFragmentTest
+ * \brief The testcase of MCRegionFragment.
+ *
+ * \see MCRegionFragment
+ */
+class MCRegionFragmentTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ MCRegionFragmentTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~MCRegionFragmentTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::MCRegionFragment* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/MemoryAreaTest.cpp b/unittests/MemoryAreaTest.cpp
new file mode 100644
index 0000000..a2e631a
--- /dev/null
+++ b/unittests/MemoryAreaTest.cpp
@@ -0,0 +1,148 @@
+//===- MemoryAreaTest.cpp -------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/MemoryArea.h"
+#include "mcld/Support/MemoryRegion.h"
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "mcld/Support/Path.h"
+
+#include "MemoryAreaTest.h"
+#include <fcntl.h>
+#include <cstdio>
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+MemoryAreaTest::MemoryAreaTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+MemoryAreaTest::~MemoryAreaTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void MemoryAreaTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void MemoryAreaTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( MemoryAreaTest, read_by_malloc )
+{
+ Path path(TOPDIR);
+ path.append("unittests/test3.txt");
+ MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1);
+ MemoryArea* area = AreaFactory->produce(path, O_RDONLY);
+ MemoryRegion* region = area->request(3, 2);
+ ASSERT_EQ('L', region->getBuffer()[0]);
+ ASSERT_EQ('O', region->getBuffer()[1]);
+ delete AreaFactory;
+}
+
+TEST_F( MemoryAreaTest, write_by_malloc )
+{
+ Path path(TOPDIR);
+ path.append("unittests/test2.txt");
+ MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1);
+ MemoryArea* area = AreaFactory->produce(path, O_RDWR);
+ ASSERT_TRUE(area->isMapped());
+ ASSERT_TRUE(area->isGood());
+ MemoryRegion* region = area->request(3, 4);
+ region->getBuffer()[0] = 'L';
+ region->getBuffer()[1] = 'i';
+ region->getBuffer()[2] = 'n';
+ region->getBuffer()[3] = 'k';
+ area->sync();
+ area->unmap();
+ area->map(path, O_RDONLY);
+ ASSERT_TRUE(area->isMapped());
+ ASSERT_TRUE(area->isGood());
+ region = area->request(5, 2);
+ ASSERT_EQ('n', region->getBuffer()[0]);
+ ASSERT_EQ('k', region->getBuffer()[1]);
+ delete AreaFactory;
+}
+
+TEST_F( MemoryAreaTest, read_one_page )
+{
+ Path path(TOPDIR) ;
+ path.append("unittests/test3.txt") ;
+ MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1) ;
+ MemoryArea* area = AreaFactory->produce(path, O_RDWR) ;
+ ASSERT_TRUE(area->isMapped()) ;
+ ASSERT_TRUE(area->isGood()) ;
+ MemoryRegion* region = area->request(0, 4096) ;
+ ASSERT_EQ('H', region->getBuffer()[0]);
+ ASSERT_EQ('E', region->getBuffer()[1]);
+ delete AreaFactory ;
+}
+
+TEST_F( MemoryAreaTest, write_one_page )
+{
+ Path path(TOPDIR) ;
+ path.append("unittests/test2.txt") ;
+ MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1) ;
+ MemoryArea* area = AreaFactory->produce(path, O_RDWR) ;
+ ASSERT_TRUE(area->isMapped()) ;
+ ASSERT_TRUE(area->isGood()) ;
+ MemoryRegion* region = area->request(0, 4096) ;
+ region->getBuffer()[4000] = 'K' ;
+ region->getBuffer()[4001] = 'R' ;
+ area->sync() ;
+ area->unmap() ;
+ area->map(path, O_RDONLY) ;
+ region = area->request(4000, 4) ;
+ ASSERT_EQ('K', region->getBuffer()[0]);
+ ASSERT_EQ('R', region->getBuffer()[1]);
+ region->getBuffer()[0] = 'O' ;
+ region->getBuffer()[1] = 'H' ;
+ area->sync() ;
+ delete AreaFactory ;
+}
+
+TEST_F( MemoryAreaTest, write_sync )
+{
+ Path path(TOPDIR) ;
+ path.append("unittests/test2.txt") ;
+ MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1) ;
+ MemoryArea* area = AreaFactory->produce(path, O_RDWR) ;
+ ASSERT_TRUE(area->isMapped()) ;
+ ASSERT_TRUE(area->isGood()) ;
+ MemoryRegion* region1 = area->request(0, 4096) ;
+ MemoryRegion* region2 = area->request(512, 1024) ;
+ region1->getBuffer()[1000] = 'L' ;
+ region1->getBuffer()[1001] = 'L' ;
+ region2->getBuffer()[488] = 'V' ;
+ region2->getBuffer()[489] = 'M' ;
+ area->sync() ;
+ area->unmap();
+ area->map(path, O_RDWR) ;
+ region1 = area->request(0, 1024) ;
+ EXPECT_EQ('V', region1->getBuffer()[1000]) ;
+ EXPECT_EQ('M', region1->getBuffer()[1001]) ;
+ region1->getBuffer()[1000] = '@' ;
+ region1->getBuffer()[1001] = '@' ;
+ area->sync();
+ delete AreaFactory ;
+}
+
+
diff --git a/unittests/MemoryAreaTest.h b/unittests/MemoryAreaTest.h
new file mode 100644
index 0000000..86a5da0
--- /dev/null
+++ b/unittests/MemoryAreaTest.h
@@ -0,0 +1,50 @@
+//===- MemoryAreaTest.h ---------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MEMORYAREA_TEST_H
+#define MEMORYAREA_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class MemoryArea;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class MemoryAreaTest
+ * \brief
+ *
+ * \see MemoryArea
+ */
+class MemoryAreaTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ MemoryAreaTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~MemoryAreaTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::MemoryArea* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/PathSetTest.cpp b/unittests/PathSetTest.cpp
new file mode 100644
index 0000000..d735e9c
--- /dev/null
+++ b/unittests/PathSetTest.cpp
@@ -0,0 +1,45 @@
+//===- PathSetTest.cpp ----------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/PathSet.h"
+#include "PathSetTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+PathSetTest::PathSetTest()
+{
+ // create testee. modify it if need
+ m_pTestee = new PathSet();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+PathSetTest::~PathSetTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void PathSetTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void PathSetTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F( PathSetTest, ) {
+}
+
diff --git a/unittests/PathSetTest.h b/unittests/PathSetTest.h
new file mode 100644
index 0000000..d64b2a8
--- /dev/null
+++ b/unittests/PathSetTest.h
@@ -0,0 +1,50 @@
+//===- PathSetTest.h ------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef PATHSET_TEST_H
+#define PATHSET_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class PathSet;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class PathSetTest
+ * \brief The testcase of PathSet
+ *
+ * \see PathSet
+ */
+class PathSetTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ PathSetTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~PathSetTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::PathSet* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/PathTest.cpp b/unittests/PathTest.cpp
new file mode 100644
index 0000000..8906d02
--- /dev/null
+++ b/unittests/PathTest.cpp
@@ -0,0 +1,140 @@
+//===- PathTest.cpp -------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "PathTest.h"
+#include "mcld/Support/FileSystem.h"
+#include <string>
+
+//
+using namespace mcld;
+using namespace mcld::sys::fs;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+PathTest::PathTest()
+{
+ // create testee. modify it if need
+ m_pTestee = new Path();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+PathTest::~PathTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void PathTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void PathTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( PathTest, should_exist ) {
+ const std::string root = "/etc/hosts";
+ m_pTestee->assign(root);
+ EXPECT_TRUE(exists(*m_pTestee));
+
+ delete m_pTestee;
+ m_pTestee = new Path(root);
+ EXPECT_TRUE(exists(*m_pTestee));
+}
+
+TEST_F( PathTest, should_not_exist ) {
+ const std::string root = "/luck";
+ m_pTestee->assign(root);
+ EXPECT_FALSE(exists(*m_pTestee));
+
+ delete m_pTestee;
+ m_pTestee = new Path(root);
+ EXPECT_FALSE(exists(*m_pTestee));
+}
+
+TEST_F( PathTest, should_is_directory ) {
+// const std::string root = "/proj/mtk03931/temp/pndk-luba/../";
+ const std::string root = "../././..";
+ m_pTestee->assign(root);
+ EXPECT_TRUE(exists(*m_pTestee));
+ EXPECT_TRUE(is_directory(*m_pTestee));
+ delete m_pTestee;
+ m_pTestee = new Path(root);
+ EXPECT_TRUE(exists(*m_pTestee));
+ EXPECT_TRUE(is_directory(*m_pTestee));
+}
+
+TEST_F( PathTest, should_not_is_directory ) {
+ const std::string root = "/luck";
+ m_pTestee->assign(root);
+ EXPECT_FALSE(exists(*m_pTestee));
+ EXPECT_FALSE(is_directory(*m_pTestee));
+ delete m_pTestee;
+ m_pTestee = new Path(root);
+ EXPECT_FALSE(exists(*m_pTestee));
+ EXPECT_FALSE(is_directory(*m_pTestee));
+}
+
+TEST_F( PathTest, should_equal ) {
+ const std::string root = "aaa/bbb/../../ccc/";
+ m_pTestee->assign(root);
+
+ Path* p2 = new Path("ccc///////");
+
+ EXPECT_TRUE(*m_pTestee==*p2);
+
+ delete m_pTestee;
+ m_pTestee = new Path(root);
+ EXPECT_TRUE(*m_pTestee==*m_pTestee);
+ delete p2;
+}
+
+TEST_F( PathTest, should_not_equal ) {
+ const std::string root = "aa/";
+ Path* p2=new Path("aaa//");
+// p2->assign(root);
+ m_pTestee->assign(root);
+ EXPECT_TRUE(*m_pTestee!=*p2);
+
+ delete m_pTestee;
+ m_pTestee = new Path(root);
+ EXPECT_TRUE(*m_pTestee!=*p2);
+ delete p2;
+}
+
+TEST_F( PathTest, append_success ) {
+
+ const std::string root = "aa/";
+ m_pTestee->assign(root);
+ m_pTestee->append("aaa");
+ std::string a("aa/aaa");
+ EXPECT_TRUE(m_pTestee->native()=="aa/aaa");
+ delete m_pTestee;
+ m_pTestee = new Path("aa/");
+ m_pTestee->append("/aaa");
+ EXPECT_TRUE(m_pTestee->string()=="aa/aaa");
+ delete m_pTestee;
+ m_pTestee = new Path("aa");
+ m_pTestee->append("/aaa");
+ EXPECT_TRUE(m_pTestee->string()=="aa/aaa");
+ delete m_pTestee;
+ m_pTestee = new Path("aa");
+ m_pTestee->append("aaa");
+ EXPECT_TRUE(m_pTestee->string()=="aa/aaa");
+}
+
+TEST_F( PathTest, should_become_generic_string ) {
+ m_pTestee->assign("/etc/../dev/../usr//lib//");
+ EXPECT_STREQ("/usr/lib/", m_pTestee->generic_string().c_str());
+}
+
diff --git a/unittests/PathTest.h b/unittests/PathTest.h
new file mode 100644
index 0000000..968ce0e
--- /dev/null
+++ b/unittests/PathTest.h
@@ -0,0 +1,45 @@
+//===- PathTest.h ---------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef PATH_TEST_H
+#define PATH_TEST_H
+
+#include "mcld/Support/Path.h"
+#include <gtest.h>
+
+namespace mcldtest
+{
+
+/** \class PathTest
+ * \brief a testcase for mcld::Path and its non-member funtions.
+ *
+ * \see Path
+ */
+class PathTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ PathTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~PathTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::sys::fs::Path* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/RTLinearAllocatorTest.cpp b/unittests/RTLinearAllocatorTest.cpp
new file mode 100644
index 0000000..9ef31e5
--- /dev/null
+++ b/unittests/RTLinearAllocatorTest.cpp
@@ -0,0 +1,140 @@
+//===- RTLinearAllocatorTest.cpp ------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/Allocators.h"
+#include <RTLinearAllocatorTest.h>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+RTLinearAllocatorTest::RTLinearAllocatorTest()
+{
+ // create testee. modify it if need
+ m_pTestee = new LinearAllocator<Data, 0>(CHUNK_SIZE);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+RTLinearAllocatorTest::~RTLinearAllocatorTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void RTLinearAllocatorTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void RTLinearAllocatorTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F(RTLinearAllocatorTest, AllocateN) {
+ Data* pointer = m_pTestee->allocate(10);
+ ASSERT_FALSE(0 == pointer);
+ ASSERT_EQ(CHUNK_SIZE, m_pTestee->max_size());
+ ASSERT_FALSE(m_pTestee->empty());
+}
+
+TEST_F(RTLinearAllocatorTest, allocate ) {
+ Data* pointer = m_pTestee->allocate();
+ ASSERT_FALSE(0 == pointer);
+ ASSERT_EQ(CHUNK_SIZE, m_pTestee->max_size());
+ ASSERT_FALSE(m_pTestee->empty());
+}
+
+TEST_F(RTLinearAllocatorTest, allocateOver ) {
+ Data* pointer = m_pTestee->allocate(CHUNK_SIZE+1);
+ ASSERT_TRUE(0 == pointer);
+ ASSERT_EQ(0, m_pTestee->max_size());
+ ASSERT_TRUE(m_pTestee->empty());
+}
+
+TEST_F(RTLinearAllocatorTest, alloc_construct ) {
+ Data* pointer = m_pTestee->allocate();
+ m_pTestee->construct(pointer);
+ ASSERT_EQ(1, pointer->one);
+ ASSERT_EQ(2, pointer->two);
+ ASSERT_EQ(3, pointer->three);
+ ASSERT_EQ(4, pointer->four);
+}
+
+TEST_F(RTLinearAllocatorTest, alloc_constructCopy ) {
+ Data* pointer = m_pTestee->allocate();
+ Data data(7, 7, 7, 7);
+ m_pTestee->construct(pointer, data);
+
+ ASSERT_EQ(7, pointer->one);
+ ASSERT_EQ(7, pointer->two);
+ ASSERT_EQ(7, pointer->three);
+ ASSERT_EQ(7, pointer->four);
+}
+
+TEST_F(RTLinearAllocatorTest, allocN_construct ) {
+ Data* pointer = m_pTestee->allocate(10);
+ m_pTestee->construct(pointer);
+ ASSERT_EQ(1, pointer->one);
+ ASSERT_EQ(2, pointer->two);
+ ASSERT_EQ(3, pointer->three);
+ ASSERT_EQ(4, pointer->four);
+}
+
+TEST_F(RTLinearAllocatorTest, allocN_constructCopy ) {
+ Data* pointer = m_pTestee->allocate(10);
+ Data data(7, 7, 7, 7);
+ m_pTestee->construct(pointer, data);
+
+ ASSERT_EQ(7, pointer->one);
+ ASSERT_EQ(7, pointer->two);
+ ASSERT_EQ(7, pointer->three);
+ ASSERT_EQ(7, pointer->four);
+}
+
+TEST_F(RTLinearAllocatorTest, multi_alloc_ctor_iterate ) {
+ for (int i=0; i<101; ++i) {
+ Data* pointer = m_pTestee->allocate();
+ m_pTestee->construct(pointer);
+ pointer->one = i;
+ }
+/**
+ Alloc::iterator data, dEnd = m_pTestee->end();
+ int counter = 0;
+ for (data=m_pTestee->begin(); data!=dEnd; ++data) {
+ ASSERT_EQ(counter, (*data).one);
+ ++counter;
+ }
+**/
+}
+
+TEST_F(RTLinearAllocatorTest, multi_allocN_ctor_iterate ) {
+ int counter = 0;
+ for (int i=0; i<10000; ++i) {
+ Data* pointer = m_pTestee->allocate(10);
+ for (int j=0; j<10; ++j) {
+ m_pTestee->construct(pointer);
+ pointer->one = counter;
+ ++pointer;
+ ++counter;
+ }
+ }
+/**
+ Alloc::iterator data, dEnd = m_pTestee->end();
+ counter = 0;
+ for (data=m_pTestee->begin(); data!=dEnd; ++data) {
+ ASSERT_EQ(counter, (*data).one);
+ ++counter;
+ }
+**/
+}
+
diff --git a/unittests/RTLinearAllocatorTest.h b/unittests/RTLinearAllocatorTest.h
new file mode 100644
index 0000000..d58442a
--- /dev/null
+++ b/unittests/RTLinearAllocatorTest.h
@@ -0,0 +1,74 @@
+//===- RTLinearAllocatorTest.h --------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef RTLINEARALLOCATOR_TEST_H
+#define RTLINEARALLOCATOR_TEST_H
+
+#include <gtest.h>
+#include "mcld/Support/Allocators.h"
+
+namespace mcldtest
+{
+
+/** \class RTLinearAllocatorTest
+ * \brief
+ *
+ * \see RTLinearAllocator
+ */
+class RTLinearAllocatorTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ RTLinearAllocatorTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~RTLinearAllocatorTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+public:
+ struct Data {
+ Data()
+ : one(1), two(2), three(3), four(4)
+ { }
+
+ Data( unsigned int pOne, unsigned int pTwo, unsigned char pThree, unsigned char pFour)
+ {
+ one = pOne;
+ two = pTwo;
+ three = pThree;
+ four = pFour;
+ }
+
+ ~Data()
+ {
+ one = -1;
+ two = -2;
+ three = -3;
+ four = -4;
+ }
+
+ unsigned int one;
+ unsigned int two;
+ unsigned char three;
+ unsigned char four;
+ };
+ enum { CHUNK_SIZE = 32 };
+
+protected:
+ mcld::LinearAllocator<Data,0>* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/StaticResolverTest.cpp b/unittests/StaticResolverTest.cpp
new file mode 100644
index 0000000..f9dfdf4
--- /dev/null
+++ b/unittests/StaticResolverTest.cpp
@@ -0,0 +1,436 @@
+//===- implTest.cpp -------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/StaticResolver.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/ResolveInfoFactory.h>
+#include "StaticResolverTest.h"
+
+#include <iostream>
+
+using namespace std;
+using namespace mcld;
+using namespace mcldtest;
+
+// Constructor can do set-up work for all test here.
+StaticResolverTest::StaticResolverTest()
+{
+ // create testee. modify it if need
+ m_pResolver = new StaticResolver();
+ m_pFactory = new ResolveInfoFactory();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+StaticResolverTest::~StaticResolverTest()
+{
+ delete m_pResolver;
+ delete m_pFactory;
+}
+
+// SetUp() will be called immediately before each test.
+void StaticResolverTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void StaticResolverTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( StaticResolverTest, MDEF ) {
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+ new_sym->setDesc(ResolveInfo::Define);
+ old_sym->setDesc(ResolveInfo::Define);
+ ASSERT_EQ( mcld::ResolveInfo::Define, new_sym->desc());
+ ASSERT_EQ( mcld::ResolveInfo::Define, old_sym->desc());
+ ASSERT_TRUE( mcld::ResolveInfo::define_flag == new_sym->info());
+ ASSERT_TRUE( mcld::ResolveInfo::define_flag == old_sym->info());
+ bool override = true;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ( Resolver::Abort, result);
+ ASSERT_FALSE( override );
+ ASSERT_STREQ( "multiple definitions of `abc'.", m_pResolver->mesg().c_str() );
+}
+
+TEST_F( StaticResolverTest, DynDefAfterDynUndef ) {
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+
+ new_sym->setBinding(ResolveInfo::Global);
+ old_sym->setBinding(ResolveInfo::Global);
+ new_sym->setDesc(ResolveInfo::Undefined);
+ old_sym->setDesc(ResolveInfo::Define);
+ new_sym->setSource(true);
+ old_sym->setSource(true);
+
+ new_sym->setSize(0);
+
+ old_sym->setSize(1);
+
+ ASSERT_EQ( mcld::ResolveInfo::Global, new_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Global, old_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Undefined, new_sym->desc());
+ ASSERT_EQ( mcld::ResolveInfo::Define, old_sym->desc());
+
+ bool override = false;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ( Resolver::Success, result);
+ ASSERT_FALSE( override );
+ ASSERT_EQ(1, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, DynDefAfterDynDef ) {
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+
+ new_sym->setBinding(ResolveInfo::Global);
+ old_sym->setBinding(ResolveInfo::Global);
+ new_sym->setDesc(ResolveInfo::Define);
+ old_sym->setDesc(ResolveInfo::Define);
+ new_sym->setSource(true);
+ old_sym->setSource(true);
+
+ new_sym->setSize(0);
+
+ old_sym->setSize(1);
+
+ ASSERT_EQ( mcld::ResolveInfo::Global, new_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Global, old_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Define, new_sym->desc());
+ ASSERT_EQ( mcld::ResolveInfo::Define, old_sym->desc());
+
+ bool override = false;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ( Resolver::Success, result);
+ ASSERT_FALSE( override );
+ ASSERT_EQ(1, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, DynUndefAfterDynUndef ) {
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+
+ new_sym->setBinding(ResolveInfo::Global);
+ old_sym->setBinding(ResolveInfo::Global);
+ new_sym->setDesc(ResolveInfo::Undefined);
+ old_sym->setDesc(ResolveInfo::Undefined);
+ new_sym->setSource(true);
+ old_sym->setSource(true);
+
+ new_sym->setSize(0);
+
+ old_sym->setSize(1);
+
+ ASSERT_EQ( mcld::ResolveInfo::Global, new_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Global, old_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Undefined, new_sym->desc());
+ ASSERT_EQ( mcld::ResolveInfo::Undefined, old_sym->desc());
+
+ bool override = false;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ( Resolver::Success, result);
+ ASSERT_FALSE( override );
+ ASSERT_EQ(1, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, OverrideWeakByGlobal )
+{
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+
+ new_sym->setBinding(ResolveInfo::Global);
+ old_sym->setBinding(ResolveInfo::Weak);
+ new_sym->setSize(0);
+ old_sym->setSize(1);
+
+ ASSERT_EQ( mcld::ResolveInfo::Global, new_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Weak, old_sym->binding());
+
+ ASSERT_TRUE( mcld::ResolveInfo::global_flag == new_sym->info());
+ ASSERT_TRUE( mcld::ResolveInfo::weak_flag == old_sym->info());
+ bool override = false;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ( Resolver::Success, result);
+ ASSERT_TRUE( override );
+ ASSERT_EQ(0, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, DynWeakAfterDynDef ) {
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+
+ old_sym->setBinding(ResolveInfo::Weak);
+ new_sym->setBinding(ResolveInfo::Global);
+
+ new_sym->setSource(true);
+ old_sym->setSource(true);
+
+ old_sym->setDesc(ResolveInfo::Define);
+ new_sym->setDesc(ResolveInfo::Define);
+
+ new_sym->setSize(0);
+
+ old_sym->setSize(1);
+
+ ASSERT_EQ( mcld::ResolveInfo::Weak, old_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Global, new_sym->binding());
+ ASSERT_EQ( mcld::ResolveInfo::Define, old_sym->desc());
+ ASSERT_EQ( mcld::ResolveInfo::Define, new_sym->desc());
+
+ bool override = false;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ( Resolver::Success, result);
+ ASSERT_FALSE( override );
+ ASSERT_EQ(1, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, MarkByBiggerCommon )
+{
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+
+ new_sym->setDesc(ResolveInfo::Common);
+ old_sym->setDesc(ResolveInfo::Common);
+ new_sym->setSize(999);
+ old_sym->setSize(0);
+
+ ASSERT_EQ( mcld::ResolveInfo::Common, new_sym->desc());
+ ASSERT_EQ( mcld::ResolveInfo::Common, old_sym->desc());
+
+ ASSERT_TRUE( mcld::ResolveInfo::common_flag == new_sym->info());
+ ASSERT_TRUE( mcld::ResolveInfo::common_flag == old_sym->info());
+ bool override = true;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ( Resolver::Success, result);
+ ASSERT_FALSE( override );
+ ASSERT_EQ(999, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, OverrideByBiggerCommon )
+{
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+
+ new_sym->setDesc(ResolveInfo::Common);
+ old_sym->setDesc(ResolveInfo::Common);
+ old_sym->setBinding(ResolveInfo::Weak);
+ new_sym->setSize(999);
+ old_sym->setSize(0);
+
+ ASSERT_EQ( ResolveInfo::Common, new_sym->desc());
+ ASSERT_EQ( ResolveInfo::Common, old_sym->desc());
+ ASSERT_EQ( ResolveInfo::Weak, old_sym->binding());
+
+ ASSERT_TRUE( ResolveInfo::common_flag == new_sym->info());
+ ASSERT_TRUE( (ResolveInfo::weak_flag | ResolveInfo::common_flag) == old_sym->info());
+
+ bool override = false;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ( Resolver::Success, result);
+ ASSERT_TRUE( override );
+ ASSERT_EQ(999, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, OverrideCommonByDefine)
+{
+ ResolveInfo* old_sym = m_pFactory->produce("abc");
+ ResolveInfo* new_sym = m_pFactory->produce("abc");
+
+ old_sym->setDesc(ResolveInfo::Common);
+ old_sym->setSize(0);
+
+ new_sym->setDesc(ResolveInfo::Define);
+ new_sym->setSize(999);
+
+ ASSERT_EQ( ResolveInfo::Define, new_sym->desc());
+ ASSERT_EQ( ResolveInfo::Common, old_sym->desc());
+
+ ASSERT_TRUE( ResolveInfo::define_flag == new_sym->info());
+ ASSERT_TRUE( ResolveInfo::common_flag == old_sym->info());
+
+ bool override = false;
+ unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+ ASSERT_EQ(Resolver::Warning, result);
+ ASSERT_TRUE( override );
+ ASSERT_EQ(999, old_sym->size());
+
+ ASSERT_STREQ("definition of 'abc' is overriding common.", m_pResolver->mesg().c_str() );
+
+}
+
+TEST_F( StaticResolverTest, SetUpDesc)
+{
+ ResolveInfo* sym = m_pFactory->produce("abc");
+
+ sym->setIsSymbol(true);
+
+// ASSERT_FALSE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_TRUE( sym->isUndef() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( 0, sym->desc() );
+ ASSERT_EQ( 0, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+
+ sym->setIsSymbol(false);
+ ASSERT_FALSE( sym->isSymbol() );
+// ASSERT_TRUE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_TRUE( sym->isUndef() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( 0, sym->desc() );
+ ASSERT_EQ( 0, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+
+ sym->setDesc(ResolveInfo::Define);
+ ASSERT_FALSE( sym->isSymbol() );
+// ASSERT_TRUE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_TRUE( sym->isDefine() );
+ ASSERT_FALSE( sym->isUndef() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( ResolveInfo::Define, sym->desc() );
+ ASSERT_EQ( 0, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+
+ sym->setDesc(ResolveInfo::Common);
+ ASSERT_FALSE( sym->isSymbol() );
+// ASSERT_TRUE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_FALSE( sym->isUndef() );
+ ASSERT_TRUE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( ResolveInfo::Common, sym->desc() );
+ ASSERT_EQ( 0, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+
+ sym->setDesc(ResolveInfo::Indirect);
+ ASSERT_FALSE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_FALSE( sym->isUndef() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_TRUE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( ResolveInfo::Indirect, sym->desc() );
+ ASSERT_EQ( 0, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+
+ sym->setDesc(ResolveInfo::Undefined);
+ ASSERT_FALSE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_TRUE( sym->isUndef() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( 0, sym->desc() );
+ ASSERT_EQ( 0, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+}
+
+TEST_F( StaticResolverTest, SetUpBinding)
+{
+ ResolveInfo* sym = m_pFactory->produce("abc");
+
+ sym->setIsSymbol(true);
+
+// ASSERT_FALSE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_TRUE( sym->isUndef() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( 0, sym->desc() );
+ ASSERT_EQ( 0, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+
+ sym->setBinding(ResolveInfo::Global);
+ ASSERT_TRUE( sym->isSymbol() );
+ ASSERT_TRUE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_TRUE( sym->isUndef() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( 0, sym->desc() );
+ ASSERT_EQ( ResolveInfo::Global, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+
+ sym->setBinding(ResolveInfo::Weak);
+ ASSERT_TRUE( sym->isSymbol() );
+ ASSERT_FALSE( sym->isGlobal() );
+ ASSERT_TRUE( sym->isWeak() );
+ ASSERT_FALSE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_TRUE( sym->isUndef() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( 0, sym->desc() );
+ ASSERT_EQ( ResolveInfo::Weak, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+
+ sym->setBinding(ResolveInfo::Local);
+ ASSERT_TRUE( sym->isSymbol() );
+ ASSERT_FALSE( sym->isGlobal() );
+ ASSERT_FALSE( sym->isWeak() );
+ ASSERT_TRUE( sym->isLocal() );
+ ASSERT_FALSE( sym->isDyn() );
+ ASSERT_FALSE( sym->isDefine() );
+ ASSERT_TRUE( sym->isUndef() );
+ ASSERT_FALSE( sym->isCommon() );
+ ASSERT_FALSE( sym->isIndirect() );
+ ASSERT_EQ( ResolveInfo::NoType, sym->type());
+ ASSERT_EQ( 0, sym->desc() );
+ ASSERT_EQ( ResolveInfo::Local, sym->binding() );
+ ASSERT_EQ( 0, sym->other() );
+}
+
diff --git a/unittests/StaticResolverTest.h b/unittests/StaticResolverTest.h
new file mode 100644
index 0000000..8b8ba31
--- /dev/null
+++ b/unittests/StaticResolverTest.h
@@ -0,0 +1,52 @@
+//===- headerTest.h -------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef STATICRESOLVER_TEST_H
+#define STATICRESOLVER_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class StaticResolver;
+class ResolveInfoFactory;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class StaticResolverTest
+ * \brief The testcases for static resolver
+ *
+ * \see StaticResolver
+ */
+class StaticResolverTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ StaticResolverTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~StaticResolverTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::StaticResolver* m_pResolver;
+ mcld::ResolveInfoFactory* m_pFactory;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/StrSymPoolTest.cpp b/unittests/StrSymPoolTest.cpp
new file mode 100644
index 0000000..a4ef558
--- /dev/null
+++ b/unittests/StrSymPoolTest.cpp
@@ -0,0 +1,259 @@
+//===- StrSymPoolTest.cpp -------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/StrSymPool.h"
+#include "StrSymPoolTest.h"
+#include <string>
+#include <cstdio>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+StrSymPoolTest::StrSymPoolTest()
+{
+ // create testee. modify it if need
+ Resolver resolver;
+ m_pTestee = new StrSymPool(1, 1, resolver);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+StrSymPoolTest::~StrSymPoolTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void StrSymPoolTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void StrSymPoolTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+
+TEST_F( StrSymPoolTest, insertString ) {
+ const char *s1 = "Hello MCLinker";
+ const char *result1 = m_pTestee->insertString(s1);
+ EXPECT_NE(s1, result1);
+ EXPECT_STREQ(s1, result1);
+}
+
+TEST_F( StrSymPoolTest, insertSameString ) {
+ const char *s1 = "Hello MCLinker";
+ std::string s2(s1);
+ const char *result1 = m_pTestee->insertString(s1);
+ const char *result2 = m_pTestee->insertString(s2.c_str());
+ EXPECT_STREQ(s1, result1);
+ EXPECT_STREQ(s2.c_str(), result2);
+ EXPECT_EQ(result1, result2);
+}
+
+TEST_F( StrSymPoolTest, insert_local_defined_Symbol ) {
+ const char *name = "Hello MCLinker";
+ bool isDyn = false;
+ LDSymbol::Type type = LDSymbol::Defined;
+ LDSymbol::Binding binding = LDSymbol::Local;
+ const llvm::MCSectionData *section = 0;
+ uint64_t value = 0;
+ uint64_t size = 0;
+ uint8_t other = 0;
+
+ LDSymbol *sym = m_pTestee->insertSymbol(name,
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+ EXPECT_NE(name, sym->name());
+ EXPECT_STREQ(name, sym->name());
+ EXPECT_EQ(isDyn, sym->isDyn());
+ EXPECT_EQ(type, sym->type());
+ EXPECT_EQ(binding, sym->binding());
+ EXPECT_EQ(section, sym->section());
+ EXPECT_EQ(value, sym->value());
+ EXPECT_EQ(size, sym->size());
+ EXPECT_EQ(other, sym->other());
+
+ LDSymbol *sym2 = m_pTestee->insertSymbol(name,
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+ EXPECT_NE(name, sym2->name());
+ EXPECT_STREQ(name, sym2->name());
+ EXPECT_EQ(isDyn, sym2->isDyn());
+ EXPECT_EQ(type, sym2->type());
+ EXPECT_EQ(binding, sym2->binding());
+ EXPECT_EQ(section, sym2->section());
+ EXPECT_EQ(value, sym2->value());
+ EXPECT_EQ(size, sym2->size());
+ EXPECT_EQ(other, sym2->other());
+
+
+ EXPECT_NE(sym, sym2);
+}
+
+TEST_F( StrSymPoolTest, insert_global_reference_Symbol ) {
+ const char *name = "Hello MCLinker";
+ bool isDyn = false;
+ LDSymbol::Type type = LDSymbol::Reference;
+ LDSymbol::Binding binding = LDSymbol::Global;
+ const llvm::MCSectionData *section = 0;
+ uint64_t value = 0;
+ uint64_t size = 0;
+ uint8_t other = 0;
+
+ LDSymbol *sym = m_pTestee->insertSymbol(name,
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+ EXPECT_NE(name, sym->name());
+ EXPECT_STREQ(name, sym->name());
+ EXPECT_EQ(isDyn, sym->isDyn());
+ EXPECT_EQ(type, sym->type());
+ EXPECT_EQ(binding, sym->binding());
+ EXPECT_EQ(section, sym->section());
+ EXPECT_EQ(value, sym->value());
+ EXPECT_EQ(size, sym->size());
+ EXPECT_EQ(other, sym->other());
+
+
+ LDSymbol *sym2 = m_pTestee->insertSymbol(name,
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+
+
+ EXPECT_EQ(sym, sym2);
+
+
+ LDSymbol *sym3 = m_pTestee->insertSymbol("Different symbol",
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+
+ EXPECT_NE(sym, sym3);
+}
+
+
+TEST_F( StrSymPoolTest, insertSymbol_after_insert_same_string ) {
+ const char *name = "Hello MCLinker";
+ bool isDyn = false;
+ LDSymbol::Type type = LDSymbol::Defined;
+ LDSymbol::Binding binding = LDSymbol::Global;
+ const llvm::MCSectionData *section = 0;
+ uint64_t value = 0;
+ uint64_t size = 0;
+ uint8_t other = 0;
+
+ const char *result1 = m_pTestee->insertString(name);
+ LDSymbol *sym = m_pTestee->insertSymbol(name,
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+
+ EXPECT_STREQ(name, sym->name());
+ EXPECT_EQ(result1, sym->name());
+
+ char s[16];
+ strcpy(s, result1);
+ const char *result2 = m_pTestee->insertString(result1);
+ const char *result3 = m_pTestee->insertString(s);
+
+ EXPECT_EQ(result1, result2);
+ EXPECT_EQ(result1, result3);
+}
+
+
+TEST_F( StrSymPoolTest, insert_16384_weak_reference_symbols ) {
+ char name[16];
+ bool isDyn = false;
+ LDSymbol::Type type = LDSymbol::Reference;
+ LDSymbol::Binding binding = LDSymbol::Weak;
+ const llvm::MCSectionData *section = 0;
+ uint64_t value = 0;
+ uint64_t size = 0;
+ uint8_t other = 0;
+ strcpy(name, "Hello MCLinker");
+ LDSymbol *syms[128][128];
+ for(int i=0; i<128 ;++i) {
+ name[0] = i;
+ for(int j=0; j<128 ;++j) {
+ name[1] = j;
+ syms[i][j] = m_pTestee->insertSymbol(name,
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+
+ ASSERT_STREQ(name, syms[i][j]->name());
+ }
+ }
+ for(int i=127; i>=0 ;--i) {
+ name[0] = i;
+ for(int j=0; j<128 ;++j) {
+ name[1] = j;
+ LDSymbol *sym = m_pTestee->insertSymbol(name,
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+ ASSERT_EQ(sym, syms[i][j]);
+ }
+ }
+ for(int i=0; i<128 ;++i) {
+ name[0] = i;
+ for(int j=0; j<128 ;++j) {
+ name[1] = j;
+ LDSymbol *sym = m_pTestee->insertSymbol(name,
+ isDyn,
+ type,
+ binding,
+ section,
+ value,
+ size,
+ other);
+ ASSERT_EQ(sym, syms[i][j]);
+ }
+ }
+}
diff --git a/unittests/StrSymPoolTest.h b/unittests/StrSymPoolTest.h
new file mode 100644
index 0000000..041fafa
--- /dev/null
+++ b/unittests/StrSymPoolTest.h
@@ -0,0 +1,50 @@
+//===- StrSymPoolTest.h ---------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef STRSYMPOOL_TEST_H
+#define STRSYMPOOL_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class StrSymPool;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class StrSymPoolTest
+ * \brief
+ *
+ * \see StrSymPool
+ */
+class StrSymPoolTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ StrSymPoolTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~StrSymPoolTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::StrSymPool* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/StringTableTest.cpp b/unittests/StringTableTest.cpp
new file mode 100644
index 0000000..59a8e7b
--- /dev/null
+++ b/unittests/StringTableTest.cpp
@@ -0,0 +1,77 @@
+//===- StringTableTest.cpp ------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "StringTableTest.h"
+#include "mcld/LD/StringTable.h"
+#include <cstring>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+StringTableTest::StringTableTest()
+{
+ // create testee. modify it if need
+ Resolver* R = new Resolver();
+ StrSymPool* Pool = new StrSymPool(1, 1, *R);
+ m_pTestee = new StringTable(*Pool);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+StringTableTest::~StringTableTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void StringTableTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void StringTableTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F(StringTableTest, different_string_size) {
+ int size = 127-32;
+ for (int i = 32; i < 127; ++i) {
+ char c[2];
+ c[0] = i;
+ c[1] = '\0';
+ ASSERT_NE(m_pTestee->insert(c), c);
+ }
+ ASSERT_EQ(m_pTestee->size(), size);
+}
+
+TEST_F(StringTableTest, traverse_begin_to_end) {
+ m_pTestee->insert("Hello");
+ m_pTestee->insert("World");
+ m_pTestee->insert("Media");
+ m_pTestee->insert("Tek");
+ StringTable::iterator it = m_pTestee->begin();
+ ASSERT_STREQ(*it, "Hello");
+ ++it;
+ ASSERT_STREQ(*it, "World");
+ ++it;
+ ASSERT_STREQ(*it, "Media");
+ ++it;
+ ASSERT_STREQ(*it, "Tek");
+ ++it;
+ ASSERT_EQ(it, m_pTestee->end());
+}
+
+TEST_F(StringTableTest, null_string) {
+ m_pTestee->insert("");
+ ASSERT_STREQ(*(m_pTestee->begin()), "");
+ ASSERT_EQ(m_pTestee->size(), 1);
+}
diff --git a/unittests/StringTableTest.h b/unittests/StringTableTest.h
new file mode 100644
index 0000000..0b397e8
--- /dev/null
+++ b/unittests/StringTableTest.h
@@ -0,0 +1,50 @@
+//===- StringTableTest.h --------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef STRINGTABLE_TEST_H
+#define STRINGTABLE_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class StringTable;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class StringTableTest
+ * \brief
+ *
+ * \see StringTable
+ */
+class StringTableTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ StringTableTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~StringTableTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::StringTable* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/SymbolCategoryTest.cpp b/unittests/SymbolCategoryTest.cpp
new file mode 100644
index 0000000..4233c3e
--- /dev/null
+++ b/unittests/SymbolCategoryTest.cpp
@@ -0,0 +1,94 @@
+//===- implTest.cpp -------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/MC/SymbolCategory.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/LDSymbol.h>
+#include <iostream>
+#include "SymbolCategoryTest.h"
+
+using namespace std;
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+SymbolCategoryTest::SymbolCategoryTest()
+{
+ // create testee. modify it if need
+ m_pTestee = new SymbolCategory();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+SymbolCategoryTest::~SymbolCategoryTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void SymbolCategoryTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void SymbolCategoryTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F(SymbolCategoryTest, upward_test) {
+ ResolveInfo* a = m_InfoFactory.produce("a");
+ ResolveInfo* b = m_InfoFactory.produce("b");
+ ResolveInfo* c = m_InfoFactory.produce("c");
+ ResolveInfo* d = m_InfoFactory.produce("d");
+ ResolveInfo* e = m_InfoFactory.produce("e");
+ e->setBinding(ResolveInfo::Global);
+ d->setBinding(ResolveInfo::Weak);
+ c->setDesc(ResolveInfo::Common);
+ c->setBinding(ResolveInfo::Global);
+ b->setBinding(ResolveInfo::Local);
+ a->setType(ResolveInfo::File);
+
+ LDSymbol aa;
+ LDSymbol bb;
+ LDSymbol cc;
+ LDSymbol dd;
+ LDSymbol ee;
+
+ aa.setResolveInfo(*a);
+ bb.setResolveInfo(*b);
+ cc.setResolveInfo(*c);
+ dd.setResolveInfo(*d);
+ ee.setResolveInfo(*e);
+
+ m_pTestee->add(ee);
+ m_pTestee->add(dd);
+ m_pTestee->add(cc);
+ m_pTestee->add(bb);
+ m_pTestee->add(aa);
+
+ SymbolCategory::iterator sym = m_pTestee->begin();
+ ASSERT_STREQ("a", (*sym)->name());
+ ++sym;
+ ASSERT_STREQ("b", (*sym)->name());
+ ++sym;
+ ASSERT_STREQ("c", (*sym)->name());
+ ++sym;
+ ASSERT_STREQ("d", (*sym)->name());
+ ++sym;
+ ASSERT_STREQ("e", (*sym)->name());
+
+ ASSERT_EQ(2, m_pTestee->numOfLocals());
+ ASSERT_EQ(1, m_pTestee->numOfCommons());
+ ASSERT_EQ(2, m_pTestee->numOfRegulars());
+ ASSERT_EQ(5, m_pTestee->numOfSymbols());
+}
+
diff --git a/unittests/SymbolCategoryTest.h b/unittests/SymbolCategoryTest.h
new file mode 100644
index 0000000..f721368
--- /dev/null
+++ b/unittests/SymbolCategoryTest.h
@@ -0,0 +1,52 @@
+//===- headerTest.h -------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SYMBOLCATEGORY_TEST_H
+#define MCLD_SYMBOLCATEGORY_TEST_H
+#include <mcld/LD/ResolveInfoFactory.h>
+
+#include <gtest.h>
+
+namespace mcld
+{
+class SymbolCategory;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class SymbolCategoryTest
+ * \brief The testcases of symbol category.
+ *
+ * \see SymbolCategory
+ */
+class SymbolCategoryTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ SymbolCategoryTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~SymbolCategoryTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::SymbolCategory* m_pTestee;
+ mcld::ResolveInfoFactory m_InfoFactory;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/SymbolTableTest.cpp b/unittests/SymbolTableTest.cpp
new file mode 100644
index 0000000..5b665f0
--- /dev/null
+++ b/unittests/SymbolTableTest.cpp
@@ -0,0 +1,45 @@
+//===- SymbolTableTest.cpp ------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/SymbolTable.h"
+#include "SymbolTableTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+SymbolTableTest::SymbolTableTest()
+{
+ // create testee. modify it if need
+ m_pTestee = new SymbolTable<>(m_StrTable);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+SymbolTableTest::~SymbolTableTest()
+{
+ delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void SymbolTableTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void SymbolTableTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+TEST_F(SymbolTableTest, init) {
+ mcld::SymbolTable<>::iterator it;
+ it = m_pTestee->begin();
+ ASSERT_EQ(it, m_pTestee->end());
+}
diff --git a/unittests/SymbolTableTest.h b/unittests/SymbolTableTest.h
new file mode 100644
index 0000000..9076ac9
--- /dev/null
+++ b/unittests/SymbolTableTest.h
@@ -0,0 +1,50 @@
+//===- SymbolTableTest.h --------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_SYMBOLTABLE_TEST_H
+#define LD_SYMBOLTABLE_TEST_H
+#include "mcld/LD/StringTable.h"
+#include <gtest.h>
+
+namespace mcld
+{
+ template <template <class> class, class>
+ class SymbolTable;
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class SymbolTableTest
+ * \brief
+ *
+ * \see SymbolTable
+ */
+class SymbolTableTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ SymbolTableTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~SymbolTableTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::SymbolTable<>* m_pTestee;
+ mcld::StringTable m_StrTable;
+};
+
+} // namespace of mcldtest
+
+#endif
diff --git a/unittests/TargetMachineTest.cpp b/unittests/TargetMachineTest.cpp
new file mode 100644
index 0000000..6258906
--- /dev/null
+++ b/unittests/TargetMachineTest.cpp
@@ -0,0 +1,42 @@
+//===- TargetMachineTest.cpp ----------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <TargetMachineTest.h>
+
+using namespace mcld;
+using namespace mcldTEST;
+
+
+// Constructor can do set-up work for all test here.
+TargetMachineTest::TargetMachineTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+TargetMachineTest::~TargetMachineTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void TargetMachineTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void TargetMachineTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F( TargetMachineTest, addPassesToEmitFile ) {
+ mcld::addPassesToEmitFile();
+}
+
diff --git a/unittests/TargetMachineTest.h b/unittests/TargetMachineTest.h
new file mode 100644
index 0000000..3f77da7
--- /dev/null
+++ b/unittests/TargetMachineTest.h
@@ -0,0 +1,41 @@
+//===- TargetMachineTest.h ------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef TARGETMACHINE_TEST_H
+#define TARGETMACHINE_TEST_H
+#include "mcld/Target/TargetMachine.h"
+#include <gtest.h>
+
+namespace mcldTEST
+{
+
+/** \class TargetMachineTest
+ * \brief
+ *
+ * \see TargetMachine
+ */
+class TargetMachineTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ TargetMachineTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~TargetMachineTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+};
+
+} // namespace of BOLDTEST
+
+#endif
+
diff --git a/unittests/UniqueGCFactoryBaseTest.cpp b/unittests/UniqueGCFactoryBaseTest.cpp
new file mode 100644
index 0000000..08f82ba
--- /dev/null
+++ b/unittests/UniqueGCFactoryBaseTest.cpp
@@ -0,0 +1,87 @@
+//===- UniqueGCFactoryBaseTest.cpp ----------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/ContextFactory.h"
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "UniqueGCFactoryBaseTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+UniqueGCFactoryBaseTest::UniqueGCFactoryBaseTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+UniqueGCFactoryBaseTest::~UniqueGCFactoryBaseTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void UniqueGCFactoryBaseTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void UniqueGCFactoryBaseTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( UniqueGCFactoryBaseTest, number_constructor ) {
+ ContextFactory *contextFactory = new ContextFactory(10);
+ contextFactory->produce("/");
+ contextFactory->produce("ab/c");
+ ASSERT_EQ( 2, contextFactory->size());
+ delete contextFactory;
+}
+
+TEST_F( UniqueGCFactoryBaseTest, unique_produce ) {
+ ContextFactory *contextFactory = new ContextFactory(10);
+ LDContext* context1 = contextFactory->produce("/");
+ contextFactory->produce("ab/c");
+ ASSERT_EQ( 2, contextFactory->size());
+ LDContext* context2 = contextFactory->produce("/");
+ ASSERT_EQ( context1, context2 );
+ delete contextFactory;
+}
+
+TEST_F( UniqueGCFactoryBaseTest, unique_produce2 ) {
+ ContextFactory *contextFactory = new ContextFactory(10);
+ LDContext* context1 = contextFactory->produce("abc/def");
+ contextFactory->produce("ab/c");
+ ASSERT_EQ( 2, contextFactory->size());
+ LDContext* context2 = contextFactory->produce("ttt/../abc/def");
+ ASSERT_EQ( context1, context2 );
+ delete contextFactory;
+}
+
+TEST_F( UniqueGCFactoryBaseTest, iterator )
+{
+ MemoryAreaFactory* memFactory = new MemoryAreaFactory(10);
+ MemoryArea* area1 = memFactory->produce("/home/luba", O_RDONLY);
+ MemoryArea* area2 = memFactory->produce("/home/jush", O_RDONLY);
+ ASSERT_NE( area1, area2);
+ MemoryArea* area3 = memFactory->produce("/home/jush/../luba", O_RDONLY);
+ ASSERT_EQ( area1, area3);
+ ASSERT_FALSE( memFactory->empty());
+ ASSERT_EQ( 2, memFactory->size());
+ MemoryAreaFactory::iterator aIter = memFactory->begin();
+ ASSERT_EQ( area1, &(*aIter));
+ ++aIter;
+ ASSERT_EQ( area2, &(*aIter));
+ ++aIter;
+ MemoryAreaFactory::iterator aEnd = memFactory->end();
+ ASSERT_TRUE( aEnd == aIter);
+ delete memFactory;
+}
+
diff --git a/unittests/UniqueGCFactoryBaseTest.h b/unittests/UniqueGCFactoryBaseTest.h
new file mode 100644
index 0000000..a1558e7
--- /dev/null
+++ b/unittests/UniqueGCFactoryBaseTest.h
@@ -0,0 +1,42 @@
+//===- UniqueGCFactoryBaseTest.h ------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef UNIQUE_GCFACTORYBASE_TEST_H
+#define UNIQUE_GCFACTORYBASE_TEST_H
+
+#include "mcld/Support/UniqueGCFactory.h"
+#include <gtest.h>
+
+namespace mcldtest
+{
+
+/** \class UniqueGCFactoryBaseTest
+ * - check the unique of key.
+ * - make sure the key associates with the same storage of value.
+ * - check if all functions in the GCFactoryBase are available.
+ */
+class UniqueGCFactoryBaseTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ UniqueGCFactoryBaseTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~UniqueGCFactoryBaseTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/test.txt b/unittests/test.txt
new file mode 100644
index 0000000..5b5a6a9
--- /dev/null
+++ b/unittests/test.txt
@@ -0,0 +1 @@
+This is a text for testing
diff --git a/unittests/test2.txt b/unittests/test2.txt
new file mode 100644
index 0000000..f1e9c6a
--- /dev/null
+++ b/unittests/test2.txt
Binary files differ
diff --git a/unittests/test3.txt b/unittests/test3.txt
new file mode 100644
index 0000000..2689bfd
--- /dev/null
+++ b/unittests/test3.txt
@@ -0,0 +1,296 @@
+HELLOopyright (C@@1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+# 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+#
+# This file 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# This Makefile contains release scripts for gdb, binutils, and other
+# packages which live in src. It used to be part of the top level Makefile,
+# but th@@ turned out to be very messy and hard to maintain.
+
+# This stuff really ought to be cleaned up and turned into something other
+# than a Makefile. As it is it's heavily recursive.
+
+# This is the name of this script (!). Needed due to horrible recursion.
+SELF = src-release
+
+SHELL = /bin/sh
+
+BZIPPROG = bzip2
+MD5PROG = md5sum
+
+# (Default to avoid splitting info files by setting the threshold high.)
+MAKEINFOFLAGS = --split-size=5000000
+
+# pwd command to use. Allow user to override default by setting PWDCMD in
+# the environment to account for automounters. The make variable must not
+# be called PWDCMD, otherwise the value set here is passed to make
+# subprocesses and overrides the setting from the user's environment.
+PWD = $${PWDCMD-pwd}
+
+#
+# Support for building net releases
+
+# Files in devo used in any net release.
+DEVO_SUPPORT= README Makefile.in configure configure.ac \
+ config.guess config.sub config move-if-change \
+ COPYING COPYING.LIB install-sh config-ml.in symlink-tree \
+ mkinstalldirs ltmain.sh missing ylwrap \
+ libtool.m4 ltsugar.m4 ltversion.m4 ltoptions.m4 \
+ Makefile.def Makefile.tpl src-release config.rpath \
+ ChangeLog MAINTAINERS README-maintainer-mode \
+ lt~obsolete.m4 ltgcc.m4 depcomp mkdep compile \
+ COPYING3 COPYING3.LIB
+
+# Files in devo/etc used in any net release.
+ETC_SUPPORT= Makefile.in configure configure.in standards.texi \
+ make-stds.texi standards.info* configure.texi configure.info* \
+ ChangeLog configbuild.* configdev.* fdl.texi texi2pod.pl gnu-oids.texi
+
+
+# When you use `make setup-dirs' or `make taz' you should always redefine
+# this macro.
+SUPPORT_FILES = list-of-support-files-for-tool-in-question
+
+# NOTE: No double quotes in the below. It is used within shell script
+# as VER="$(VER)"
+VER = ` if grep 'AM_INIT_AUTOMAKE.*BFD_VERSION' $(TOOL)/configure.in >/dev/null 2>&1; then \
+ sed < bfd/configure.in -n 's/AM_INIT_AUTOMAKE[^,]*, *\([^)]*\))/\1/p'; \
+ elif grep AM_INIT_AUTOMAKE $(TOOL)/configure.in >/dev/null 2>&1; then \
+ sed < $(TOOL)/configure.in -n 's/AM_INIT_AUTOMAKE[^,]*, *\([^)]*\))/\1/p'; \
+ elif test -f $(TOOL)/version.in; then \
+ head -1 $(TOOL)/version.in; \
+ elif grep VERSION $(TOOL)/Makefile.in > /dev/null 2>&1; then \
+ sed < $(TOOL)/Makefile.in -n 's/^VERSION *= *//p'; \
+ else \
+ echo VERSION; \
+ fi`
+PACKAGE = $(TOOL)
+
+.PHONY: taz
+taz: $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex
+ $(MAKE) -f $(SELF) do-proto-toplev \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+ $(MAKE) -f $(SELF) do-md5sum \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+ $(MAKE) -f $(SELF) do-tar \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+ $(MAKE) -f $(SELF) do-bz2 \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+
+.PHONY: gdb-tar
+gdb-tar: $(DEVO_SUPPORT)OH(SUPPORT_FILES) texinfo/texinfo.tex
+ $(MAKE) -f $(SELF) do-proto-toplev \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+ $(MAKE) -f $(SELF) do-md5sum \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+ $(MAKE) -f $(SELF) do-djunpack \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+ $(MAKE) -f $(SELF) do-tar \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+
+.PHONY: gdb-taz
+gdb-taz: gdb-tar $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex
+ $(MAKE) -f $(SELF) gdb-tar \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+ $(MAKE) -f $(SELF) do-bz2 \
+ TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(SUPPORT_FILES)"
+
+.PHONY: do-proto-toplev
+do-proto-toplev: $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex
+ echo "==> Making $(PACKAGE)-$(VER)/"
+ # Take out texinfo from a few places.
+ sed -e '/^all\.normal: /s/\all-texinfo //' \
+ -e '/^ install-texinfo /d' \
+ <Makefile.in >tmp
+ mv -f tmp Makefile.in
+ #
+ ./configure i686-pc-linux-gnu
+ $(MAKE) configure-host configure-target \
+ ALL_GCC="" ALL_GCC_C="" ALL_GCC_CXX="" \
+ CC_FOR_TARGET="$(CC)" CXX_FOR_TARGET="$(CXX)"
+ # Make links, and run "make diststuff" or "make info" when needed.
+ rm -rf proto-toplev ; mkdir proto-toplev
+ set -e ; dirs="$(DEVO_SUPPORT) $(SUPPORT_FILES) $(TOOL)" ; \
+ for d in $$dirs ; do \
+ if [ -d $$d ]; then \
+ if [ ! -f $$d/Makefile ] ; then true ; \
+ elif grep '^diststuff:' $$d/Makefile >/dev/null ; then \
+ (cd $$d ; $(MAKE) MAKEINFOFLAGS="$(MAKEINFOFLAGS)" \
+ diststuff ) || exit 1 ; \
+ elif grep '^info:' $$d/Makefile >/dev/null ; then \
+ (cd $$d ; $(MAKE) MAKEINFOFLAGS="$(MAKEINFOFLAGS)" \
+ info ) || exit 1 ; \
+ fi ; \
+ if [ -d $$d/proto-$$d.dir ]; then \
+ ln -s ../$$d/proto-$$d.dir proto-toplev/$$d ; \
+ else \
+ ln -s ../$$d proto-toplev/$$d ; \
+ fi ; \
+ else ln -s ../$$d proto-toplev/$$d ; fi ; \
+ done
+ cd etc && $(MAKE) MAKEINFOFLAGS="$(MAKEINFOFLAGS)" info
+ $(MAKE) distclean
+ # Kludge for pr gdb/857. intl/Makefile.in lacks a couple
+ # of files in the distclean rule. Zack W is planning to make
+ # the gcc version of intl/ the master version and then push
+ # that version to src soon. See:
+ # http://sources.redhat.com/ml/binutils/2003-07/msg00032.html
+ # After the src version of intl/ is upgraded, we can look at
+ # moving this logic into intl/Makefile.in distclean rule
+ # if it is still needed. -- chastain 2003-09-12
+ rm -f intl/config.cache
+ rm -f intl/config.status
+ rm -f intl/config.h
+ rm -f intl/stamp-h
+ #
+ mkdir proto-toplev/etc
+ (cd proto-toplev/etc; \
+ for i in $(ETC_SUPPORT); do \
+ ln -s ../../etc/$$i . ; \
+ done)
+ #
+ # Take out texinfo from configurable dirs
+ rm proto-toplev/configure.ac
+ sed -e '/^host_tools=/s/texinfo //' \
+ <configure.ac >proto-toplev/configure.ac
+ #
+ mkdir proto-toplev/texinfo
+ ln -s ../../texinfo/texinfo.tex proto-toplev/texinfo/
+ if test -r texinfo/util/tex3patch ; then \
+ mkdir proto-toplev/texinfo/util && \
+ ln -s ../../../texinfo/util/tex3patch proto-toplev/texinfo/util ; \
+ else true; fi
+ chmod -R og=u . || chmod og=u `find . -print`
+ #
+ # Create .gmo files from .po files.
+ for f in `find . -name '*.po' -type f -print`; do \
+ msgfmt -o `echo $$f | sed -e 's/\.po$$/.gmo/'` $$f ; \
+ done
+ #
+ -rm -f $(PACKAGE)-$(VER)
+ ln -s proto-toplev $(PACKAGE)-$(VER)
+
+CVS_NAMES= \( -name CVS -o -name '.cvsignore' \)
+
+.PHONY: do-tar
+do-tar:
+ echo "==> Making $(PACKAGE)-$(VER).tar"
+ -rm -f $(PACKAGE)-$(VER).tar
+ find $(PACKAGE)-$(VER) -follow $(CVS_NAMES) -prune \
+ -o -type f -print \
+ | tar cTfh - $(PACKAGE)-$(VER).tar
+
+.PHONY: do-bz2
+do-bz2:
+ echo "==> Bzipping $(PACKAGE)-$(VER).tar.bz2"
+ -rm -f $(PACKAGE)-$(VER).tar.bz2
+ $(BZIPPROG) -v -9 $(PACKAGE)-$(VER).tar
+
+.PHONY: do-md5sum
+do-md5sum:
+ echo "==> Adding md5 checksum to top-level directory"
+ cd proto-toplev && find * -follow $(CVS_NAMES) -prune \
+ -o -type f -print \
+ | xargs $(MD5PROG) > ../md5.new
+ -rm -f proto-toplev/md5.sum
+ mv md5.new proto-toplev/md5.sum
+
+.PHONY: do-djunpack
+do-djunpack:
+ echo "==> Adding updated djunpack.bat to top-level directory"
+ echo - 's /gdb-[0-9\.]*/$(PACKAGE)-'"$(VER)"'/'
+ sed < djunpack.bat > djunpack.new \
+ -e 's/gdb-[0-9][0-9\.]*/$(PACKAGE)-'"$(VER)"'/'
+ -rm -f proto-toplev/djunpack.bat
+ mv djunpack.new proto-toplev/djunpack.bat
+
+TEXINFO_SUPPORT= texinfo/texinfo.tex
+DIST_SUPPORT= $(DEVO_SUPPORT) $(TEXINFO_SUPPORT)
+
+.PHONY: gas.tar.bz2
+GAS_SUPPORT_DIRS= bfd include libiberty opcodes intl setup.com makefile.vms mkdep
+gas.tar.bz2: $(DIST_SUPPORT) $(GAS_SUPPORT_DIRS) gas
+ $(MAKE) -f $(SELF) taz TOOL=gas \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(GAS_SUPPORT_DIRS)"
+
+# The FSF "binutils" release includes gprof and ld.
+.PHONY: binutils.tar.bz2
+BINUTILS_SUPPORT_DIRS= bfd gas include libiberty opcodes ld elfcpp gold gprof intl setup.com makefile.vms cpu
+binutils.tar.bz2: $(DIST_SUPPORT) $(BINUTILS_SUPPORT_DIRS) binutils
+ $(MAKE) -f $(SELF) taz TOOL=binutils \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(BINUTILS_SUPPORT_DIRS)"
+
+.PHONY: gas+binutils.tar.bz2
+GASB_SUPPORT_DIRS= $(GAS_SUPPORT_DIRS) binutils ld gprof
+gas+binutils.tar.bz2: $(DIST_SUPPORT) $(GASB_SUPPORT_DIRS) gas
+ $(MAKE) -f $(SELF) taz TOOL=gas \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(GASB_SUPPORT_DIRS)"
+
+GNATS_SUPPORT_DIRS=include libiberty send-pr
+gnats.tar.bz2: $(DIST_SUPPORT) $(GNATS_SUPPORT_DIRS) gnats
+ $(MAKE) -f $(SELF) taz TOOL=gnats \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(GNATS_SUPPORT_DIRS)"
+
+.PHONY: gdb.tar.bz2
+GDB_SUPPORT_DIRS= bfd include libiberty opcodes readline sim intl libdecnumber
+gdb.tar.bz2: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+ $(MAKE) -f $(SELF) gdb-taz TOOL=gdb \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(GDB_SUPPORT_DIRS)"
+.PHONY: gdb.tar
+gdb.tar: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+ $(MAKE) -f $(SELF) gdb-tar TOOL=gdb \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(GDB_SUPPORT_DIRS)"
+
+.PHONY: insight.tar.bz2
+INSIGHT_SUPPORT_DIRS= $(GDB_SUPPORT_DIRS) tcl tk itcl libgui
+insight.tar.bz2: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+ $(MAKE) -f $(SELF) gdb-taz TOOL=gdb PACKAGE=insight \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(INSIGHT_SUPPORT_DIRS)"
+.PHONY: insight.tar
+insight.tar: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+ $(MAKE) -f $(SELF) gdb-tar TOOL=gdb PACKAGE=insight \
+ MD5PROG="$(MD5PROG)" \
+ SUPPORT_FILES="$(INSIGHT_SUPPORT_DIRS)"
+
+.NOEXPORT:
+MAKEOVERRIDES=