<commit_before>#include "commands.h"

#include <chrono>
#include <iostream>

#include "BuildAction.h"
#include "FileStates.h"

using namespace aBuild;

namespace commands {

bool build(std::string const& rootProjectName, bool verbose, bool noconsole, int jobs) {
	std::vector<Project const*> rootProjects;

	Workspace ws(".");

	checkingMissingPackages(ws);
	//checkingNotNeededPackages(ws);
	checkingInvalidPackages(ws);
	checkingRequiredPackages(ws);

	Graph graph;

	auto allToolchains = getAllToolchains(ws);
	auto allFlavors    = getAllFlavors(ws);

	Toolchain toolchain = allToolchains.rbegin()->second;
	std::string toolchainName = ws.accessConfigFile().getToolchain();
	std::string lastFlavor    = ws.accessConfigFile().getLastFlavor();

	std::string buildMode = ws.accessConfigFile().getBuildMode();

	if (allToolchains.find(toolchainName) != allToolchains.end()) {
		toolchain = allToolchains.at(toolchainName);
	}
	// check if flavor has toolchain
	if (allFlavors.find(lastFlavor) != allFlavors.end()) {
		auto flavor = allFlavors.at(lastFlavor);
		if (allToolchains.find(flavor.toolchain) != allToolchains.end()) {
			if (flavor.buildMode == "release" || flavor.buildMode == "debug") {
				buildMode = flavor.buildMode;
				toolchain = allToolchains.at(flavor.toolchain);
			}
		}
	}
	ws.accessConfigFile().setToolchain(toolchain.getName());
	ws.accessConfigFile().setBuildMode(buildMode);
	ws.save();

	auto timeSinceBegin = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());

	std::cout << "Using buildMode: " << ws.accessConfigFile().getBuildMode() << std::endl;
	std::cout << "Using toolchain: " << ws.accessConfigFile().getToolchain() << std::endl;

	std::unique_ptr<BuildAction> action { new BuildAction(&graph, verbose, &ws.accessConfigFile(), toolchain) };

	auto linkingLibFunc         = action->getLinkingLibFunc();
	auto linkingExecFunc        = action->getLinkingExecFunc();
	auto _compileFileCppFunc    = action->getCompileCppFileFunc();
	auto _compileFileCppFuncDep = action->getCompileCppFileFuncDep();
	auto _compileFileCFunc      = action->getCompileCFileFunc();
	auto _compileFileCFuncDep   = action->getCompileCFileFuncDep();

	std::function<bool(std::string*)> compileFileCppFunc = [&] (std::string* p){
		bool error = _compileFileCppFunc(p);
		_compileFileCppFuncDep(p);
		return error;
	};
	std::function<bool(std::string*)> compileFileCFunc = [&] (std::string* p) {
		bool error = _compileFileCFunc(p);
		_compileFileCFuncDep(p);
		return error;
	};

	auto excludedProjects = ws.getExcludedProjects();
	auto requiredProjects = ws.getAllRequiredProjects();

	auto packagesDir = utils::listDirs("packages", true);
	for (auto& p : packagesDir) {
		p = "packages/" + p;
	}
	packagesDir.push_back(".");

	std::vector<Project*> autoProjects;

	for (auto const& pDir : packagesDir) {
		if (not utils::fileExists(pDir + "/src")) continue;
		// Find auto projects
		auto projectDirs = utils::listDirs(pDir + "/src", true);
		for (auto const& d : projectDirs) {
			if (excludedProjects.count(d) != 0) continue;
			auto iter = requiredProjects.find(d);
			if (iter == requiredProjects.end()) {
				requiredProjects[d].set(d);
				requiredProjects[d].setPackagePath(pDir);
				requiredProjects[d].setAuto(true);
			}

			auto& project = requiredProjects.at(d);
			if (project.getIgnore()) continue;
			if (not project.getAuto()) continue;

			autoProjects.push_back(&project);
		}
	}
	for (auto p : autoProjects) {
		auto& project = *p;

		auto dep    = project.getDefaultDependencies(&ws, requiredProjects);
		auto optDep = project.getDefaultOptionalDependencies(&ws, requiredProjects);

		for (auto d : optDep) {
			auto iter = std::find(dep.begin(), dep.end(), d);
			while (iter != dep.end()) {
				dep.erase(iter);
				iter = std::find(dep.begin(), dep.end(), d);
			}
		}

		project.setDependencies(std::move(dep));
		project.setOptionalDependencies(std::move(optDep));
	}
	// save all the auto detected dependencies
	ws.save();

	// Create dependency tree
	auto projects = requiredProjects;
	for (auto& e  : projects) {
		auto& project = e.second;
		if (project.getIgnore()) continue;
		if (excludedProjects.count(project.getName()) != 0) continue;

		if ((project.getName() == rootProjectName) || (rootProjectName == "" && excludedProjects.size() > 0)) {
			rootProjects.push_back(&project);
		}

		// Adding linking
		if (project.getType() == "library") {
			graph.addNode(&project, linkingLibFunc);
		} else if (project.getType() == "executable") {
			graph.addNode(&project,  linkingExecFunc);
			if (rootProjectName == "" && excludedProjects.size() > 0) {
				rootProjects.push_back(&project);
			}
		} else {
			throw std::runtime_error("Project " + project.getName() + " has unknown type " + project.getType());
		}

		// Adding compile files
		for (auto& f : project.getAllCppFiles()) {
			graph.addNode(&f, compileFileCppFunc);
			graph.addEdge(&f, &project);
		}
		// Adding compile files
		for (auto& f : project.getAllCFiles()) {
			graph.addNode(&f, compileFileCFunc);
			graph.addEdge(&f, &project);
		}
		// adding dependencies between projects
		for (auto const& dep : project.getDependencies()) {
			auto l   = utils::explode(dep, "/");
			if (l.size() != 2) {
				throw std::runtime_error("Project " + project.getName() + " has unknown dependency " + dep);
			}
			auto key = l[l.size() -1];
			if (projects.find(key) == projects.end()) {
				throw std::runtime_error("Project " + project.getName() + " has unknown dependency " + dep);
			}
			graph.addEdge(&projects.at(key), &project);
		}
		// adding dependencies between optional projects
		for (auto const& dep : project.getOptionalDependencies()) {
			auto l   = utils::explode(dep, "/");
			if (l.size() != 2) {
				throw std::runtime_error("Project " + project.getName() + " has unknown dependency " + dep);
			}
			auto key = l[l.size() -1];
			if (projects.find(key) != projects.end()) {
				if (excludedProjects.count(key) == 0) {
					graph.addEdge(&projects.at(key), &project);
				}
			}
		}
	}

	if (rootProjects.size() > 0) {
		std::cout << "Compiling project(s): ";
		for (auto p : rootProjects) {
			std::cout << p->getName() << ", ";
		}
		std::cout << std::endl;
		// Removing stuff that is not a dependency on rootProject
		graph.removeUnreachableIngoing(rootProjects);
	}

	bool success = graph.visitAllNodes(jobs, [=](int done, int total, int totaltotal) {
		if (not noconsole) {
			std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
			std::cout << "working on job: " << done << "/" << total << "/" << totaltotal << std::flush;

			if (done == totaltotal) {
				std::cout << std::endl;
			}
		} else if (done == totaltotal) {
			std::cout << "working on job: "<< done << "/" << total << "/" << totaltotal << std::endl;
		}
	});
	if (not success) {
		std::cout<<"Build failed"<<std::endl;
		return false;
	} else {
		std::cout<<"Build succeeded"<<std::endl;
		ws.accessConfigFile().setLastCompileTime(timeSinceBegin.count());
		ws.save();
	}
	return true;
}

}

<commit_msg>Add color and build time<commit_after>#include "commands.h"

#include <chrono>
#include <iostream>

#include "BuildAction.h"
#include "FileStates.h"

using namespace aBuild;
namespace commands {

bool build(std::string const& rootProjectName, bool verbose, bool noconsole, int jobs) {
	std::vector<Project const*> rootProjects;

	Workspace ws(".");

	checkingMissingPackages(ws);
	//checkingNotNeededPackages(ws);
	checkingInvalidPackages(ws);
	checkingRequiredPackages(ws);

	Graph graph;

	auto allToolchains = getAllToolchains(ws);
	auto allFlavors    = getAllFlavors(ws);
	Toolchain toolchain = allToolchains.rbegin()->second;
	std::string toolchainName = ws.accessConfigFile().getToolchain();
	std::string lastFlavor    = ws.accessConfigFile().getLastFlavor();

	std::string buildMode = ws.accessConfigFile().getBuildMode();
	std::chrono::high_resolution_clock::time_point startTime = std::chrono::high_resolution_clock::now();

	if (allToolchains.find(toolchainName) != allToolchains.end()) {
		toolchain = allToolchains.at(toolchainName);
	}
	// check if flavor has toolchain
	if (allFlavors.find(lastFlavor) != allFlavors.end()) {
		auto flavor = allFlavors.at(lastFlavor);
		if (allToolchains.find(flavor.toolchain) != allToolchains.end()) {
			if (flavor.buildMode == "release" || flavor.buildMode == "debug") {
				buildMode = flavor.buildMode;
				toolchain = allToolchains.at(flavor.toolchain);
			}
		}
	}
	ws.accessConfigFile().setToolchain(toolchain.getName());
	ws.accessConfigFile().setBuildMode(buildMode);
	ws.save();

	auto timeSinceBegin = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());

	std::cout << "Using buildMode: " << ws.accessConfigFile().getBuildMode() << std::endl;
	std::cout << "Using toolchain: " << ws.accessConfigFile().getToolchain() << std::endl;

	std::unique_ptr<BuildAction> action { new BuildAction(&graph, verbose, &ws.accessConfigFile(), toolchain) };

	auto linkingLibFunc         = action->getLinkingLibFunc();
	auto linkingExecFunc        = action->getLinkingExecFunc();
	auto _compileFileCppFunc    = action->getCompileCppFileFunc();
	auto _compileFileCppFuncDep = action->getCompileCppFileFuncDep();
	auto _compileFileCFunc      = action->getCompileCFileFunc();
	auto _compileFileCFuncDep   = action->getCompileCFileFuncDep();

	std::function<bool(std::string*)> compileFileCppFunc = [&] (std::string* p){
		bool error = _compileFileCppFunc(p);
		_compileFileCppFuncDep(p);
		return error;
	};
	std::function<bool(std::string*)> compileFileCFunc = [&] (std::string* p) {
		bool error = _compileFileCFunc(p);
		_compileFileCFuncDep(p);
		return error;
	};

	auto excludedProjects = ws.getExcludedProjects();
	auto requiredProjects = ws.getAllRequiredProjects();

	auto packagesDir = utils::listDirs("packages", true);
	for (auto& p : packagesDir) {
		p = "packages/" + p;
	}
	packagesDir.push_back(".");

	std::vector<Project*> autoProjects;

	for (auto const& pDir : packagesDir) {
		if (not utils::fileExists(pDir + "/src")) continue;
		// Find auto projects
		auto projectDirs = utils::listDirs(pDir + "/src", true);
		for (auto const& d : projectDirs) {
			if (excludedProjects.count(d) != 0) continue;
			auto iter = requiredProjects.find(d);
			if (iter == requiredProjects.end()) {
				requiredProjects[d].set(d);
				requiredProjects[d].setPackagePath(pDir);
				requiredProjects[d].setAuto(true);
			}

			auto& project = requiredProjects.at(d);
			if (project.getIgnore()) continue;
			if (not project.getAuto()) continue;

			autoProjects.push_back(&project);
		}
	}
	for (auto p : autoProjects) {
		auto& project = *p;

		auto dep    = project.getDefaultDependencies(&ws, requiredProjects);
		auto optDep = project.getDefaultOptionalDependencies(&ws, requiredProjects);

		for (auto d : optDep) {
			auto iter = std::find(dep.begin(), dep.end(), d);
			while (iter != dep.end()) {
				dep.erase(iter);
				iter = std::find(dep.begin(), dep.end(), d);
			}
		}

		project.setDependencies(std::move(dep));
		project.setOptionalDependencies(std::move(optDep));
	}
	// save all the auto detected dependencies
	ws.save();

	// Create dependency tree
	auto projects = requiredProjects;
	for (auto& e  : projects) {
		auto& project = e.second;
		if (project.getIgnore()) continue;
		if (excludedProjects.count(project.getName()) != 0) continue;

		if ((project.getName() == rootProjectName) || (rootProjectName == "" && excludedProjects.size() > 0)) {
			rootProjects.push_back(&project);
		}

		// Adding linking
		if (project.getType() == "library") {
			graph.addNode(&project, linkingLibFunc);
		} else if (project.getType() == "executable") {
			graph.addNode(&project,  linkingExecFunc);
			if (rootProjectName == "" && excludedProjects.size() > 0) {
				rootProjects.push_back(&project);
			}
		} else {
			throw std::runtime_error("Project " + project.getName() + " has unknown type " + project.getType());
		}

		// Adding compile files
		for (auto& f : project.getAllCppFiles()) {
			graph.addNode(&f, compileFileCppFunc);
			graph.addEdge(&f, &project);
		}
		// Adding compile files
		for (auto& f : project.getAllCFiles()) {
			graph.addNode(&f, compileFileCFunc);
			graph.addEdge(&f, &project);
		}
		// adding dependencies between projects
		for (auto const& dep : project.getDependencies()) {
			auto l   = utils::explode(dep, "/");
			if (l.size() != 2) {
				throw std::runtime_error("Project " + project.getName() + " has unknown dependency " + dep);
			}
			auto key = l[l.size() -1];
			if (projects.find(key) == projects.end()) {
				throw std::runtime_error("Project " + project.getName() + " has unknown dependency " + dep);
			}
			graph.addEdge(&projects.at(key), &project);
		}
		// adding dependencies between optional projects
		for (auto const& dep : project.getOptionalDependencies()) {
			auto l   = utils::explode(dep, "/");
			if (l.size() != 2) {
				throw std::runtime_error("Project " + project.getName() + " has unknown dependency " + dep);
			}
			auto key = l[l.size() -1];
			if (projects.find(key) != projects.end()) {
				if (excludedProjects.count(key) == 0) {
					graph.addEdge(&projects.at(key), &project);
				}
			}
		}
	}

	if (rootProjects.size() > 0) {
		std::cout << "Compiling project(s): ";
		for (auto p : rootProjects) {
			std::cout << p->getName() << ", ";
		}
		std::cout << std::endl;
		// Removing stuff that is not a dependency on rootProject
		graph.removeUnreachableIngoing(rootProjects);
	}

	bool success = graph.visitAllNodes(jobs, [=](int done, int total, int totaltotal) {
		if (not noconsole) {
			std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
			std::cout << "working on job: " << done << "/" << total << "/" << totaltotal << std::flush;

			if (done == totaltotal) {
				std::cout << std::endl;
			}
		} else if (done == totaltotal) {
			std::cout << "working on job: "<< done << "/" << total << "/" << totaltotal << std::endl;
		}
	});

	std::chrono::high_resolution_clock::time_point endTime = std::chrono::high_resolution_clock::now();
	std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(endTime - startTime);

	if (not success) {
		std::cout<<std::endl<<"Build \033[31mfailed\033[0m";
		std::cout<< " after " << time_span.count() << " seconds." << std::endl;
		return false;
	} else {
		std::cout<<std::endl<<"Build \033[32msucceeded\033[0m";
		std::cout << " after " << time_span.count() << " seconds." << std::endl;
		ws.accessConfigFile().setLastCompileTime(timeSinceBegin.count());
		ws.save();
	}
	return true;
}

}

<|endoftext|>


<commit_before>#include "list.h"
#include "gtest/gtest.h"
#include <string>

class listTest : public testing::Test {
 protected:
  virtual void SetUp() {
    list_1.insert(list_1.begin(), 10);
    int_iter = list_1.insert(list_1.end(), 30);
    int_iter = list_1.insert(int_iter, 20);
    str = "a string";
  }
  virtual void TearDown() {}
  // class constant

  // setup fixtures
  ::list<int> list_1;
  ::list<int> list_2;
  list<int> list_empty;
  ::list<std::string> list_str;
  list<int>::iterator int_iter;
  list<std::string>::iterator str_iter;
  std::string str;
};

class listIteratorTest : public testing::Test {
  // try to make friend with list_const_iterator DOES NOT WORK here
  // because friendship must be made before template is resolved:
  // friend class list_const_iterator<int>;
 protected:
  virtual void SetUp() {
    head_ = new listNode<int> (0);
    head_->next_ = new listNode<int> (10);
    tail_ = head_->next_->next_ = new listNode<int> (20);
    head_->next_->prev_ = head_;
    tail_->prev_ = head_->next_;
    c_iter = list_const_iterator<int> (head_);
    c_iter_1 = list_const_iterator<int> (head_->next_);
    iter = list_iterator<int> (head_);
    iter_1 = list_iterator<int> (head_->next_);
  }

  virtual void TearDown() {
    delete tail_;
    delete head_->next_;
    delete head_;
  }
  listNode<int>* head_;
  listNode<int>* tail_;
  list_const_iterator<int> c_iter;
  list_const_iterator<int> c_iter_1;
  list_iterator<int> iter;
  list_iterator<int> iter_1;

};

// test the helper class listNodeTest
// this is a canonical example of writing testable code:
// to test private members, just write another helper class
// and make its data public
TEST(listHelperTest, ListNode) {
  int element_1 = 100;
  std::string element_2("Hello world");
  listNode<int> node_1(element_1);
  listNode<std::string> node_2(element_2);
  EXPECT_EQ(element_1, node_1.element_);
  EXPECT_EQ(element_2, node_2.element_);
  EXPECT_EQ(nullptr, node_2.prev_);
  EXPECT_EQ(nullptr, node_2.next_);
  // test the move constructor for node:
  listNode<int> node_3(std::move(element_1));
  listNode<std::string> node_4(std::move(element_2));
  EXPECT_EQ(100, node_3.element_);
  EXPECT_EQ("Hello world", node_4.element_);
  EXPECT_TRUE(element_2.empty());
}

TEST_F(listIteratorTest, ConstIterator) {
  list_const_iterator<int> c_iter_temp = c_iter;
  // testing increment and decrement of const_iterator
  EXPECT_EQ(++c_iter_temp, c_iter_1);
  EXPECT_EQ(--c_iter_temp, c_iter);
  EXPECT_EQ(c_iter_temp++, c_iter);
  EXPECT_EQ(c_iter_temp, c_iter_1);
  EXPECT_EQ(c_iter_temp--, c_iter_1);
  EXPECT_EQ(c_iter_temp, c_iter);
  EXPECT_TRUE(c_iter_temp == c_iter);
  EXPECT_TRUE(c_iter_temp != c_iter_1);

  // testing access capability of const_iterator
  EXPECT_EQ(0, *c_iter_temp);
  EXPECT_EQ(10, *(++c_iter_temp));
  EXPECT_EQ(20, *(++c_iter_temp));
  EXPECT_EQ(10, *(--c_iter_temp));

  // testing non-modifying capability of const_iterator:
  // will not even compile:
  //*c_iter_temp = 100;
}

TEST_F(listIteratorTest, Iterator) {
  list_iterator<int> iter_temp = iter;
  // testing increment and decrement of iterator
  // which are all inherited from base
  EXPECT_EQ(++iter_temp, iter_1);
  EXPECT_EQ(--iter_temp, iter);
  EXPECT_EQ(iter_temp++, iter);
  EXPECT_EQ(iter_temp, iter_1);
  EXPECT_EQ(iter_temp--, iter_1);
  EXPECT_EQ(iter_temp, iter);
  EXPECT_TRUE(iter_temp == iter);
  EXPECT_TRUE(iter_temp != iter_1);

  // testing access capability of iterator
  EXPECT_EQ(0, *iter_temp);
  EXPECT_EQ(10, *(++iter_temp));
  EXPECT_EQ(20, *(++iter_temp));
  EXPECT_EQ(10, *(--iter_temp));

  // testing modifying capability of iterator:
  *iter_temp = 100;
  EXPECT_EQ(*iter_temp, 100);
}

TEST_F(listTest, DefaultCtor) {
  EXPECT_EQ(0u, list_empty.size());
  EXPECT_TRUE(list_empty.empty());
}

TEST_F(listTest, CopyCtor) {
  for (int i = 0; i < 100; i++) {
    list_1.push_back(i);
  }
  const list<int> list_temp = list_1;
  EXPECT_EQ(list_temp.size(), list_1.size());
  int_iter = list_1.begin();
  list<int>::const_iterator temp_iter = list_temp.begin();
  while(temp_iter != list_temp.end()
        && int_iter != list_1.end())
  {
    EXPECT_EQ(*temp_iter++, *int_iter++);
  }

  // edge case: empty list
  list<int> list_nothing = list_empty;
  EXPECT_TRUE(list_nothing.empty());
}

TEST_F(listTest, BeginEnd) {
  EXPECT_EQ(list_empty.begin(), list_empty.end());
  // decrement pass begin() and increment pass end() should be ok
  EXPECT_NO_FATAL_FAILURE(--list_empty.begin());
  EXPECT_NO_FATAL_FAILURE(++list_empty.end());
}

TEST_F(listTest, InsertLvalue) {
  // iter is pointing to tail_
  list<int>::iterator iter = list_empty.begin();
  // testing iterator insert (iterator, const E&)
  int x = 10;
  list<int>::iterator ret_iter = list_empty.insert(iter, x);
  EXPECT_TRUE(--iter == ret_iter);
  // iter--;
  EXPECT_EQ(*ret_iter, 10);
  EXPECT_EQ(list_empty.size(), 1);
  EXPECT_EQ(++ret_iter, list_empty.end());
  --ret_iter; // set ret_iter to point to 10
  ret_iter = list_empty.insert(ret_iter, x + 10);
  EXPECT_EQ(list_empty.size(), 2);
  EXPECT_EQ(*ret_iter, 20);
  EXPECT_EQ(*(++ret_iter), 10);
  EXPECT_TRUE(++ret_iter == list_empty.end());

  // insert pass begin() and pass end() should fail
  // the following would not even compile:
  // list_empty.insert(++list_empty.end(), 100);
  // list_empty.insert(--list_empty.begin(), 100);
}

TEST_F(listTest, InsertRvalue) {
  size_t old_size = list_str.size();
  str_iter = list_str.insert(list_str.begin(), std::move(str));
  EXPECT_EQ(*str_iter, "a string");
  EXPECT_TRUE(str_iter == list_str.begin());
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_TRUE(str.empty());
}

TEST_F(listTest, InsertConstObject) {
  // insert const object by lvalue:
  const std::string const_str("const string");
  const std::string CONST_STR(const_str);

  size_t old_size = list_str.size();
  str_iter = list_str.insert(list_str.begin(), const_str);
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*str_iter, CONST_STR);
  EXPECT_EQ(const_str, CONST_STR);

  // insert const objects by rvalue:
  // std::move automatically degrade to a copy insert
  str_iter = list_str.insert(list_str.begin(), std::move(const_str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*str_iter, CONST_STR);
  EXPECT_EQ(const_str, CONST_STR);
}

TEST_F(listTest, EraseAtIter) {
  int_iter = list_1.erase(list_1.begin()); // erase 10
  EXPECT_EQ(list_1.size(), 2);
  EXPECT_EQ(*list_1.begin(), 20);
  EXPECT_EQ(*int_iter, 20);
  int_iter = list_1.erase(int_iter); // erase 20
  int_iter = list_1.erase(int_iter); // erase 30
  // test for seg fault if erase end()
  // it trigers a memory leak error right before core dump,
  // which it is expected. Turned off when running memtest
  //EXPECT_DEATH(int_iter = list_1.erase(list_1.end()), "");
}

TEST_F(listTest, PushFront) {
  // lvalue version
  size_t old_size = list_1.size();
  list_1.push_front(100);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*list_1.begin(), 100);

  list_1.push_front(200);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*list_1.begin(), 200);
  EXPECT_EQ(*(++list_1.begin()), 100);
  EXPECT_TRUE(--(++list_1.begin()) == list_1.begin());

  // rvalue version
  old_size = list_str.size();
  list_str.push_front(std::move(str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*list_str.begin(), "a string");
  EXPECT_TRUE(str.empty());
}

TEST_F(listTest, PushBack) {
  // lvalue version
  size_t old_size = list_1.size();
  list_1.push_back(1000);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*(--list_1.end()), 1000);

  list_1.push_back(2000);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*(--list_1.end()), 2000);
  EXPECT_EQ(*(--(--list_1.end())), 1000);
  EXPECT_TRUE(++(--list_1.end()) == list_1.end());

  // rvalue version
  old_size = list_str.size();
  list_str.push_back(std::move(str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*(--list_str.end()), "a string");
  EXPECT_TRUE(str.empty());
}
<commit_msg>list: add tests for assignment operator<commit_after>#include "list.h"
#include "gtest/gtest.h"
#include <string>

class listTest : public testing::Test {
 protected:
  virtual void SetUp() {
    list_1.insert(list_1.begin(), 10);
    int_iter = list_1.insert(list_1.end(), 30);
    int_iter = list_1.insert(int_iter, 20);
    str = "a string";
  }
  virtual void TearDown() {}
  // class constant

  // setup fixtures
  ::list<int> list_1;
  ::list<int> list_2;
  list<int> list_empty;
  ::list<std::string> list_str;
  list<int>::iterator int_iter;
  list<std::string>::iterator str_iter;
  std::string str;
};

class listIteratorTest : public testing::Test {
  // try to make friend with list_const_iterator DOES NOT WORK here
  // because friendship must be made before template is resolved:
  // friend class list_const_iterator<int>;
 protected:
  virtual void SetUp() {
    head_ = new listNode<int> (0);
    head_->next_ = new listNode<int> (10);
    tail_ = head_->next_->next_ = new listNode<int> (20);
    head_->next_->prev_ = head_;
    tail_->prev_ = head_->next_;
    c_iter = list_const_iterator<int> (head_);
    c_iter_1 = list_const_iterator<int> (head_->next_);
    iter = list_iterator<int> (head_);
    iter_1 = list_iterator<int> (head_->next_);
  }

  virtual void TearDown() {
    delete tail_;
    delete head_->next_;
    delete head_;
  }
  listNode<int>* head_;
  listNode<int>* tail_;
  list_const_iterator<int> c_iter;
  list_const_iterator<int> c_iter_1;
  list_iterator<int> iter;
  list_iterator<int> iter_1;

};

// test the helper class listNodeTest
// this is a canonical example of writing testable code:
// to test private members, just write another helper class
// and make its data public
TEST(listHelperTest, ListNode) {
  int element_1 = 100;
  std::string element_2("Hello world");
  listNode<int> node_1(element_1);
  listNode<std::string> node_2(element_2);
  EXPECT_EQ(element_1, node_1.element_);
  EXPECT_EQ(element_2, node_2.element_);
  EXPECT_EQ(nullptr, node_2.prev_);
  EXPECT_EQ(nullptr, node_2.next_);
  // test the move constructor for node:
  listNode<int> node_3(std::move(element_1));
  listNode<std::string> node_4(std::move(element_2));
  EXPECT_EQ(100, node_3.element_);
  EXPECT_EQ("Hello world", node_4.element_);
  EXPECT_TRUE(element_2.empty());
}

TEST_F(listIteratorTest, ConstIterator) {
  list_const_iterator<int> c_iter_temp = c_iter;
  // testing increment and decrement of const_iterator
  EXPECT_EQ(++c_iter_temp, c_iter_1);
  EXPECT_EQ(--c_iter_temp, c_iter);
  EXPECT_EQ(c_iter_temp++, c_iter);
  EXPECT_EQ(c_iter_temp, c_iter_1);
  EXPECT_EQ(c_iter_temp--, c_iter_1);
  EXPECT_EQ(c_iter_temp, c_iter);
  EXPECT_TRUE(c_iter_temp == c_iter);
  EXPECT_TRUE(c_iter_temp != c_iter_1);

  // testing access capability of const_iterator
  EXPECT_EQ(0, *c_iter_temp);
  EXPECT_EQ(10, *(++c_iter_temp));
  EXPECT_EQ(20, *(++c_iter_temp));
  EXPECT_EQ(10, *(--c_iter_temp));

  // testing non-modifying capability of const_iterator:
  // will not even compile:
  //*c_iter_temp = 100;
}

TEST_F(listIteratorTest, Iterator) {
  list_iterator<int> iter_temp = iter;
  // testing increment and decrement of iterator
  // which are all inherited from base
  EXPECT_EQ(++iter_temp, iter_1);
  EXPECT_EQ(--iter_temp, iter);
  EXPECT_EQ(iter_temp++, iter);
  EXPECT_EQ(iter_temp, iter_1);
  EXPECT_EQ(iter_temp--, iter_1);
  EXPECT_EQ(iter_temp, iter);
  EXPECT_TRUE(iter_temp == iter);
  EXPECT_TRUE(iter_temp != iter_1);

  // testing access capability of iterator
  EXPECT_EQ(0, *iter_temp);
  EXPECT_EQ(10, *(++iter_temp));
  EXPECT_EQ(20, *(++iter_temp));
  EXPECT_EQ(10, *(--iter_temp));

  // testing modifying capability of iterator:
  *iter_temp = 100;
  EXPECT_EQ(*iter_temp, 100);
}

TEST_F(listTest, DefaultCtor) {
  EXPECT_EQ(0u, list_empty.size());
  EXPECT_TRUE(list_empty.empty());
}

TEST_F(listTest, CopyCtor) {
  for (int i = 0; i < 100; i++) {
    list_1.push_back(i);
  }
  const list<int> list_temp = list_1;
  EXPECT_EQ(list_temp.size(), list_1.size());
  int_iter = list_1.begin();
  list<int>::const_iterator temp_iter = list_temp.begin();
  while(temp_iter != list_temp.end()
        && int_iter != list_1.end())
  {
    EXPECT_EQ(*temp_iter++, *int_iter++);
  }

  // edge case: empty list
  list<int> list_nothing = list_empty;
  EXPECT_TRUE(list_nothing.empty());
}

TEST_F(listTest, AssigmentOperator) {
  for (int i = 0; i < 100; i++) {
    list_1.push_back(i);
  }
  list_2 = list_1;
  EXPECT_EQ(list_2.size(), list_1.size());
  int_iter = list_1.begin();
  list<int>::const_iterator temp_iter = list_2.begin();
  while(temp_iter != list_2.end()
        && int_iter != list_1.end())
  {
    EXPECT_EQ(*temp_iter++, *int_iter++);
  }

  // edge case: empty list
  list_1 = list_empty;
  EXPECT_TRUE(list_1.empty());

  // edge case: self-assign
  const list<int> old_list_2 = list_2;
  list_2 = list_2;
  // make sure list_2 is not emptied
  EXPECT_EQ(list_2.size(), old_list_2.size());
  // TODO: compare list_2 and old_list_2 elementwise
}

TEST_F(listTest, BeginEnd) {
  EXPECT_EQ(list_empty.begin(), list_empty.end());
  // decrement pass begin() and increment pass end() should be ok
  EXPECT_NO_FATAL_FAILURE(--list_empty.begin());
  EXPECT_NO_FATAL_FAILURE(++list_empty.end());
}

TEST_F(listTest, InsertLvalue) {
  // iter is pointing to tail_
  list<int>::iterator iter = list_empty.begin();
  // testing iterator insert (iterator, const E&)
  int x = 10;
  list<int>::iterator ret_iter = list_empty.insert(iter, x);
  EXPECT_TRUE(--iter == ret_iter);
  // iter--;
  EXPECT_EQ(*ret_iter, 10);
  EXPECT_EQ(list_empty.size(), 1);
  EXPECT_EQ(++ret_iter, list_empty.end());
  --ret_iter; // set ret_iter to point to 10
  ret_iter = list_empty.insert(ret_iter, x + 10);
  EXPECT_EQ(list_empty.size(), 2);
  EXPECT_EQ(*ret_iter, 20);
  EXPECT_EQ(*(++ret_iter), 10);
  EXPECT_TRUE(++ret_iter == list_empty.end());

  // insert pass begin() and pass end() should fail
  // the following would not even compile:
  // list_empty.insert(++list_empty.end(), 100);
  // list_empty.insert(--list_empty.begin(), 100);
}

TEST_F(listTest, InsertRvalue) {
  size_t old_size = list_str.size();
  str_iter = list_str.insert(list_str.begin(), std::move(str));
  EXPECT_EQ(*str_iter, "a string");
  EXPECT_TRUE(str_iter == list_str.begin());
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_TRUE(str.empty());
}

TEST_F(listTest, InsertConstObject) {
  // insert const object by lvalue:
  const std::string const_str("const string");
  const std::string CONST_STR(const_str);

  size_t old_size = list_str.size();
  str_iter = list_str.insert(list_str.begin(), const_str);
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*str_iter, CONST_STR);
  EXPECT_EQ(const_str, CONST_STR);

  // insert const objects by rvalue:
  // std::move automatically degrade to a copy insert
  str_iter = list_str.insert(list_str.begin(), std::move(const_str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*str_iter, CONST_STR);
  EXPECT_EQ(const_str, CONST_STR);
}

TEST_F(listTest, EraseAtIter) {
  int_iter = list_1.erase(list_1.begin()); // erase 10
  EXPECT_EQ(list_1.size(), 2);
  EXPECT_EQ(*list_1.begin(), 20);
  EXPECT_EQ(*int_iter, 20);
  int_iter = list_1.erase(int_iter); // erase 20
  int_iter = list_1.erase(int_iter); // erase 30
  // test for seg fault if erase end()
  // it trigers a memory leak error right before core dump,
  // which it is expected. Turned off when running memtest
  //EXPECT_DEATH(int_iter = list_1.erase(list_1.end()), "");
}

TEST_F(listTest, PushFront) {
  // lvalue version
  size_t old_size = list_1.size();
  list_1.push_front(100);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*list_1.begin(), 100);

  list_1.push_front(200);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*list_1.begin(), 200);
  EXPECT_EQ(*(++list_1.begin()), 100);
  EXPECT_TRUE(--(++list_1.begin()) == list_1.begin());

  // rvalue version
  old_size = list_str.size();
  list_str.push_front(std::move(str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*list_str.begin(), "a string");
  EXPECT_TRUE(str.empty());
}

TEST_F(listTest, PushBack) {
  // lvalue version
  size_t old_size = list_1.size();
  list_1.push_back(1000);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*(--list_1.end()), 1000);

  list_1.push_back(2000);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*(--list_1.end()), 2000);
  EXPECT_EQ(*(--(--list_1.end())), 1000);
  EXPECT_TRUE(++(--list_1.end()) == list_1.end());

  // rvalue version
  old_size = list_str.size();
  list_str.push_back(std::move(str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*(--list_str.end()), "a string");
  EXPECT_TRUE(str.empty());
}
<|endoftext|>


<commit_before>#ifndef LIGHTGBM_PREDICTOR_HPP_
#define LIGHTGBM_PREDICTOR_HPP_

#include <LightGBM/meta.h>
#include <LightGBM/boosting.h>
#include <LightGBM/utils/text_reader.h>
#include <LightGBM/dataset.h>

#include <LightGBM/utils/openmp_wrapper.h>

#include <cstring>
#include <cstdio>
#include <vector>
#include <utility>
#include <functional>
#include <string>
#include <memory>

namespace LightGBM {

/*!
* \brief Used to predict data with input model
*/
class Predictor {
public:
  /*!
  * \brief Constructor
  * \param boosting Input boosting model
  * \param num_iteration Number of boosting round
  * \param is_raw_score True if need to predict result with raw score
  * \param is_predict_leaf_index True if output leaf index instead of prediction score
  */
  Predictor(Boosting* boosting, int num_iteration,
            bool is_raw_score, bool is_predict_leaf_index,
            bool early_stop, int early_stop_freq, double early_stop_margin) {

    early_stop_ = CreatePredictionEarlyStopInstance("none", LightGBM::PredictionEarlyStopConfig());
    if (early_stop && !boosting->NeedAccuratePrediction()) {
      PredictionEarlyStopConfig pred_early_stop_config;
      pred_early_stop_config.margin_threshold = early_stop_margin;
      pred_early_stop_config.round_period = early_stop_freq;
      if (boosting->NumberOfClasses() == 1) {
        early_stop_ = CreatePredictionEarlyStopInstance("binary", pred_early_stop_config);
      } else {
        early_stop_ = CreatePredictionEarlyStopInstance("multiclass", pred_early_stop_config);
      }
    }

    #pragma omp parallel
    #pragma omp master
    {
      num_threads_ = omp_get_num_threads();
    }
    boosting->InitPredict(num_iteration);
    boosting_ = boosting;
    num_pred_one_row_ = boosting_->NumPredictOneRow(num_iteration, is_predict_leaf_index);
    num_feature_ = boosting_->MaxFeatureIdx() + 1;
    predict_buf_ = std::vector<std::vector<double>>(num_threads_, std::vector<double>(num_feature_, 0.0f));

    if (is_predict_leaf_index) {
      predict_fun_ = [this](const std::vector<std::pair<int, double>>& features, double* output) {
        int tid = omp_get_thread_num();
        CopyToPredictBuffer(predict_buf_[tid].data(), features);
        // get result for leaf index
        boosting_->PredictLeafIndex(predict_buf_[tid].data(), output);
        ClearPredictBuffer(predict_buf_[tid].data(), predict_buf_[tid].size(), features);
      };

    } else {
      if (is_raw_score) {
        predict_fun_ = [this](const std::vector<std::pair<int, double>>& features, double* output) {
          int tid = omp_get_thread_num();
          CopyToPredictBuffer(predict_buf_[tid].data(), features);
          boosting_->PredictRaw(predict_buf_[tid].data(), output, &early_stop_);
          ClearPredictBuffer(predict_buf_[tid].data(), predict_buf_[tid].size(), features);
        };
      } else {
        predict_fun_ = [this](const std::vector<std::pair<int, double>>& features, double* output) {
          int tid = omp_get_thread_num();
          CopyToPredictBuffer(predict_buf_[tid].data(), features);
          boosting_->Predict(predict_buf_[tid].data(), output, &early_stop_);
          ClearPredictBuffer(predict_buf_[tid].data(), predict_buf_[tid].size(), features);
        };
      }
    }
  }

  /*!
  * \brief Destructor
  */
  ~Predictor() {
  }

  inline const PredictFunction& GetPredictFunction() const {
    return predict_fun_;
  }

  /*!
  * \brief predicting on data, then saving result to disk
  * \param data_filename Filename of data
  * \param result_filename Filename of output result
  */
  void Predict(const char* data_filename, const char* result_filename, bool has_header) {
    FILE* result_file;

    #ifdef _MSC_VER
    fopen_s(&result_file, result_filename, "w");
    #else
    result_file = fopen(result_filename, "w");
    #endif

    if (result_file == NULL) {
      Log::Fatal("Prediction results file %s doesn't exist", data_filename);
    }
    auto parser = std::unique_ptr<Parser>(Parser::CreateParser(data_filename, has_header, boosting_->MaxFeatureIdx() + 1, boosting_->LabelIdx()));

    if (parser == nullptr) {
      Log::Fatal("Could not recognize the data format of data file %s", data_filename);
    }

    // function for parse data
    std::function<void(const char*, std::vector<std::pair<int, double>>*)> parser_fun;
    double tmp_label;
    parser_fun = [this, &parser, &tmp_label]
    (const char* buffer, std::vector<std::pair<int, double>>* feature) {
      parser->ParseOneLine(buffer, feature, &tmp_label);
    };

    std::function<void(data_size_t, const std::vector<std::string>&)> process_fun =
      [this, &parser_fun, &result_file]
    (data_size_t, const std::vector<std::string>& lines) {
      std::vector<std::pair<int, double>> oneline_features;
      std::vector<std::string> result_to_write(lines.size());
      OMP_INIT_EX();
      #pragma omp parallel for schedule(static) firstprivate(oneline_features)
      for (data_size_t i = 0; i < static_cast<data_size_t>(lines.size()); ++i) {
        OMP_LOOP_EX_BEGIN();
        oneline_features.clear();
        // parser
        parser_fun(lines[i].c_str(), &oneline_features);
        // predict
        std::vector<double> result(num_pred_one_row_);
        predict_fun_(oneline_features, result.data());
        auto str_result = Common::Join<double>(result, "\t");
        result_to_write[i] = str_result;
        OMP_LOOP_EX_END();
      }
      OMP_THROW_EX();
      for (data_size_t i = 0; i < static_cast<data_size_t>(result_to_write.size()); ++i) {
        fprintf(result_file, "%s\n", result_to_write[i].c_str());
      }
    };
    TextReader<data_size_t> predict_data_reader(data_filename, has_header);
    predict_data_reader.ReadAllAndProcessParallel(process_fun);
    fclose(result_file);
  }

private:

  void CopyToPredictBuffer(double* pred_buf, const std::vector<std::pair<int, double>>& features) {
    int loop_size = static_cast<int>(features.size());
    for (int i = 0; i < loop_size; ++i) {
      if (features[i].first < num_feature_) {
        pred_buf[features[i].first] = features[i].second;
      }
    }
  }

  void ClearPredictBuffer(double* pred_buf, size_t buf_size, const std::vector<std::pair<int, double>>& features) {
    if (features.size() < static_cast<size_t>(buf_size / 2)) {
      std::memset(pred_buf, 0, sizeof(double)*(buf_size));
    } else {
      int loop_size = static_cast<int>(features.size());
      for (int i = 0; i < loop_size; ++i) {
        pred_buf[features[i].first] = 0.0f;
      }
    }
  }

  /*! \brief Boosting model */
  const Boosting* boosting_;
  /*! \brief function for prediction */
  PredictFunction predict_fun_;
  PredictionEarlyStopInstance early_stop_;
  int num_feature_;
  int num_pred_one_row_;
  int num_threads_;
  std::vector<std::vector<double>> predict_buf_;
};

}  // namespace LightGBM

#endif   // LightGBM_PREDICTOR_HPP_
<commit_msg>fix #596<commit_after>#ifndef LIGHTGBM_PREDICTOR_HPP_
#define LIGHTGBM_PREDICTOR_HPP_

#include <LightGBM/meta.h>
#include <LightGBM/boosting.h>
#include <LightGBM/utils/text_reader.h>
#include <LightGBM/dataset.h>

#include <LightGBM/utils/openmp_wrapper.h>

#include <cstring>
#include <cstdio>
#include <vector>
#include <utility>
#include <functional>
#include <string>
#include <memory>

namespace LightGBM {

/*!
* \brief Used to predict data with input model
*/
class Predictor {
public:
  /*!
  * \brief Constructor
  * \param boosting Input boosting model
  * \param num_iteration Number of boosting round
  * \param is_raw_score True if need to predict result with raw score
  * \param is_predict_leaf_index True if output leaf index instead of prediction score
  */
  Predictor(Boosting* boosting, int num_iteration,
            bool is_raw_score, bool is_predict_leaf_index,
            bool early_stop, int early_stop_freq, double early_stop_margin) {

    early_stop_ = CreatePredictionEarlyStopInstance("none", LightGBM::PredictionEarlyStopConfig());
    if (early_stop && !boosting->NeedAccuratePrediction()) {
      PredictionEarlyStopConfig pred_early_stop_config;
      pred_early_stop_config.margin_threshold = early_stop_margin;
      pred_early_stop_config.round_period = early_stop_freq;
      if (boosting->NumberOfClasses() == 1) {
        early_stop_ = CreatePredictionEarlyStopInstance("binary", pred_early_stop_config);
      } else {
        early_stop_ = CreatePredictionEarlyStopInstance("multiclass", pred_early_stop_config);
      }
    }

    #pragma omp parallel
    #pragma omp master
    {
      num_threads_ = omp_get_num_threads();
    }
    boosting->InitPredict(num_iteration);
    boosting_ = boosting;
    num_pred_one_row_ = boosting_->NumPredictOneRow(num_iteration, is_predict_leaf_index);
    num_feature_ = boosting_->MaxFeatureIdx() + 1;
    predict_buf_ = std::vector<std::vector<double>>(num_threads_, std::vector<double>(num_feature_, 0.0f));

    if (is_predict_leaf_index) {
      predict_fun_ = [this](const std::vector<std::pair<int, double>>& features, double* output) {
        int tid = omp_get_thread_num();
        CopyToPredictBuffer(predict_buf_[tid].data(), features);
        // get result for leaf index
        boosting_->PredictLeafIndex(predict_buf_[tid].data(), output);
        ClearPredictBuffer(predict_buf_[tid].data(), predict_buf_[tid].size(), features);
      };

    } else {
      if (is_raw_score) {
        predict_fun_ = [this](const std::vector<std::pair<int, double>>& features, double* output) {
          int tid = omp_get_thread_num();
          CopyToPredictBuffer(predict_buf_[tid].data(), features);
          boosting_->PredictRaw(predict_buf_[tid].data(), output, &early_stop_);
          ClearPredictBuffer(predict_buf_[tid].data(), predict_buf_[tid].size(), features);
        };
      } else {
        predict_fun_ = [this](const std::vector<std::pair<int, double>>& features, double* output) {
          int tid = omp_get_thread_num();
          CopyToPredictBuffer(predict_buf_[tid].data(), features);
          boosting_->Predict(predict_buf_[tid].data(), output, &early_stop_);
          ClearPredictBuffer(predict_buf_[tid].data(), predict_buf_[tid].size(), features);
        };
      }
    }
  }

  /*!
  * \brief Destructor
  */
  ~Predictor() {
  }

  inline const PredictFunction& GetPredictFunction() const {
    return predict_fun_;
  }

  /*!
  * \brief predicting on data, then saving result to disk
  * \param data_filename Filename of data
  * \param result_filename Filename of output result
  */
  void Predict(const char* data_filename, const char* result_filename, bool has_header) {
    FILE* result_file;

    #ifdef _MSC_VER
    fopen_s(&result_file, result_filename, "w");
    #else
    result_file = fopen(result_filename, "w");
    #endif

    if (result_file == NULL) {
      Log::Fatal("Prediction results file %s doesn't exist", data_filename);
    }
    auto parser = std::unique_ptr<Parser>(Parser::CreateParser(data_filename, has_header, boosting_->MaxFeatureIdx() + 1, boosting_->LabelIdx()));

    if (parser == nullptr) {
      Log::Fatal("Could not recognize the data format of data file %s", data_filename);
    }

    // function for parse data
    std::function<void(const char*, std::vector<std::pair<int, double>>*)> parser_fun;
    double tmp_label;
    parser_fun = [this, &parser, &tmp_label]
    (const char* buffer, std::vector<std::pair<int, double>>* feature) {
      parser->ParseOneLine(buffer, feature, &tmp_label);
    };

    std::function<void(data_size_t, const std::vector<std::string>&)> process_fun =
      [this, &parser_fun, &result_file]
    (data_size_t, const std::vector<std::string>& lines) {
      std::vector<std::pair<int, double>> oneline_features;
      std::vector<std::string> result_to_write(lines.size());
      OMP_INIT_EX();
      #pragma omp parallel for schedule(static) firstprivate(oneline_features)
      for (data_size_t i = 0; i < static_cast<data_size_t>(lines.size()); ++i) {
        OMP_LOOP_EX_BEGIN();
        oneline_features.clear();
        // parser
        parser_fun(lines[i].c_str(), &oneline_features);
        // predict
        std::vector<double> result(num_pred_one_row_);
        predict_fun_(oneline_features, result.data());
        auto str_result = Common::Join<double>(result, "\t");
        result_to_write[i] = str_result;
        OMP_LOOP_EX_END();
      }
      OMP_THROW_EX();
      for (data_size_t i = 0; i < static_cast<data_size_t>(result_to_write.size()); ++i) {
        fprintf(result_file, "%s\n", result_to_write[i].c_str());
      }
    };
    TextReader<data_size_t> predict_data_reader(data_filename, has_header);
    predict_data_reader.ReadAllAndProcessParallel(process_fun);
    fclose(result_file);
  }

private:

  void CopyToPredictBuffer(double* pred_buf, const std::vector<std::pair<int, double>>& features) {
    int loop_size = static_cast<int>(features.size());
    for (int i = 0; i < loop_size; ++i) {
      if (features[i].first < num_feature_) {
        pred_buf[features[i].first] = features[i].second;
      }
    }
  }

  void ClearPredictBuffer(double* pred_buf, size_t buf_size, const std::vector<std::pair<int, double>>& features) {
    if (features.size() < static_cast<size_t>(buf_size / 2)) {
      std::memset(pred_buf, 0, sizeof(double)*(buf_size));
    } else {
      int loop_size = static_cast<int>(features.size());
      for (int i = 0; i < loop_size; ++i) {
        if (features[i].first < num_feature_) {
          pred_buf[features[i].first] = 0.0f;
        }
      }
    }
  }

  /*! \brief Boosting model */
  const Boosting* boosting_;
  /*! \brief function for prediction */
  PredictFunction predict_fun_;
  PredictionEarlyStopInstance early_stop_;
  int num_feature_;
  int num_pred_one_row_;
  int num_threads_;
  std::vector<std::vector<double>> predict_buf_;
};

}  // namespace LightGBM

#endif   // LightGBM_PREDICTOR_HPP_
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "qt4symbiantargetfactory.h"
#include "qt4projectmanagerconstants.h"
#include "qt4project.h"
#include "buildconfigurationinfo.h"

#include "qt-s60/s60deployconfiguration.h"
#include "qt-s60/s60devicerunconfiguration.h"
#include "qt-s60/s60emulatorrunconfiguration.h"
#include "qt-s60/s60createpackagestep.h"
#include "qt-s60/s60deploystep.h"
#include "qt-s60/qt4symbiantarget.h"

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/customexecutablerunconfiguration.h>
#include <projectexplorer/toolchainmanager.h>

using ProjectExplorer::idFromMap;
using ProjectExplorer::Task;
using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

// -------------------------------------------------------------------------
// Qt4SymbianTargetFactory
// -------------------------------------------------------------------------

Qt4SymbianTargetFactory::Qt4SymbianTargetFactory(QObject *parent) :
    Qt4BaseTargetFactory(parent)
{
    connect(QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>)),
            this, SIGNAL(supportedTargetIdsChanged()));
}

Qt4SymbianTargetFactory::~Qt4SymbianTargetFactory()
{
}

bool Qt4SymbianTargetFactory::supportsTargetId(const QString &id) const
{
    return id == QLatin1String(Constants::S60_DEVICE_TARGET_ID)
            || id == QLatin1String(Constants::S60_EMULATOR_TARGET_ID);
}

QStringList Qt4SymbianTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const
{
    if (parent && !qobject_cast<Qt4Project *>(parent))
        return QStringList();

    QStringList ids;
    if (QtVersionManager::instance()->supportsTargetId(Constants::S60_DEVICE_TARGET_ID))
        ids << QLatin1String(Constants::S60_DEVICE_TARGET_ID);
    if (QtVersionManager::instance()->supportsTargetId(Constants::S60_EMULATOR_TARGET_ID))
        ids << QLatin1String(Constants::S60_EMULATOR_TARGET_ID);

    return ids;
}

QString Qt4SymbianTargetFactory::displayNameForId(const QString &id) const
{
    return Qt4SymbianTarget::defaultDisplayName(id);
}

QIcon Qt4SymbianTargetFactory::iconForId(const QString &id) const
{
    if (id == QLatin1String(Constants::S60_EMULATOR_TARGET_ID))
        return QIcon(":/projectexplorer/images/SymbianEmulator.png");
    if (id == QLatin1String(Constants::S60_DEVICE_TARGET_ID))
        return QIcon(":/projectexplorer/images/SymbianDevice.png");
    return QIcon();
}

bool Qt4SymbianTargetFactory::canCreate(ProjectExplorer::Project *parent, const QString &id) const
{
    if (!qobject_cast<Qt4Project *>(parent))
        return false;
    return supportsTargetId(id);
}

bool Qt4SymbianTargetFactory::canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const
{
    return canCreate(parent, idFromMap(map));
}

ProjectExplorer::Target *Qt4SymbianTargetFactory::restore(ProjectExplorer::Project *parent, const QVariantMap &map)
{
    if (!canRestore(parent, map))
        return 0;

    Qt4Project *qt4project = static_cast<Qt4Project *>(parent);
    Qt4SymbianTarget *target = new Qt4SymbianTarget(qt4project, idFromMap(map));

    if (target->fromMap(map))
        return target;
    delete target;
    return 0;
}

QString Qt4SymbianTargetFactory::defaultShadowBuildDirectory(const QString &projectLocation, const QString &id)
{
    Q_UNUSED(projectLocation);
    Q_UNUSED(id);
    // should not be called from anywhere, since we override Qt4BaseTarget::defaultBuldDirectory()
    return QString();
}

QList<ProjectExplorer::Task> Qt4SymbianTargetFactory::reportIssues(const QString &proFile)
{
    QList<ProjectExplorer::Task> results;
    // Warn of strange characters in project name and path:
    const QString projectName = proFile.mid(proFile.lastIndexOf(QLatin1Char('/')) + 1);
    QString projectPath = proFile.left(proFile.lastIndexOf(QLatin1Char('/')));
#if defined (Q_OS_WIN)
    if (projectPath.at(1) == QChar(':') && projectPath.at(0).toUpper() >= QChar('A') && projectPath.at(0).toUpper() <= QChar('Z'))
        projectPath = projectPath.mid(2);
#endif
    if (projectPath.contains(QLatin1Char(' '))) {
        results.append(Task(Task::Warning,
                            QCoreApplication::translate("ProjectExplorer::Internal::S60ProjectChecker",
                                                        "The Symbian tool chain does not handle spaces "
                                                        "in the project path '%1'.").arg(projectPath),
                            QString(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
    }
    if (projectName.contains(QRegExp("[^a-zA-Z0-9.-]"))) {
        results.append(Task(Task::Warning,
                            QCoreApplication::translate("ProjectExplorer::Internal::S60ProjectChecker",
                                                        "The Symbian tool chain does not handle special "
                                                        "characters in the project name '%1' well.")
                            .arg(projectName),
                            QString(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
    }
    return results;
}

QList<BuildConfigurationInfo> Qt4SymbianTargetFactory::availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion)
{
    QList<BuildConfigurationInfo> infos;
    QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id, minimumQtVersion);

    foreach (QtVersion *version, knownVersions) {
        if (!version->isValid() || !version->toolChainAvailable())
            continue;

        bool buildAll = version->defaultBuildConfig() & QtVersion::BuildAll;
        QtVersion::QmakeBuildConfigs config = buildAll ? QtVersion::BuildAll : QtVersion::QmakeBuildConfig(0);
        QString dir = QFileInfo(proFilePath).absolutePath(), id;
        if (id == Constants::S60_EMULATOR_TARGET_ID) {
            infos.append(BuildConfigurationInfo(version, config | QtVersion::DebugBuild, QString(), dir));
        } else {
            infos.append(BuildConfigurationInfo(version, config, QString(), dir));
            infos.append(BuildConfigurationInfo(version, config ^ QtVersion::DebugBuild, QString(), dir));
        }
    }

    return infos;
}

bool Qt4SymbianTargetFactory::isMobileTarget(const QString &id)
{
    Q_UNUSED(id)
    return true;
}

ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id)
{
    if (!canCreate(parent, id))
        return 0;

    QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id);
    if (knownVersions.isEmpty())
        return 0;

    QtVersion *qtVersion = knownVersions.first();
    QtVersion::QmakeBuildConfigs config = qtVersion->defaultBuildConfig();

    QList<BuildConfigurationInfo> infos;
    if (id != Constants::S60_EMULATOR_TARGET_ID) {
        infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString()));
        infos.append(BuildConfigurationInfo(qtVersion, config ^ QtVersion::DebugBuild, QString(), QString()));
    } else {
        if(config & QtVersion::DebugBuild)
            infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString()));
        else
            infos.append(BuildConfigurationInfo(qtVersion, config ^ QtVersion::DebugBuild, QString(), QString()));
    }

    return create(parent, id, infos);
}

ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos)
{
    if (!canCreate(parent, id))
        return 0;
    Qt4SymbianTarget *t = new Qt4SymbianTarget(static_cast<Qt4Project *>(parent), id);
    foreach (const BuildConfigurationInfo &info, infos)
        t->addQt4BuildConfiguration(msgBuildConfigurationName(info),
                                    info.version, info.buildConfig,
                                    info.additionalArguments, info.directory);

    t->addDeployConfiguration(t->deployConfigurationFactory()->create(t, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));

    t->createApplicationProFiles();

    if (t->runConfigurations().isEmpty())
        t->addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(t));
    return t;
}

ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, Qt4TargetSetupWidget *widget)
{
    if (!widget->isTargetSelected())
        return 0;
    Qt4DefaultTargetSetupWidget *w = static_cast<Qt4DefaultTargetSetupWidget *>(widget);
    return create(parent, id, w->buildConfigurationInfos());
}
<commit_msg>Fix deploy configuration for symbian<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "qt4symbiantargetfactory.h"
#include "qt4projectmanagerconstants.h"
#include "qt4project.h"
#include "buildconfigurationinfo.h"

#include "qt-s60/s60deployconfiguration.h"
#include "qt-s60/s60devicerunconfiguration.h"
#include "qt-s60/s60emulatorrunconfiguration.h"
#include "qt-s60/s60createpackagestep.h"
#include "qt-s60/s60deploystep.h"
#include "qt-s60/qt4symbiantarget.h"

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/customexecutablerunconfiguration.h>
#include <projectexplorer/toolchainmanager.h>

using ProjectExplorer::idFromMap;
using ProjectExplorer::Task;
using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

// -------------------------------------------------------------------------
// Qt4SymbianTargetFactory
// -------------------------------------------------------------------------

Qt4SymbianTargetFactory::Qt4SymbianTargetFactory(QObject *parent) :
    Qt4BaseTargetFactory(parent)
{
    connect(QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>)),
            this, SIGNAL(supportedTargetIdsChanged()));
}

Qt4SymbianTargetFactory::~Qt4SymbianTargetFactory()
{
}

bool Qt4SymbianTargetFactory::supportsTargetId(const QString &id) const
{
    return id == QLatin1String(Constants::S60_DEVICE_TARGET_ID)
            || id == QLatin1String(Constants::S60_EMULATOR_TARGET_ID);
}

QStringList Qt4SymbianTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const
{
    if (parent && !qobject_cast<Qt4Project *>(parent))
        return QStringList();

    QStringList ids;
    if (QtVersionManager::instance()->supportsTargetId(Constants::S60_DEVICE_TARGET_ID))
        ids << QLatin1String(Constants::S60_DEVICE_TARGET_ID);
    if (QtVersionManager::instance()->supportsTargetId(Constants::S60_EMULATOR_TARGET_ID))
        ids << QLatin1String(Constants::S60_EMULATOR_TARGET_ID);

    return ids;
}

QString Qt4SymbianTargetFactory::displayNameForId(const QString &id) const
{
    return Qt4SymbianTarget::defaultDisplayName(id);
}

QIcon Qt4SymbianTargetFactory::iconForId(const QString &id) const
{
    if (id == QLatin1String(Constants::S60_EMULATOR_TARGET_ID))
        return QIcon(":/projectexplorer/images/SymbianEmulator.png");
    if (id == QLatin1String(Constants::S60_DEVICE_TARGET_ID))
        return QIcon(":/projectexplorer/images/SymbianDevice.png");
    return QIcon();
}

bool Qt4SymbianTargetFactory::canCreate(ProjectExplorer::Project *parent, const QString &id) const
{
    if (!qobject_cast<Qt4Project *>(parent))
        return false;
    return supportsTargetId(id);
}

bool Qt4SymbianTargetFactory::canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const
{
    return canCreate(parent, idFromMap(map));
}

ProjectExplorer::Target *Qt4SymbianTargetFactory::restore(ProjectExplorer::Project *parent, const QVariantMap &map)
{
    if (!canRestore(parent, map))
        return 0;

    Qt4Project *qt4project = static_cast<Qt4Project *>(parent);
    Qt4SymbianTarget *target = new Qt4SymbianTarget(qt4project, idFromMap(map));

    if (target->fromMap(map))
        return target;
    delete target;
    return 0;
}

QString Qt4SymbianTargetFactory::defaultShadowBuildDirectory(const QString &projectLocation, const QString &id)
{
    Q_UNUSED(projectLocation);
    Q_UNUSED(id);
    // should not be called from anywhere, since we override Qt4BaseTarget::defaultBuldDirectory()
    return QString();
}

QList<ProjectExplorer::Task> Qt4SymbianTargetFactory::reportIssues(const QString &proFile)
{
    QList<ProjectExplorer::Task> results;
    // Warn of strange characters in project name and path:
    const QString projectName = proFile.mid(proFile.lastIndexOf(QLatin1Char('/')) + 1);
    QString projectPath = proFile.left(proFile.lastIndexOf(QLatin1Char('/')));
#if defined (Q_OS_WIN)
    if (projectPath.at(1) == QChar(':') && projectPath.at(0).toUpper() >= QChar('A') && projectPath.at(0).toUpper() <= QChar('Z'))
        projectPath = projectPath.mid(2);
#endif
    if (projectPath.contains(QLatin1Char(' '))) {
        results.append(Task(Task::Warning,
                            QCoreApplication::translate("ProjectExplorer::Internal::S60ProjectChecker",
                                                        "The Symbian tool chain does not handle spaces "
                                                        "in the project path '%1'.").arg(projectPath),
                            QString(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
    }
    if (projectName.contains(QRegExp("[^a-zA-Z0-9.-]"))) {
        results.append(Task(Task::Warning,
                            QCoreApplication::translate("ProjectExplorer::Internal::S60ProjectChecker",
                                                        "The Symbian tool chain does not handle special "
                                                        "characters in the project name '%1' well.")
                            .arg(projectName),
                            QString(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
    }
    return results;
}

QList<BuildConfigurationInfo> Qt4SymbianTargetFactory::availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion)
{
    QList<BuildConfigurationInfo> infos;
    QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id, minimumQtVersion);

    foreach (QtVersion *version, knownVersions) {
        if (!version->isValid() || !version->toolChainAvailable())
            continue;

        bool buildAll = version->defaultBuildConfig() & QtVersion::BuildAll;
        QtVersion::QmakeBuildConfigs config = buildAll ? QtVersion::BuildAll : QtVersion::QmakeBuildConfig(0);
        QString dir = QFileInfo(proFilePath).absolutePath(), id;
        if (id == Constants::S60_EMULATOR_TARGET_ID) {
            infos.append(BuildConfigurationInfo(version, config | QtVersion::DebugBuild, QString(), dir));
        } else {
            infos.append(BuildConfigurationInfo(version, config, QString(), dir));
            infos.append(BuildConfigurationInfo(version, config ^ QtVersion::DebugBuild, QString(), dir));
        }
    }

    return infos;
}

bool Qt4SymbianTargetFactory::isMobileTarget(const QString &id)
{
    Q_UNUSED(id)
    return true;
}

ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id)
{
    if (!canCreate(parent, id))
        return 0;

    QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id);
    if (knownVersions.isEmpty())
        return 0;

    QtVersion *qtVersion = knownVersions.first();
    QtVersion::QmakeBuildConfigs config = qtVersion->defaultBuildConfig();

    QList<BuildConfigurationInfo> infos;
    if (id != Constants::S60_EMULATOR_TARGET_ID) {
        infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString()));
        infos.append(BuildConfigurationInfo(qtVersion, config ^ QtVersion::DebugBuild, QString(), QString()));
    } else {
        if(config & QtVersion::DebugBuild)
            infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString()));
        else
            infos.append(BuildConfigurationInfo(qtVersion, config ^ QtVersion::DebugBuild, QString(), QString()));
    }

    return create(parent, id, infos);
}

ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos)
{
    if (!canCreate(parent, id))
        return 0;
    Qt4SymbianTarget *t = new Qt4SymbianTarget(static_cast<Qt4Project *>(parent), id);
    foreach (const BuildConfigurationInfo &info, infos)
        t->addQt4BuildConfiguration(msgBuildConfigurationName(info),
                                    info.version, info.buildConfig,
                                    info.additionalArguments, info.directory);

    t->addDeployConfiguration(t->createDeployConfiguration(QLatin1String(Qt4ProjectManager::Constants::S60_DEVICE_TARGET_ID)));

    t->createApplicationProFiles();

    if (t->runConfigurations().isEmpty())
        t->addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(t));
    return t;
}

ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, Qt4TargetSetupWidget *widget)
{
    if (!widget->isTargetSelected())
        return 0;
    Qt4DefaultTargetSetupWidget *w = static_cast<Qt4DefaultTargetSetupWidget *>(widget);
    return create(parent, id, w->buildConfigurationInfos());
}
<|endoftext|>


<commit_before>#include <QtTest>

#include <timing/calendartiming.h>

class TestCalendarTiming : public QObject
{
    Q_OBJECT

private slots:
    void constructors()
    {
        CalendarTiming timing;

        QCOMPARE(timing.type(), QLatin1String("calendar"));
    }

    void nextRuns()
    {
        QTime time = QTime::currentTime();
        time = QTime(time.hour(), time.minute(), time.second());
        QDateTime now = QDateTime::currentDateTime();
        now.setTime(time);

        QDateTime start = QDateTime::currentDateTime();
        QDateTime end;
        QList<int> months = QList<int>()<<1<<2<<3<<4<<5<<6<<7<<8<<9<<10<<11<<12;
        QList<int> daysOfWeek = QList<int>()<<1<<2<<3<<4<<5<<6<<7;
        QList<int> daysOfMonth;
        QList<int> hours;
        QList<int> minutes;
        QList<int> seconds;

        for (int i = 1; i < 32; i++)
        {
            daysOfMonth<<i;
        }

        for (int i = 0; i < 24; i++)
        {
            hours<<i;
        }

        for (int i = 0; i < 60; i++)
        {
            minutes<<i;
            seconds<<i;
        }

        // start now
        CalendarTiming nowTiming(start, end, months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("start time now");
        QCOMPARE(nowTiming.nextRun(), now);

        // start time in the future
        CalendarTiming futureTiming(start.addDays(1), end, months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("start time one day in the future");
        QCOMPARE(futureTiming.nextRun(), now.addDays(1));

        // end time already reached
        CalendarTiming pastTiming(start.addDays(1), start.addDays(-1), months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("end time already reached");
        QCOMPARE(pastTiming.nextRun(), QDateTime());

        // start tomorrow because hour already passed today (not true before 4 am)
        CalendarTiming tomorrowTiming(start, end, months, daysOfWeek, daysOfMonth, QList<int>()<<4, minutes, seconds);
        qDebug("nextRun tomorrow because hour already passed today (4 am)");
        QDateTime tomorrowTime = now.addDays(1);
        tomorrowTime.setTime(QTime(4,0,0));
        QCOMPARE(tomorrowTiming.nextRun(), tomorrowTime);

        // start tomorrow because hour already passed today (not true before 4 am [2])
        CalendarTiming tomorrowTiming2(start, end, months, daysOfWeek, daysOfMonth, QList<int>()<<4<<5, minutes, seconds);
        qDebug("nextRun tomorrow because hour already passed today (4 and 5 am)");
        QCOMPARE(tomorrowTiming2.nextRun(), tomorrowTime);

        // start next month because day already passed this month (not true on 1st of month)
        CalendarTiming nextMonthTiming(start, end, months, daysOfWeek, QList<int>()<<1, hours, minutes, seconds);
        qDebug("nextRun next month because day already passed this month (1st)");
        QDateTime nextMonthTime = now.addMonths(1);
        nextMonthTime.setTime(QTime(0,0,0));
        nextMonthTime.setDate(QDate(nextMonthTime.date().year(), nextMonthTime.date().month(), 1));
        QCOMPARE(nextMonthTiming.nextRun(), nextMonthTime);

        // start next month because day already passed this month (not true on 1st or 2nd of month)
        CalendarTiming nextMonthTiming2(start, end, months, daysOfWeek, QList<int>()<<1<<2, hours, minutes, seconds);
        qDebug("nextRun next month because day already passed this month (1st and 2nd)");
        QCOMPARE(nextMonthTiming2.nextRun(), nextMonthTime);

        // no nextRun because of invalid Timing (February 30th)
        CalendarTiming februaryTiming(start, end,  QList<int>()<<2, daysOfWeek, QList<int>()<<30, hours, minutes, seconds);
        qDebug("no nextRun because invalid Timing (30.02)");
        QCOMPARE(februaryTiming.nextRun(), QDateTime());

        // start next year because day already passed this year (not true on January 1st)
        CalendarTiming yearTiming(start, end,  QList<int>()<<1, daysOfWeek, QList<int>()<<1, hours, minutes, seconds);
        qDebug("nextRun on January 1st");
        QCOMPARE(yearTiming.nextRun(), QDateTime(QDate(now.date().year()+1, 1, 1), QTime(0,0,0)));
    }
};

QTEST_MAIN(TestCalendarTiming)

#include "tst_calendartiming.moc"
<commit_msg>Changed Timing-Unittests to work on the first two days of the month (quickfix for now)<commit_after>#include <QtTest>

#include <timing/calendartiming.h>

class TestCalendarTiming : public QObject
{
    Q_OBJECT

private slots:
    void constructors()
    {
        CalendarTiming timing;

        QCOMPARE(timing.type(), QLatin1String("calendar"));
    }

    void nextRuns()
    {
        QTime time = QTime::currentTime();
        time = QTime(time.hour(), time.minute(), time.second());
        QDateTime now = QDateTime::currentDateTime();
        now.setTime(time);

        QDateTime start = QDateTime::currentDateTime();
        QDateTime end;
        QList<int> months = QList<int>()<<1<<2<<3<<4<<5<<6<<7<<8<<9<<10<<11<<12;
        QList<int> daysOfWeek = QList<int>()<<1<<2<<3<<4<<5<<6<<7;
        QList<int> daysOfMonth;
        QList<int> hours;
        QList<int> minutes;
        QList<int> seconds;

        for (int i = 1; i < 32; i++)
        {
            daysOfMonth<<i;
        }

        for (int i = 0; i < 24; i++)
        {
            hours<<i;
        }

        for (int i = 0; i < 60; i++)
        {
            minutes<<i;
            seconds<<i;
        }

        // start now
        CalendarTiming nowTiming(start, end, months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("start time now");
        QCOMPARE(nowTiming.nextRun(), now);

        // start time in the future
        CalendarTiming futureTiming(start.addDays(1), end, months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("start time one day in the future");
        QCOMPARE(futureTiming.nextRun(), now.addDays(1));

        // end time already reached
        CalendarTiming pastTiming(start.addDays(1), start.addDays(-1), months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("end time already reached");
        QCOMPARE(pastTiming.nextRun(), QDateTime());

        if (now.time().hour() > 3)
        {
            // start tomorrow because hour already passed today (not true before 4 am)
            CalendarTiming tomorrowTiming(start, end, months, daysOfWeek, daysOfMonth, QList<int>()<<4, minutes, seconds);
            qDebug("nextRun tomorrow because hour already passed today (4 am)");
            QDateTime tomorrowTime = now.addDays(1);
            tomorrowTime.setTime(QTime(4,0,0));
            QCOMPARE(tomorrowTiming.nextRun(), tomorrowTime);

            // start tomorrow because hour already passed today (not true before 4 am [2])
            CalendarTiming tomorrowTiming2(start, end, months, daysOfWeek, daysOfMonth, QList<int>()<<4<<5, minutes, seconds);
            qDebug("nextRun tomorrow because hour already passed today (4 and 5 am)");
            QCOMPARE(tomorrowTiming2.nextRun(), tomorrowTime);
        }

        if (now.date().day() > 1)
        {
            // start next month because day already passed this month (not true on 1st of month)
            CalendarTiming nextMonthTiming(start, end, months, daysOfWeek, QList<int>()<<1, hours, minutes, seconds);
            qDebug("nextRun next month because day already passed this month (1st)");
            QDateTime nextMonthTime = now.addMonths(1);
            nextMonthTime.setTime(QTime(0,0,0));
            nextMonthTime.setDate(QDate(nextMonthTime.date().year(), nextMonthTime.date().month(), 1));
            QCOMPARE(nextMonthTiming.nextRun(), nextMonthTime);
        }

        // start next month because day already passed this month (not true on 1st or 2nd of month)
        if (now.date().day() > 2)
        {
            QDateTime nextMonthTime = now.addMonths(1);
            CalendarTiming nextMonthTiming2(start, end, months, daysOfWeek, QList<int>()<<1<<2, hours, minutes, seconds);
            qDebug("nextRun next month because day already passed this month (1st and 2nd)");
            QCOMPARE(nextMonthTiming2.nextRun(), nextMonthTime);
        }

        // no nextRun because of invalid Timing (February 30th)
        CalendarTiming februaryTiming(start, end,  QList<int>()<<2, daysOfWeek, QList<int>()<<30, hours, minutes, seconds);
        qDebug("no nextRun because invalid Timing (30.02)");
        QCOMPARE(februaryTiming.nextRun(), QDateTime());

        if (now.date().month() > 1 || now.date().day() > 1)
        {
            // start next year because day already passed this year (not true on January 1st)
            CalendarTiming yearTiming(start, end,  QList<int>()<<1, daysOfWeek, QList<int>()<<1, hours, minutes, seconds);
            qDebug("nextRun on January 1st");
            QCOMPARE(yearTiming.nextRun(), QDateTime(QDate(now.date().year()+1, 1, 1), QTime(0,0,0)));
        }
    }
};

QTEST_MAIN(TestCalendarTiming)

#include "tst_calendartiming.moc"
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * Written by James D. Berry 7/20/00
 * Critical Path Software, Inc.
 */

/*
 * $Id$
 */

#if !defined(URLACCESSBININPUTSTREAM_HPP)
#define URLACCESSBININPUTSTREAM_HPP

#include <util/XMLURL.hpp>
#include <util/XMLExceptMsgs.hpp>
#include <util/BinInputStream.hpp>

#if defined(TARGET_API_MAC_CARBON)
	#include <Carbon.h>
#else
	#include <URLAccess.h>
#endif

//
// This class implements the BinInputStream interface specified by the XML
// parser.
//

class XMLUTIL_EXPORT URLAccessBinInputStream : public BinInputStream
{
public :
    URLAccessBinInputStream(const XMLURL&  urlSource);
    ~URLAccessBinInputStream();

    unsigned int curPos() const;
    unsigned int readBytes
    (
                XMLByte* const  toFill
        , const unsigned int    maxToRead
    );

private :
    unsigned int        mBytesProcessed;
    URLReference		mURLReference;
    void*				mBuffer;			// Current buffer from URLAccess (or NULL)
    char*				mBufPos;			// Read position in buffer
    Size				mBufAvailable;		// Bytes available
};

inline unsigned int
URLAccessBinInputStream::curPos() const
{
    return mBytesProcessed;
}

#endif // URLACCESSBININPUTSTREAM_HPP
<commit_msg>Omit include carbon.h in favor of specific include files<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * Written by James D. Berry 7/20/00
 * Critical Path Software, Inc.
 */

/*
 * $Id$
 */

#if !defined(URLACCESSBININPUTSTREAM_HPP)
#define URLACCESSBININPUTSTREAM_HPP

#include <util/XMLURL.hpp>
#include <util/XMLExceptMsgs.hpp>
#include <util/BinInputStream.hpp>

#if defined(XML_MACOSX)
    //	Framework includes from ProjectBuilder
	#include <URLAccess/URLAccess.h>
#else
    //	Classic includes otherwise
	#include <URLAccess.h>
#endif

//
// This class implements the BinInputStream interface specified by the XML
// parser.
//

class XMLUTIL_EXPORT URLAccessBinInputStream : public BinInputStream
{
public :
    URLAccessBinInputStream(const XMLURL&  urlSource);
    ~URLAccessBinInputStream();

    unsigned int curPos() const;
    unsigned int readBytes
    (
                XMLByte* const  toFill
        , const unsigned int    maxToRead
    );

private :
    unsigned int        mBytesProcessed;
    URLReference		mURLReference;
    void*				mBuffer;			// Current buffer from URLAccess (or NULL)
    char*				mBufPos;			// Read position in buffer
    Size				mBufAvailable;		// Bytes available
};

inline unsigned int
URLAccessBinInputStream::curPos() const
{
    return mBytesProcessed;
}

#endif // URLACCESSBININPUTSTREAM_HPP
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application 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.
*/

#include <osgDB/FileUtils>
#include <osg/Version>

#include "PluginQuery.h"

using namespace osgDB;

FileNameList osgDB::listAllAvailablePlugins()
{
    FileNameList pluginFiles;

    std::string pluginDirectoryName = std::string("osgPlugins-")+std::string(osgGetVersion());
    std::string fullPath = osgDB::findLibraryFile(pluginDirectoryName);
    if (!fullPath.empty())
    {
        osgDB::DirectoryContents contents = getDirectoryContents(fullPath);
        for(DirectoryContents::iterator itr = contents.begin();
            itr != contents.end();
            ++itr)
        {
            std::string::size_type pos = itr->find("osgdb_");
            if (pos!=std::string::npos)
            {
                pluginFiles.push_back(fullPath + std::string("/")+*itr);
            }
        }
    }

    return pluginFiles;
}

bool osgDB::queryPlugin(const std::string& fileName, ReaderWriterInfoList& infoList)
{
    if (osgDB::Registry::instance()->loadLibrary(fileName))
    {
        const Registry::ReaderWriterList& rwList = osgDB::Registry::instance()->getReaderWriterList();
        for(Registry::ReaderWriterList::const_iterator itr = rwList.begin();
            itr != rwList.end();
            ++itr)
        {
            const ReaderWriter* rw = itr->get();
            osg::ref_ptr<ReaderWriterInfo> rwi = new ReaderWriterInfo;
            rwi->plugin = fileName;
            rwi->description = rw->className();
            rwi->protocols = rw->supportedProtocols();
            rwi->extensions = rw->supportedExtensions();
            rwi->options = rw->supportedOptions();

            infoList.push_back(rwi.get());
        }

        osgDB::Registry::instance()->closeLibrary(fileName);
        return true;
    }
    else
    {
        return false;
    }
}

static std::string padwithspaces(const std::string& str, unsigned int padLength)
{
    std::string newStr(str);
    while(newStr.length()<padLength) newStr.push_back(' ');
    return newStr;
}

bool osgDB::outputPluginDetails(std::ostream& out, const std::string& fileName)
{
    osgDB::ReaderWriterInfoList infoList;
    if (osgDB::queryPlugin(fileName, infoList))
    {
        out<<"Plugin "<<fileName<<std::endl;
        out<<"{"<<std::endl;

        for(osgDB::ReaderWriterInfoList::iterator rwi_itr = infoList.begin();
            rwi_itr != infoList.end();
            ++rwi_itr)
        {
            osgDB::ReaderWriterInfo& info = *(*rwi_itr);
            out<<"    ReaderWriter : "<<info.description<<std::endl;
            out<<"    {"<<std::endl;

            unsigned int longestOptionLength = 0;
            osgDB::ReaderWriter::FormatDescriptionMap::iterator fdm_itr;
            for(fdm_itr = info.protocols.begin();
                fdm_itr != info.protocols.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            for(fdm_itr = info.extensions.begin();
                fdm_itr != info.extensions.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            for(fdm_itr = info.options.begin();
                fdm_itr != info.options.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            unsigned int padLength = longestOptionLength+4;

            for(fdm_itr = info.protocols.begin();
                fdm_itr != info.protocols.end();
                ++fdm_itr)
            {
                out<<"        protocol   : "<<padwithspaces(fdm_itr->first, padLength)<<fdm_itr->second<<std::endl;
            }

            for(fdm_itr = info.extensions.begin();
                fdm_itr != info.extensions.end();
                ++fdm_itr)
            {
                out<<"        extensions : ."<<padwithspaces(fdm_itr->first, padLength-1)<<fdm_itr->second<<std::endl;
            }

            for(fdm_itr = info.options.begin();
                fdm_itr != info.options.end();
                ++fdm_itr)
            {
                out<<"        options    : "<<padwithspaces(fdm_itr->first, padLength)<<fdm_itr->second<<std::endl;
            }
            out<<"    }"<<std::endl;
        }
        out<<"}"<<std::endl<<std::endl;
    }
    else
    {
        out<<"Plugin "<<fileName<<" not found."<<std::endl;
    }
}

<commit_msg>Added missing returns<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application 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.
*/

#include <osgDB/FileUtils>
#include <osg/Version>

#include "PluginQuery.h"

using namespace osgDB;

FileNameList osgDB::listAllAvailablePlugins()
{
    FileNameList pluginFiles;

    std::string pluginDirectoryName = std::string("osgPlugins-")+std::string(osgGetVersion());
    std::string fullPath = osgDB::findLibraryFile(pluginDirectoryName);
    if (!fullPath.empty())
    {
        osgDB::DirectoryContents contents = getDirectoryContents(fullPath);
        for(DirectoryContents::iterator itr = contents.begin();
            itr != contents.end();
            ++itr)
        {
            std::string::size_type pos = itr->find("osgdb_");
            if (pos!=std::string::npos)
            {
                pluginFiles.push_back(fullPath + std::string("/")+*itr);
            }
        }
    }

    return pluginFiles;
}

bool osgDB::queryPlugin(const std::string& fileName, ReaderWriterInfoList& infoList)
{
    if (osgDB::Registry::instance()->loadLibrary(fileName))
    {
        const Registry::ReaderWriterList& rwList = osgDB::Registry::instance()->getReaderWriterList();
        for(Registry::ReaderWriterList::const_iterator itr = rwList.begin();
            itr != rwList.end();
            ++itr)
        {
            const ReaderWriter* rw = itr->get();
            osg::ref_ptr<ReaderWriterInfo> rwi = new ReaderWriterInfo;
            rwi->plugin = fileName;
            rwi->description = rw->className();
            rwi->protocols = rw->supportedProtocols();
            rwi->extensions = rw->supportedExtensions();
            rwi->options = rw->supportedOptions();

            infoList.push_back(rwi.get());
        }

        osgDB::Registry::instance()->closeLibrary(fileName);
        return true;
    }
    else
    {
        return false;
    }
}

static std::string padwithspaces(const std::string& str, unsigned int padLength)
{
    std::string newStr(str);
    while(newStr.length()<padLength) newStr.push_back(' ');
    return newStr;
}

bool osgDB::outputPluginDetails(std::ostream& out, const std::string& fileName)
{
    osgDB::ReaderWriterInfoList infoList;
    if (osgDB::queryPlugin(fileName, infoList))
    {
        out<<"Plugin "<<fileName<<std::endl;
        out<<"{"<<std::endl;

        for(osgDB::ReaderWriterInfoList::iterator rwi_itr = infoList.begin();
            rwi_itr != infoList.end();
            ++rwi_itr)
        {
            osgDB::ReaderWriterInfo& info = *(*rwi_itr);
            out<<"    ReaderWriter : "<<info.description<<std::endl;
            out<<"    {"<<std::endl;

            unsigned int longestOptionLength = 0;
            osgDB::ReaderWriter::FormatDescriptionMap::iterator fdm_itr;
            for(fdm_itr = info.protocols.begin();
                fdm_itr != info.protocols.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            for(fdm_itr = info.extensions.begin();
                fdm_itr != info.extensions.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            for(fdm_itr = info.options.begin();
                fdm_itr != info.options.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            unsigned int padLength = longestOptionLength+4;

            for(fdm_itr = info.protocols.begin();
                fdm_itr != info.protocols.end();
                ++fdm_itr)
            {
                out<<"        protocol   : "<<padwithspaces(fdm_itr->first, padLength)<<fdm_itr->second<<std::endl;
            }

            for(fdm_itr = info.extensions.begin();
                fdm_itr != info.extensions.end();
                ++fdm_itr)
            {
                out<<"        extensions : ."<<padwithspaces(fdm_itr->first, padLength-1)<<fdm_itr->second<<std::endl;
            }

            for(fdm_itr = info.options.begin();
                fdm_itr != info.options.end();
                ++fdm_itr)
            {
                out<<"        options    : "<<padwithspaces(fdm_itr->first, padLength)<<fdm_itr->second<<std::endl;
            }
            out<<"    }"<<std::endl;
        }
        out<<"}"<<std::endl<<std::endl;
        return true;
    }
    else
    {
        out<<"Plugin "<<fileName<<" not found."<<std::endl;
        return false;
    }
}

<|endoftext|>