<commit_before>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2014 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * 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.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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.
 **
 **********************************************************************************************************************/

#include "CppImportManager.h"

#include "ClangFrontendActionFactory.h"
#include "CppImportException.h"

#include "ModelBase/src/model/TreeManager.h"

namespace CppImport {

CppImportManager::~CppImportManager()
{
	// clean the maps
	auto vectors = sourcesMap_.values();
	for (auto sv : vectors)
		SAFE_DELETE(sv);
	sourcesMap_.clear();
	auto dbs = compilationDbMap_.values();
	for (auto db : dbs)
		SAFE_DELETE(db);
	compilationDbMap_.clear();
}

void CppImportManager::setImportPath(const QString& sourcePath, const bool subProjects)
{
	setProjectName(sourcePath);
	if (subProjects)
	{
		QDirIterator dirIterator(sourcePath, QDir::Dirs | QDir::NoDot | QDir::NoDotDot);
		while (dirIterator.hasNext())
			initPath(dirIterator.next());
	}
	else
		initPath(sourcePath);
}

Model::TreeManager*CppImportManager::createTreeManager(const bool statisticsPerProject)
{
	auto project = new OOModel::Project(projectName_);
	auto log = new CppImportLogger();
	auto visitor = new ClangAstVisitor(project, log);

	for (QString s : projects_)
	{
		qDebug() << "Start processing project :" << s;
		auto tool = new clang::tooling::ClangTool(*compilationDbMap_.value(s), *sourcesMap_.value(s));
		auto frontendActionFactory = new ClangFrontendActionFactory(visitor, log);
		tool->run(frontendActionFactory);
		// statistics
		if (statisticsPerProject)
			log->outputStatistics();
		//clean up
		SAFE_DELETE(frontendActionFactory);
		SAFE_DELETE(tool);
	}

	visitor->macroImporter_.endEntireImport();

	// statistics
	if (!statisticsPerProject)
		log->outputStatistics();
	SAFE_DELETE(visitor);
	SAFE_DELETE(log);
	// reset the path (because clang tool changes it)
	QDir::setCurrent(qApp->applicationDirPath());
	return new Model::TreeManager("CppImport", project);
}

void CppImportManager::setupTest()
{
	// setup the root dir
	QDir rootDir(QDir::currentPath());
	rootDir.cdUp();
	rootDir.cd(QString("CppImport").append(QDir::separator()).append("test"));
	QString rootPath = rootDir.canonicalPath();
	// open testSelector file to read in dir
	QFile selector(rootPath + QDir::separator() + "testSelector");
	if (!selector.open(QFile::ReadOnly))
		throw CppImportException("Could not open testSelector file");
	QTextStream inStream(&selector);
	QString testDir;
	while (!inStream.atEnd())
	{
		testDir = inStream.readLine();
		if (testDir.trimmed().isEmpty())
			continue;
		else if (testDir.startsWith("path:"))
		{
			testDir.replace(0, 5, "");
			return setImportPath(QDir(QCoreApplication::applicationDirPath() + "/test" + testDir).absolutePath());
		}
		else if (testDir.startsWith("spath:"))
		{
			testDir.replace(0, 6, "");
			return setImportPath(QDir(QCoreApplication::applicationDirPath() + "/test" + testDir).absolutePath(), true);
		}
		else if (!testDir.startsWith("#"))
		{
			rootPath.append(QDir::separator()).append(testDir);
			createCompilationDbForTest(rootPath);
			return setImportPath(rootPath);
		}
	}
	throw CppImportException("No test case set in the testSelector file");
}

void CppImportManager::initPath(const QString& sourcePath)
{
	// check if there is a compilation db file in this directory otherwise we exclude it
	QDir curDir(sourcePath);
	if (!curDir.exists("compile_commands.json"))
	{
		qDebug() << "Ignoring directory" << sourcePath << "because there is no compile_commands.json file";
		return;
	}
	// append to the projects
	projects_.append(sourcePath);

	readInFiles(sourcePath);
	setCompilationDbPath(sourcePath);
}

void CppImportManager::setProjectName(const QString& sourcePath)
{
	projectName_ = sourcePath.split(QDir::separator()).last();
}

void CppImportManager::readInFiles(const QString& sourcePath)
{
	QDirIterator dirIterator(sourcePath, cppFilter_, QDir::Files, QDirIterator::Subdirectories);
	auto sources = new std::vector<std::string>();
	while (dirIterator.hasNext())
		sources->push_back(dirIterator.next().toStdString());
	sourcesMap_.insert(sourcePath, sources);
}

void CppImportManager::setCompilationDbPath(const QString& sourcePath)
{
	std::string Error;
	auto compDB = clang::tooling::CompilationDatabase::loadFromDirectory(sourcePath.toLatin1().data(), Error);
	if (!compDB)
		throw CppImportException("No compilation database found : " + QString::fromStdString(Error));
	compilationDbMap_.insert(sourcePath, compDB.release());
}

void CppImportManager::createCompilationDbForTest(const QString& testPath)
{
	QDir curDir(testPath);
	if (!curDir.exists("compile_commands.json"))
	{
		QString test = testPath.split(QDir::separator()).last();
		QFile db(testPath + QDir::separator() + "compile_commands.json");
		if (!db.open(QFile::ReadWrite))
			throw CppImportException("Cannot create compile_commands file for test: " + test);
		QTextStream out(&db);
		out << "[" << endl;
		out << "{" << "\"directory\":" << "\"" << testPath << "\"," << endl;
		// TODO: this is platform dependent
		out << "\"command\":" << "\"/usr/bin/clang++ -std=c++0x -Irelative " <<
				"-I/usr/lib/llvm-3.4/include/clang/ -c -o test.o test.cpp\"," << endl;
		out << "\"file\":" << "\"test.cpp\"" << endl;
		out << "}" << endl << "]" << endl;
		db.close();
	}
}

}
<commit_msg>add space<commit_after>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2014 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * 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.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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.
 **
 **********************************************************************************************************************/

#include "CppImportManager.h"

#include "ClangFrontendActionFactory.h"
#include "CppImportException.h"

#include "ModelBase/src/model/TreeManager.h"

namespace CppImport {

CppImportManager::~CppImportManager()
{
	// clean the maps
	auto vectors = sourcesMap_.values();
	for (auto sv : vectors)
		SAFE_DELETE(sv);
	sourcesMap_.clear();
	auto dbs = compilationDbMap_.values();
	for (auto db : dbs)
		SAFE_DELETE(db);
	compilationDbMap_.clear();
}

void CppImportManager::setImportPath(const QString& sourcePath, const bool subProjects)
{
	setProjectName(sourcePath);
	if (subProjects)
	{
		QDirIterator dirIterator(sourcePath, QDir::Dirs | QDir::NoDot | QDir::NoDotDot);
		while (dirIterator.hasNext())
			initPath(dirIterator.next());
	}
	else
		initPath(sourcePath);
}

Model::TreeManager* CppImportManager::createTreeManager(const bool statisticsPerProject)
{
	auto project = new OOModel::Project(projectName_);
	auto log = new CppImportLogger();
	auto visitor = new ClangAstVisitor(project, log);

	for (QString s : projects_)
	{
		qDebug() << "Start processing project :" << s;
		auto tool = new clang::tooling::ClangTool(*compilationDbMap_.value(s), *sourcesMap_.value(s));
		auto frontendActionFactory = new ClangFrontendActionFactory(visitor, log);
		tool->run(frontendActionFactory);
		// statistics
		if (statisticsPerProject)
			log->outputStatistics();
		//clean up
		SAFE_DELETE(frontendActionFactory);
		SAFE_DELETE(tool);
	}

	visitor->macroImporter_.endEntireImport();

	// statistics
	if (!statisticsPerProject)
		log->outputStatistics();
	SAFE_DELETE(visitor);
	SAFE_DELETE(log);
	// reset the path (because clang tool changes it)
	QDir::setCurrent(qApp->applicationDirPath());
	return new Model::TreeManager("CppImport", project);
}

void CppImportManager::setupTest()
{
	// setup the root dir
	QDir rootDir(QDir::currentPath());
	rootDir.cdUp();
	rootDir.cd(QString("CppImport").append(QDir::separator()).append("test"));
	QString rootPath = rootDir.canonicalPath();
	// open testSelector file to read in dir
	QFile selector(rootPath + QDir::separator() + "testSelector");
	if (!selector.open(QFile::ReadOnly))
		throw CppImportException("Could not open testSelector file");
	QTextStream inStream(&selector);
	QString testDir;
	while (!inStream.atEnd())
	{
		testDir = inStream.readLine();
		if (testDir.trimmed().isEmpty())
			continue;
		else if (testDir.startsWith("path:"))
		{
			testDir.replace(0, 5, "");
			return setImportPath(QDir(QCoreApplication::applicationDirPath() + "/test" + testDir).absolutePath());
		}
		else if (testDir.startsWith("spath:"))
		{
			testDir.replace(0, 6, "");
			return setImportPath(QDir(QCoreApplication::applicationDirPath() + "/test" + testDir).absolutePath(), true);
		}
		else if (!testDir.startsWith("#"))
		{
			rootPath.append(QDir::separator()).append(testDir);
			createCompilationDbForTest(rootPath);
			return setImportPath(rootPath);
		}
	}
	throw CppImportException("No test case set in the testSelector file");
}

void CppImportManager::initPath(const QString& sourcePath)
{
	// check if there is a compilation db file in this directory otherwise we exclude it
	QDir curDir(sourcePath);
	if (!curDir.exists("compile_commands.json"))
	{
		qDebug() << "Ignoring directory" << sourcePath << "because there is no compile_commands.json file";
		return;
	}
	// append to the projects
	projects_.append(sourcePath);

	readInFiles(sourcePath);
	setCompilationDbPath(sourcePath);
}

void CppImportManager::setProjectName(const QString& sourcePath)
{
	projectName_ = sourcePath.split(QDir::separator()).last();
}

void CppImportManager::readInFiles(const QString& sourcePath)
{
	QDirIterator dirIterator(sourcePath, cppFilter_, QDir::Files, QDirIterator::Subdirectories);
	auto sources = new std::vector<std::string>();
	while (dirIterator.hasNext())
		sources->push_back(dirIterator.next().toStdString());
	sourcesMap_.insert(sourcePath, sources);
}

void CppImportManager::setCompilationDbPath(const QString& sourcePath)
{
	std::string Error;
	auto compDB = clang::tooling::CompilationDatabase::loadFromDirectory(sourcePath.toLatin1().data(), Error);
	if (!compDB)
		throw CppImportException("No compilation database found : " + QString::fromStdString(Error));
	compilationDbMap_.insert(sourcePath, compDB.release());
}

void CppImportManager::createCompilationDbForTest(const QString& testPath)
{
	QDir curDir(testPath);
	if (!curDir.exists("compile_commands.json"))
	{
		QString test = testPath.split(QDir::separator()).last();
		QFile db(testPath + QDir::separator() + "compile_commands.json");
		if (!db.open(QFile::ReadWrite))
			throw CppImportException("Cannot create compile_commands file for test: " + test);
		QTextStream out(&db);
		out << "[" << endl;
		out << "{" << "\"directory\":" << "\"" << testPath << "\"," << endl;
		// TODO: this is platform dependent
		out << "\"command\":" << "\"/usr/bin/clang++ -std=c++0x -Irelative " <<
				"-I/usr/lib/llvm-3.4/include/clang/ -c -o test.o test.cpp\"," << endl;
		out << "\"file\":" << "\"test.cpp\"" << endl;
		out << "}" << endl << "]" << endl;
		db.close();
	}
}

}
<|endoftext|>


<commit_before>#include "details/context/build.h"
#include "instanciate.h"
#include "details/reporting/report.h"
#include "details/atom/func-overload-match.h"
#include "details/reporting/message.h"
#include "details/utils/origin.h"
#include "libnany-traces.h"
#include "instanciate-atom.h"
#include <memory>

using namespace Yuni;

namespace Nany
{
namespace Pass
{
namespace Instanciate
{

	SequenceBuilder::SequenceBuilder(Logs::Report report, ClassdefTableView& cdeftable, Build& build,
		IR::Sequence& out, IR::Sequence& sequence, SequenceBuilder* parent)
		: cdeftable(cdeftable)
		, build(build)
		, intrinsics(build.intrinsics)
		, out(out)
		, currentSequence(sequence)
		, overloadMatch(report, cdeftable)
		, report(report)
		, parent(parent)
	{
		// reduce memory (re)allocations
		multipleResults.reserve(8); // arbitrary value

		pushedparams.func.indexed.reserve(16);
		pushedparams.func.named.reserve(16);
		pushedparams.gentypes.indexed.reserve(8);
		pushedparams.gentypes.named.reserve(8);
	}

	SequenceBuilder::~SequenceBuilder()
	{
		if (Config::Traces::allTypeDefinitions)
			printClassdefTable();

		auto* frm = frame;
		while (frm)
		{
			auto* previous = frm->previous;
			build.deallocate(frm);
			frm = previous;
		}
	}

	void SequenceBuilder::printClassdefTable()
	{
		for (auto* f = frame; f != nullptr; f = f->previous)
			printClassdefTable(report.subgroup(), *f);
	}

	void SequenceBuilder::releaseScopedVariables(int scope, bool forget)
	{
		if (unlikely(!frame))
			return;
		if (not forget and (not canGenerateCode()))
			return;

		// unref in the reverse order
		auto i = static_cast<uint32_t>(frame->lvids.size());

		if (canGenerateCode())
		{
			while (i-- != 0)
			{
				auto& clcvr = frame->lvids[i];
				if (not (clcvr.scope >= scope))
					continue;

				if (clcvr.autorelease)
				{
					//if (not clcvr.userDefinedName.empty())
					//	out.emitComment(String{"unref var "} << clcvr.userDefinedName << " -> %" << i);
					tryUnrefObject(i);
				}

				// forget this variable!
				if (forget)
				{
					if (not clcvr.userDefinedName.empty() and clcvr.warning.unused)
					{
						if (unlikely(not clcvr.hasBeenUsed) and (clcvr.userDefinedName != "self"))
							complainUnusedVariable(*frame, i);
					}

					clcvr.userDefinedName.clear();
					clcvr.scope = -1;
				}
			}
		}
		else
		{
			assert(forget == true);
			while (i-- != 0) // just invalidate everything
			{
				auto& clcvr = frame->lvids[i];
				if (clcvr.scope >= scope)
				{
					clcvr.userDefinedName.clear();
					clcvr.scope = -1;
				}
			}
		}
	}

	uint32_t SequenceBuilder::createLocalVariables(uint32_t count)
	{
		assert(count > 0);
		assert(frame != nullptr);
		assert(frame->offsetOpcodeStacksize != (uint32_t) -1);

		auto& operands = out.at<IR::ISA::Op::stacksize>(frame->offsetOpcodeStacksize);
		uint32_t startOffset = operands.add;
		int scope = frame->scope;

		operands.add += count;
		frame->resizeRegisterCount(operands.add, cdeftable);
		assert(startOffset + count <= frame->lvids.size());

		if (canGenerateCode())
		{
			for (uint32_t i = 0; i != count; ++i)
			{
				auto& lvidinfo = frame->lvids[startOffset + i];
				lvidinfo.scope = scope;
				lvidinfo.synthetic = false;
				lvidinfo.offsetDeclOut = out.opcodeCount();
				out.emitStackalloc(startOffset + i, nyt_any);
			}
		}
		else
		{
			for (uint32_t i = 0; i != count; ++i)
			{
				auto& lvidinfo = frame->lvids[startOffset + i];
				lvidinfo.scope = scope;
				lvidinfo.synthetic = false;
			}
		}
		return startOffset;
	}

	void SequenceBuilder::printClassdefTable(Logs::Report trace, const AtomStackFrame& frame) const
	{
		auto entry = trace.trace();

		entry.message.prefix << cdeftable.keyword(frame.atom) << ' ';
		frame.atom.retrieveCaption(entry.message.prefix, cdeftable);
		entry << " - type matrix, after instanciation - atom " << frame.atom.atomid;

		for (uint i = 0; i != frame.localVariablesCount(); ++i)
		{
			auto clid = CLID{frame.atomid, i};
			auto entry = trace.trace();

			if (cdeftable.hasClassdef(clid) or cdeftable.hasSubstitute(clid))
			{
				cdeftable.printClassdef(entry.message.message, clid, cdeftable.classdef(clid));
				entry.message.message.trimRight();

				if (cdeftable.hasSubstitute(clid))
					entry << " (local replacement)";

				if (frame.lvids[i].isConstexpr)
					entry << " (constexpr)";

				if (frame.lvids[i].errorReported)
					entry << " [ERROR]";
			}
			else
			{
				entry << "    " << clid << ": !!INVALID CLID";
			}
		}
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::inherit>& operands)
	{
		assert(frame != nullptr);
		if (not frame->verify(operands.lhs))
			return;

		switch (operands.inherit)
		{
			case 2: // qualifiers
			{
				auto& spare = cdeftable.substitute(operands.lhs);
				spare.qualifiers = cdeftable.classdef(CLID{frame->atomid, operands.rhs}).qualifiers;
				break;
			}
			default:
			{
				ICE() << "invalid inherit value " << operands.inherit;
			}
		}
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::namealias>& operands)
	{
		const auto& name = currentSequence.stringrefs[operands.name];
		declareNamedVariable(name, operands.lvid);
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::debugfile>& operands)
	{
		currentFilename = currentSequence.stringrefs[operands.filename].c_str();
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::debugpos>& operands)
	{
		currentLine   = operands.line;
		currentOffset = operands.offset;
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::unref>& operands)
	{
		tryUnrefObject(operands.lvid);
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::nop>&)
	{
		// duplicate nop as well since they can be used to insert code
		// (for shortcircuit for example)
		out.emitNop();
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::label>& operands)
	{
		uint32_t lbl = out.emitLabel(operands.label);
		(void) lbl; // avoid compiler warning for `emitLabel`
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::qualifiers>& operands)
	{
		bool  onoff = (operands.flag != 0);
		auto& spare = cdeftable.substitute(operands.lvid);

		switch (operands.qualifier)
		{
			case 1: // ref
			{
				spare.qualifiers.ref = onoff;
				break;
			}
			case 2: // const
			{
				spare.qualifiers.constant = onoff;
				break;
			}
			default:
				ICE() << "unknown qualifier constant " << operands.qualifier;
		}
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::jmp>& opc)
	{
		out.emit<IR::ISA::Op::jmp>() = opc;
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::jz>& opc)
	{
		out.emit<IR::ISA::Op::jz>() = opc;
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::jnz>& opc)
	{
		out.emit<IR::ISA::Op::jnz>() = opc;
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::comment>& opc)
	{
		// keep the comments in debug
		if (Yuni::debugmode)
			out.emitComment(currentSequence.stringrefs[opc.text]);
	}

	template<IR::ISA::Op O>
	void SequenceBuilder::visit(const IR::ISA::Operand<O>& operands)
	{
		complainOperand(IR::Instruction::fromOpcode(operands));
	}

	bool SequenceBuilder::readAndInstanciate(uint32_t offset)
	{
		currentSequence.each(*this, offset);
		return success;
	}

} // namespace Instanciate
} // namespace Pass
} // namespace Nany

namespace Nany
{

	bool Build::instanciate(const AnyString& entrypoint, const nytype_t* args, uint32_t& atomid, uint32_t& instanceid)
	{
		Nany::Logs::Report report{*messages.get()};

		if (unlikely(args))
		{
			report.error() << "arguments for atom instanciation is not supported yet";
			return false;
		}

		// lock the isolate
		MutexLocker locker{mutex};

		// try to find the entrypoint
		Atom* entrypointAtom = nullptr;
		{
			bool canContinue = true;
			cdeftable.atoms.root.eachChild(entrypoint, [&](Atom& child) -> bool
			{
				if (entrypointAtom != nullptr)
				{
					canContinue = false;
					report.error() << "failed to instanciate '" << entrypoint << "': multiple entry points found";
					return false;
				}
				entrypointAtom = &child;
				return true;
			});

			if (not canContinue)
				return false;
		}

		if (unlikely(nullptr == entrypointAtom))
		{
			report.ICE() << "failed to instanciate '" << entrypoint << "()': function not found";
			return false;
		}

		if (unlikely(entrypointAtom->type != Atom::Type::funcdef))
		{
			report.ICE() << "failed to instanciate '" << entrypoint << "': the atom is not a function";
			return false;
		}

		// parameters for the signature
		decltype(FuncOverloadMatch::result.params) params;
		decltype(FuncOverloadMatch::result.params) tmplparams;
		Logs::Message::Ptr newReport;

		ClassdefTableView cdeftblView{cdeftable};

		Pass::Instanciate::InstanciateData info {
			newReport, *entrypointAtom, cdeftblView, *this, params, tmplparams
		};
		bool instanciated = Pass::Instanciate::instanciateAtom(info);
		report.appendEntry(newReport);

		if (instanciated)
		{
			atomid = entrypointAtom->atomid;
			instanceid = info.instanceid;
			return true;
		}
		else
		{
			atomid = (uint32_t) -1;
			instanceid = (uint32_t) -1;
			return false;
		}
	}

} // namespace Nany
<commit_msg>Restored traces for `Config::Traces::atomTable`<commit_after>#include "details/context/build.h"
#include "instanciate.h"
#include "details/reporting/report.h"
#include "details/atom/func-overload-match.h"
#include "details/reporting/message.h"
#include "details/utils/origin.h"
#include "libnany-traces.h"
#include "instanciate-atom.h"
#include <memory>

using namespace Yuni;

namespace Nany
{
namespace Pass
{
namespace Instanciate
{

	SequenceBuilder::SequenceBuilder(Logs::Report report, ClassdefTableView& cdeftable, Build& build,
		IR::Sequence& out, IR::Sequence& sequence, SequenceBuilder* parent)
		: cdeftable(cdeftable)
		, build(build)
		, intrinsics(build.intrinsics)
		, out(out)
		, currentSequence(sequence)
		, overloadMatch(report, cdeftable)
		, report(report)
		, parent(parent)
	{
		// reduce memory (re)allocations
		multipleResults.reserve(8); // arbitrary value

		pushedparams.func.indexed.reserve(16);
		pushedparams.func.named.reserve(16);
		pushedparams.gentypes.indexed.reserve(8);
		pushedparams.gentypes.named.reserve(8);
	}

	SequenceBuilder::~SequenceBuilder()
	{
		if (Config::Traces::allTypeDefinitions)
			printClassdefTable();

		auto* frm = frame;
		while (frm)
		{
			auto* previous = frm->previous;
			build.deallocate(frm);
			frm = previous;
		}
	}

	void SequenceBuilder::printClassdefTable()
	{
		for (auto* f = frame; f != nullptr; f = f->previous)
			printClassdefTable(report.subgroup(), *f);
	}

	void SequenceBuilder::releaseScopedVariables(int scope, bool forget)
	{
		if (unlikely(!frame))
			return;
		if (not forget and (not canGenerateCode()))
			return;

		// unref in the reverse order
		auto i = static_cast<uint32_t>(frame->lvids.size());

		if (canGenerateCode())
		{
			while (i-- != 0)
			{
				auto& clcvr = frame->lvids[i];
				if (not (clcvr.scope >= scope))
					continue;

				if (clcvr.autorelease)
				{
					//if (not clcvr.userDefinedName.empty())
					//	out.emitComment(String{"unref var "} << clcvr.userDefinedName << " -> %" << i);
					tryUnrefObject(i);
				}

				// forget this variable!
				if (forget)
				{
					if (not clcvr.userDefinedName.empty() and clcvr.warning.unused)
					{
						if (unlikely(not clcvr.hasBeenUsed) and (clcvr.userDefinedName != "self"))
							complainUnusedVariable(*frame, i);
					}

					clcvr.userDefinedName.clear();
					clcvr.scope = -1;
				}
			}
		}
		else
		{
			assert(forget == true);
			while (i-- != 0) // just invalidate everything
			{
				auto& clcvr = frame->lvids[i];
				if (clcvr.scope >= scope)
				{
					clcvr.userDefinedName.clear();
					clcvr.scope = -1;
				}
			}
		}
	}

	uint32_t SequenceBuilder::createLocalVariables(uint32_t count)
	{
		assert(count > 0);
		assert(frame != nullptr);
		assert(frame->offsetOpcodeStacksize != (uint32_t) -1);

		auto& operands = out.at<IR::ISA::Op::stacksize>(frame->offsetOpcodeStacksize);
		uint32_t startOffset = operands.add;
		int scope = frame->scope;

		operands.add += count;
		frame->resizeRegisterCount(operands.add, cdeftable);
		assert(startOffset + count <= frame->lvids.size());

		if (canGenerateCode())
		{
			for (uint32_t i = 0; i != count; ++i)
			{
				auto& lvidinfo = frame->lvids[startOffset + i];
				lvidinfo.scope = scope;
				lvidinfo.synthetic = false;
				lvidinfo.offsetDeclOut = out.opcodeCount();
				out.emitStackalloc(startOffset + i, nyt_any);
			}
		}
		else
		{
			for (uint32_t i = 0; i != count; ++i)
			{
				auto& lvidinfo = frame->lvids[startOffset + i];
				lvidinfo.scope = scope;
				lvidinfo.synthetic = false;
			}
		}
		return startOffset;
	}

	void SequenceBuilder::printClassdefTable(Logs::Report trace, const AtomStackFrame& frame) const
	{
		auto entry = trace.trace();

		entry.message.prefix << cdeftable.keyword(frame.atom) << ' ';
		frame.atom.retrieveCaption(entry.message.prefix, cdeftable);
		entry << " - type matrix, after instanciation - atom " << frame.atom.atomid;

		for (uint i = 0; i != frame.localVariablesCount(); ++i)
		{
			auto clid = CLID{frame.atomid, i};
			auto entry = trace.trace();

			if (cdeftable.hasClassdef(clid) or cdeftable.hasSubstitute(clid))
			{
				cdeftable.printClassdef(entry.message.message, clid, cdeftable.classdef(clid));
				entry.message.message.trimRight();

				if (cdeftable.hasSubstitute(clid))
					entry << " (local replacement)";

				if (frame.lvids[i].isConstexpr)
					entry << " (constexpr)";

				if (frame.lvids[i].errorReported)
					entry << " [ERROR]";
			}
			else
			{
				entry << "    " << clid << ": !!INVALID CLID";
			}
		}
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::inherit>& operands)
	{
		assert(frame != nullptr);
		if (not frame->verify(operands.lhs))
			return;

		switch (operands.inherit)
		{
			case 2: // qualifiers
			{
				auto& spare = cdeftable.substitute(operands.lhs);
				spare.qualifiers = cdeftable.classdef(CLID{frame->atomid, operands.rhs}).qualifiers;
				break;
			}
			default:
			{
				ICE() << "invalid inherit value " << operands.inherit;
			}
		}
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::namealias>& operands)
	{
		const auto& name = currentSequence.stringrefs[operands.name];
		declareNamedVariable(name, operands.lvid);
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::debugfile>& operands)
	{
		currentFilename = currentSequence.stringrefs[operands.filename].c_str();
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::debugpos>& operands)
	{
		currentLine   = operands.line;
		currentOffset = operands.offset;
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::unref>& operands)
	{
		tryUnrefObject(operands.lvid);
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::nop>&)
	{
		// duplicate nop as well since they can be used to insert code
		// (for shortcircuit for example)
		out.emitNop();
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::label>& operands)
	{
		uint32_t lbl = out.emitLabel(operands.label);
		(void) lbl; // avoid compiler warning for `emitLabel`
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::qualifiers>& operands)
	{
		bool  onoff = (operands.flag != 0);
		auto& spare = cdeftable.substitute(operands.lvid);

		switch (operands.qualifier)
		{
			case 1: // ref
			{
				spare.qualifiers.ref = onoff;
				break;
			}
			case 2: // const
			{
				spare.qualifiers.constant = onoff;
				break;
			}
			default:
				ICE() << "unknown qualifier constant " << operands.qualifier;
		}
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::jmp>& opc)
	{
		out.emit<IR::ISA::Op::jmp>() = opc;
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::jz>& opc)
	{
		out.emit<IR::ISA::Op::jz>() = opc;
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::jnz>& opc)
	{
		out.emit<IR::ISA::Op::jnz>() = opc;
	}

	inline void SequenceBuilder::visit(const IR::ISA::Operand<IR::ISA::Op::comment>& opc)
	{
		// keep the comments in debug
		if (Yuni::debugmode)
			out.emitComment(currentSequence.stringrefs[opc.text]);
	}

	template<IR::ISA::Op O>
	void SequenceBuilder::visit(const IR::ISA::Operand<O>& operands)
	{
		complainOperand(IR::Instruction::fromOpcode(operands));
	}

	bool SequenceBuilder::readAndInstanciate(uint32_t offset)
	{
		currentSequence.each(*this, offset);
		return success;
	}

} // namespace Instanciate
} // namespace Pass
} // namespace Nany

namespace Nany
{

	bool Build::instanciate(const AnyString& entrypoint, const nytype_t* args, uint32_t& atomid, uint32_t& instanceid)
	{
		Nany::Logs::Report report{*messages.get()};

		if (unlikely(args))
		{
			report.error() << "arguments for atom instanciation is not supported yet";
			return false;
		}

		// lock the isolate
		MutexLocker locker{mutex};

		// try to find the entrypoint
		Atom* entrypointAtom = nullptr;
		{
			bool canContinue = true;
			cdeftable.atoms.root.eachChild(entrypoint, [&](Atom& child) -> bool
			{
				if (entrypointAtom != nullptr)
				{
					canContinue = false;
					report.error() << "failed to instanciate '" << entrypoint << "': multiple entry points found";
					return false;
				}
				entrypointAtom = &child;
				return true;
			});

			if (not canContinue)
				return false;
		}

		if (unlikely(nullptr == entrypointAtom))
		{
			report.ICE() << "failed to instanciate '" << entrypoint << "()': function not found";
			return false;
		}

		if (unlikely(entrypointAtom->type != Atom::Type::funcdef))
		{
			report.ICE() << "failed to instanciate '" << entrypoint << "': the atom is not a function";
			return false;
		}

		// parameters for the signature
		decltype(FuncOverloadMatch::result.params) params;
		decltype(FuncOverloadMatch::result.params) tmplparams;
		Logs::Message::Ptr newReport;

		ClassdefTableView cdeftblView{cdeftable};

		Pass::Instanciate::InstanciateData info {
			newReport, *entrypointAtom, cdeftblView, *this, params, tmplparams
		};
		bool instanciated = Pass::Instanciate::instanciateAtom(info);
		report.appendEntry(newReport);

		if (Config::Traces::atomTable)
			cdeftable.atoms.root.print(report, cdeftable);

		if (instanciated)
		{
			atomid = entrypointAtom->atomid;
			instanceid = info.instanceid;
			return true;
		}
		else
		{
			atomid = (uint32_t) -1;
			instanceid = (uint32_t) -1;
			return false;
		}
	}

} // namespace Nany
<|endoftext|>


<commit_before>/** \brief Utility for displaying the count of MARC records contained in a collection.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2015-2017 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include "MarcReader.h"
#include "MarcRecord.h"
#include "util.h"

static void Usage() __attribute__((noreturn));

static void Usage() {
    std::cerr << "Usage: " << ::progname << " marc_data\n";
    std::exit(EXIT_FAILURE);
}

void CountRecords(MarcReader * const marc_reader) {
    unsigned record_count(0);
    while (const MarcRecord record = marc_reader->read())
        ++record_count;
    std::cout << record_count << '\n';
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc != 2)
        Usage();

    std::unique_ptr<MarcReader> marc_reader(MarcReader::Factory(argv[1]));

    try {
        CountRecords(marc_reader.get());
    } catch (const std::exception &e) {
        logger->error("Caught exception: " + std::string(e.what()));
    }
}
<commit_msg>New API: marc_size<commit_after>/** \brief Utility for displaying the count of MARC records contained in a collection.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2015-2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include "MARC.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    std::cerr << "Usage: " << ::progname << " marc_data\n";
    std::exit(EXIT_FAILURE);
}

void CountRecords(MARC::Reader * const marc_reader) {
    unsigned record_count(0);
    while (const MARC::Record record = marc_reader->read())
        ++record_count;
    std::cout << record_count << '\n';
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 2)
        Usage();

    auto marc_reader(MARC::Reader::Factory(argv[1]));
    CountRecords(marc_reader.get());
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file exp_omi_setup.C
/// @brief Contains the explorer OMI setup
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: Memory

#include <fapi2.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/exp_attribute_accessors_manual.H>
#include <lib/omi/exp_omi_utils.H>

extern "C"
{

    ///
    /// @brief Setup the OCMB for enterprise and half-DIMM modes as desired
    /// @param[in] i_target the OCMB target to operate on
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
    {
        // Declares variables
        fapi2::buffer<uint64_t> l_data;
        bool l_is_enterprise = false;
        bool l_is_half_dimm = false;

        // Gets the configuration information
        FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise));
        FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm));

        // Prints out the data
        FAPI_INF("%s %s enterprise mode %s-DIMM mode", mss::c_str(i_target), l_is_enterprise ? "is" : "isn't",
                 l_is_half_dimm ? "half" : "full");

        // Sets up the register
        mss::exp::omi::set_enterprise_set_bit(l_data, l_is_enterprise);
        mss::exp::omi::set_half_dimm_mode(l_data, l_is_half_dimm);

        // Writes the data to the register
        FAPI_TRY(mss::exp::omi::write_enterprise_config(i_target, l_data));

        // Checks that the chip is configured correctly
        FAPI_TRY(mss::exp::omi::read_enterprise_config(i_target, l_data));
        FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data));

    fapi_try_exit:
        return fapi2::current_err;
    }
}
<commit_msg>Add snapshot of ocmb/explorer for master-p10 branch<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file exp_omi_setup.C
/// @brief Contains the explorer OMI setup
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: Memory

#include <fapi2.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/exp_attribute_accessors_manual.H>
#include <lib/omi/exp_omi_utils.H>
#include <generic/memory/mss_git_data_helper.H>

extern "C"
{

    ///
    /// @brief Setup the OCMB for enterprise and half-DIMM modes as desired
    /// @param[in] i_target the OCMB target to operate on
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
    {
        mss::display_git_commit_info("exp_omi_setup");

        // Declares variables
        fapi2::buffer<uint64_t> l_data;
        bool l_is_enterprise = false;
        bool l_is_half_dimm = false;

        // Gets the configuration information from attributes
        FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise));
        FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm));

        // Prints out the data
        FAPI_INF("%s is %s enterprise mode, and %s-DIMM mode", mss::c_str(i_target), l_is_enterprise ? "" : "non",
                 l_is_half_dimm ? "half" : "full");

        // Sets up the register
        mss::exp::omi::set_enterprise_set_bit(l_data, l_is_enterprise);
        mss::exp::omi::set_half_dimm_mode(l_data, l_is_half_dimm);

        // Writes the data to the register
        FAPI_TRY(mss::exp::omi::write_enterprise_config(i_target, l_data));

        // Checks that the chip is configured correctly
        FAPI_TRY(mss::exp::omi::read_enterprise_config(i_target, l_data));
        FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data));

    fapi_try_exit:
        return fapi2::current_err;
    }
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_draminit_training.C
/// @brief Train dram
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP FW Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

using fapi2::TARGET_TYPE_MCBIST;

extern "C"
{
///
/// @brief Train dram
/// @param[in] i_target, the McBIST of the ports of the dram you're training
/// @return FAPI2_RC_SUCCESS iff ok
///
    fapi2::ReturnCode p9_mss_draminit_training( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
    {
        FAPI_INF("Start draminit training");
        FAPI_INF("End draminit training");
        return fapi2::FAPI2_RC_SUCCESS;
    }
}
<commit_msg>Include .H files in their respective C files to avoid compilation error<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_draminit_training.C
/// @brief Train dram
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP FW Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include "p9_mss_draminit_training.H"

using fapi2::TARGET_TYPE_MCBIST;

extern "C"
{
///
/// @brief Train dram
/// @param[in] i_target, the McBIST of the ports of the dram you're training
/// @return FAPI2_RC_SUCCESS iff ok
///
    fapi2::ReturnCode p9_mss_draminit_training( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
    {
        FAPI_INF("Start draminit training");
        FAPI_INF("End draminit training");
        return fapi2::FAPI2_RC_SUCCESS;
    }
}
<|endoftext|>


<commit_before>#include "ComponentMessenger.hpp"
#include <Core/Utils/StdUtils.hpp>
namespace Ra {
namespace Engine {

inline std::size_t ComponentMessenger::HashFunc::operator()( const Key& k ) const {
    return Core::Utils::hash( k );
}

template <typename ReturnType>
inline typename ComponentMessenger::CallbackTypes<ReturnType>::Getter
ComponentMessenger::getterCallback( const Entity* entity, const std::string& id ) {
    CORE_ASSERT( canGet<ReturnType>( entity, id ), "Unregistered callback" );
    return static_cast<GetterCallback<ReturnType>*>(
               m_entityGetLists[entity][Key( id, std::type_index( typeid( ReturnType ) ) )].get() )
        ->m_cb;
}

template <typename ReturnType>
inline typename ComponentMessenger::CallbackTypes<ReturnType>::ReadWrite
ComponentMessenger::rwCallback( const Entity* entity, const std::string& id ) {
    CORE_ASSERT( canRw<ReturnType>( entity, id ), "Unregistered callback" );
    return static_cast<RwCallback<ReturnType>*>(
               m_entityRwLists[entity][Key( id, std::type_index( typeid( ReturnType ) ) )].get() )
        ->m_cb;
}

template <typename ReturnType>
inline typename ComponentMessenger::CallbackTypes<ReturnType>::Setter
ComponentMessenger::setterCallback( const Entity* entity, const std::string& id ) {
    CORE_ASSERT( canSet<ReturnType>( entity, id ), "Unregistered callback" );
    return static_cast<SetterCallback<ReturnType>*>(
               m_entitySetLists[entity][Key( id, std::type_index( typeid( ReturnType ) ) )].get() )
        ->m_cb;
}

template <typename ReturnType>
inline const ReturnType& ComponentMessenger::get( const Entity* entity, const std::string& id ) {
    return CallbackTypes<ReturnType>::getHelper( getterCallback<ReturnType>( entity, id ) );
}
/*
        template<typename ReturnType>
        inline void ComponentMessenger::set(const Entity* entity, const std::string& id, const
   ReturnType& x)
        {
            return setterCallback<ReturnType>(entity, id)(x);
        }
*/
template <typename ReturnType>
inline bool ComponentMessenger::canGet( const Entity* entity, const std::string& id ) {
    // Attempt to find the given entity list.
    const auto& entityListPos = m_entityGetLists.find( entity );
    if ( entityListPos == m_entityGetLists.end() )
        return false; // Entity has no registered component

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    const CallbackMap& entityList = entityListPos->second;

    // Check if there are components exporting the given type,
    // so let's try to find if there is one with the requested id.
    const auto& callbackEntry = entityList.find( key );
    const bool found          = ( callbackEntry != entityList.end() );
    return found;
}

template <typename ReturnType>
inline bool ComponentMessenger::canSet( const Entity* entity, const std::string& id ) {
    // Attempt to find the given entity list.
    auto entityListPos = m_entitySetLists.find( entity );
    if ( entityListPos == m_entitySetLists.end() )
        return false; // Entity has no registered component

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    const CallbackMap& entityList = entityListPos->second;

    // Check if there are components exporting the given type,
    // so let's try to find if there is one with the requested id.
    const auto& callbackEntry = entityList.find( key );
    const bool found          = ( callbackEntry != entityList.end() );
    return found;
}

template <typename ReturnType>
inline bool ComponentMessenger::canRw( const Entity* entity, const std::string& id ) {
    // Attempt to find the given entity list.
    const auto& entityListPos = m_entityRwLists.find( entity );
    if ( entityListPos == m_entityRwLists.end() )
        return false; // Entity has no registered component

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    const CallbackMap& entityList = entityListPos->second;

    // Check if there are components exporting the given type,
    // so let's try to find if there is one with the requested id.
    const auto& callbackEntry = entityList.find( key );
    const bool found          = ( callbackEntry != entityList.end() );
    return found;
}

template <typename ReturnType>
inline void
ComponentMessenger::registerOutput( const Entity* entity,
                                    Component* comp,
                                    const std::string& id,
                                    const typename CallbackTypes<ReturnType>::Getter& cb ) {
    CORE_ASSERT( entity && comp->getEntity() == entity, "Component not added to entity" );
    CORE_UNUSED( comp );
    // Will insert a new entity entry if it doesn't exist.
    CallbackMap& entityList = m_entityGetLists[entity];

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    CORE_ASSERT( entityList.find( key ) == entityList.end(), "Output function already registered" );

    GetterCallback<ReturnType>* getter = new GetterCallback<ReturnType>();
    getter->m_cb                       = cb;
    entityList[key].reset( getter );
}

template <typename ReturnType>
inline void
ComponentMessenger::registerReadWrite( const Entity* entity,
                                       Component* comp,
                                       const std::string& id,
                                       const typename CallbackTypes<ReturnType>::ReadWrite& cb ) {
    CORE_ASSERT( entity && comp->getEntity() == entity, "Component not added to entity" );
    CORE_UNUSED( comp );
    // Will insert a new entity entry if it doesn't exist.
    CallbackMap& entityList = m_entityRwLists[entity];

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    CORE_ASSERT( entityList.find( key ) == entityList.end(), "Rw function already registered" );

    RwCallback<ReturnType>* rw = new RwCallback<ReturnType>();
    rw->m_cb                   = cb;
    entityList[key].reset( rw );
}

template <typename ReturnType>
inline void
ComponentMessenger::registerInput( const Entity* entity,
                                   Component* comp,
                                   const std::string& id,
                                   const typename CallbackTypes<ReturnType>::Setter& cb ) {
    CORE_ASSERT( entity && comp->getEntity() == entity, "Component not added to entity" );
    // Will insert a new entity entry if it doesn't exist.
    CallbackMap& entityList = m_entitySetLists[entity];

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    CORE_ASSERT( entityList.find( key ) == entityList.end(), "Input function already registered" );

    SetterCallback<ReturnType>* setter = new SetterCallback<ReturnType>();
    setter->m_cb                       = cb;
    entityList[key].reset( setter );
}

} // namespace Engine
} // namespace Ra
<commit_msg>[engine] ComponentManager: More verbose errors.<commit_after>#include "ComponentMessenger.hpp"
#include <Core/Utils/StdUtils.hpp>
namespace Ra {
namespace Engine {

inline std::size_t ComponentMessenger::HashFunc::operator()( const Key& k ) const {
    return Core::Utils::hash( k );
}

template <typename ReturnType>
inline typename ComponentMessenger::CallbackTypes<ReturnType>::Getter
ComponentMessenger::getterCallback( const Entity* entity, const std::string& id ) {
    CORE_ASSERT( canGet<ReturnType>( entity, id ), "Unregistered callback" );
    return static_cast<GetterCallback<ReturnType>*>(
               m_entityGetLists[entity][Key( id, std::type_index( typeid( ReturnType ) ) )].get() )
        ->m_cb;
}

template <typename ReturnType>
inline typename ComponentMessenger::CallbackTypes<ReturnType>::ReadWrite
ComponentMessenger::rwCallback( const Entity* entity, const std::string& id ) {
    CORE_ASSERT( canRw<ReturnType>( entity, id ), "Unregistered callback" );
    return static_cast<RwCallback<ReturnType>*>(
               m_entityRwLists[entity][Key( id, std::type_index( typeid( ReturnType ) ) )].get() )
        ->m_cb;
}

template <typename ReturnType>
inline typename ComponentMessenger::CallbackTypes<ReturnType>::Setter
ComponentMessenger::setterCallback( const Entity* entity, const std::string& id ) {
    CORE_ASSERT( canSet<ReturnType>( entity, id ), "Unregistered callback" );
    return static_cast<SetterCallback<ReturnType>*>(
               m_entitySetLists[entity][Key( id, std::type_index( typeid( ReturnType ) ) )].get() )
        ->m_cb;
}

template <typename ReturnType>
inline const ReturnType& ComponentMessenger::get( const Entity* entity, const std::string& id ) {
    return CallbackTypes<ReturnType>::getHelper( getterCallback<ReturnType>( entity, id ) );
}
/*
        template<typename ReturnType>
        inline void ComponentMessenger::set(const Entity* entity, const std::string& id, const
   ReturnType& x)
        {
            return setterCallback<ReturnType>(entity, id)(x);
        }
*/
template <typename ReturnType>
inline bool ComponentMessenger::canGet( const Entity* entity, const std::string& id ) {
    // Attempt to find the given entity list.
    const auto& entityListPos = m_entityGetLists.find( entity );
    if ( entityListPos == m_entityGetLists.end() )
        return false; // Entity has no registered component

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    const CallbackMap& entityList = entityListPos->second;

    // Check if there are components exporting the given type,
    // so let's try to find if there is one with the requested id.
    const auto& callbackEntry = entityList.find( key );
    const bool found          = ( callbackEntry != entityList.end() );
    return found;
}

template <typename ReturnType>
inline bool ComponentMessenger::canSet( const Entity* entity, const std::string& id ) {
    // Attempt to find the given entity list.
    auto entityListPos = m_entitySetLists.find( entity );
    if ( entityListPos == m_entitySetLists.end() )
        return false; // Entity has no registered component

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    const CallbackMap& entityList = entityListPos->second;

    // Check if there are components exporting the given type,
    // so let's try to find if there is one with the requested id.
    const auto& callbackEntry = entityList.find( key );
    const bool found          = ( callbackEntry != entityList.end() );
    return found;
}

template <typename ReturnType>
inline bool ComponentMessenger::canRw( const Entity* entity, const std::string& id ) {
    // Attempt to find the given entity list.
    const auto& entityListPos = m_entityRwLists.find( entity );
    if ( entityListPos == m_entityRwLists.end() )
        return false; // Entity has no registered component

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    const CallbackMap& entityList = entityListPos->second;

    // Check if there are components exporting the given type,
    // so let's try to find if there is one with the requested id.
    const auto& callbackEntry = entityList.find( key );
    const bool found          = ( callbackEntry != entityList.end() );
    return found;
}

template <typename ReturnType>
inline void
ComponentMessenger::registerOutput( const Entity* entity,
                                    Component* comp,
                                    const std::string& id,
                                    const typename CallbackTypes<ReturnType>::Getter& cb ) {
    CORE_ASSERT( entity && comp->getEntity() == entity, "Component not added to entity" );
    CORE_UNUSED( comp );
    // Will insert a new entity entry if it doesn't exist.
    CallbackMap& entityList = m_entityGetLists[entity];

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    CORE_ASSERT( entityList.find( key ) == entityList.end(), "Output function already registered for " + id );

    GetterCallback<ReturnType>* getter = new GetterCallback<ReturnType>();
    getter->m_cb                       = cb;
    entityList[key].reset( getter );
}

template <typename ReturnType>
inline void
ComponentMessenger::registerReadWrite( const Entity* entity,
                                       Component* comp,
                                       const std::string& id,
                                       const typename CallbackTypes<ReturnType>::ReadWrite& cb ) {
    CORE_ASSERT( entity && comp->getEntity() == entity, "Component not added to entity" );
    CORE_UNUSED( comp );
    // Will insert a new entity entry if it doesn't exist.
    CallbackMap& entityList = m_entityRwLists[entity];

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    CORE_ASSERT( entityList.find( key ) == entityList.end(), "Rw function already registered for " + id);

    RwCallback<ReturnType>* rw = new RwCallback<ReturnType>();
    rw->m_cb                   = cb;
    entityList[key].reset( rw );
}

template <typename ReturnType>
inline void
ComponentMessenger::registerInput( const Entity* entity,
                                   Component* comp,
                                   const std::string& id,
                                   const typename CallbackTypes<ReturnType>::Setter& cb ) {
    CORE_ASSERT( entity && comp->getEntity() == entity, "Component not added to entity" );
    // Will insert a new entity entry if it doesn't exist.
    CallbackMap& entityList = m_entitySetLists[entity];

    Key key( id, std::type_index( typeid( ReturnType ) ) );
    CORE_ASSERT( entityList.find( key ) == entityList.end(), "Input function already registered for " + id );

    SetterCallback<ReturnType>* setter = new SetterCallback<ReturnType>();
    setter->m_cb                       = cb;
    entityList[key].reset( setter );
}

} // namespace Engine
} // namespace Ra
<|endoftext|>


<commit_before>#include <vtkSphereSource.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

#include "system/parse_stl.h"

#include "mainwindow.h"
#include "ui_mainwindow.h"

using namespace gca;

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)//, ui(new Ui::MainWindow)
{
  //ui->setupUi(this);

  vtk_window = new QVTKWidget(this, Qt::Widget);
  setCentralWidget(vtk_window);

  auto m =
    parse_stl("/Users/dillon/CppWorkspace/gca/test/stl-files/onshape_parts/SmallReverseCameraMount - Part 1.stl", 0.0001);

  vtkSmartPointer<vtkSphereSource> sphereSource =
    vtkSmartPointer<vtkSphereSource>::New();
  sphereSource->SetCenter(0.0, 0.0, 0.0);
  sphereSource->SetRadius(5.0);

  vtkSmartPointer<vtkPolyDataMapper> mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(sphereSource->GetOutputPort());

  vtkSmartPointer<vtkActor> actor =
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();

  renderer->SetBackground(1, 1, 1);
  renderer->AddActor(actor);

  vtk_window->GetRenderWindow()->AddRenderer(renderer);

  vtk_window->show();

}

MainWindow::~MainWindow()
{
}
<commit_msg>Can now parse and display a mesh<commit_after>#include <vtkSphereSource.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

#include "geometry/vtk_utils.h"
#include "system/parse_stl.h"

#include "mainwindow.h"
#include "ui_mainwindow.h"

using namespace gca;

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)//, ui(new Ui::MainWindow)
{
  //ui->setupUi(this);

  vtk_window = new QVTKWidget(this, Qt::Widget);
  setCentralWidget(vtk_window);

  auto m =
    parse_stl("/Users/dillon/CppWorkspace/gca/test/stl-files/onshape_parts/SmallReverseCameraMount - Part 1.stl", 0.0001);

  auto mesh_pd = polydata_for_trimesh(m);

  // vtkSmartPointer<vtkSphereSource> sphereSource =
  //   vtkSmartPointer<vtkSphereSource>::New();
  // sphereSource->SetCenter(0.0, 0.0, 0.0);
  // sphereSource->SetRadius(5.0);

  vtkSmartPointer<vtkPolyDataMapper> mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputData(mesh_pd); //sphereSource->GetOutputPort());

  vtkSmartPointer<vtkActor> actor =
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();

  renderer->SetBackground(1, 1, 1);
  renderer->AddActor(actor);

  vtk_window->GetRenderWindow()->AddRenderer(renderer);

  vtk_window->show();

}

MainWindow::~MainWindow()
{
}
<|endoftext|>


<commit_before>
#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)

#include "os/memory.h"
#include "rw_lock_posix.h"
#include "error_macros.h"
#include <stdio.h>

void RWLockPosix::read_lock() {

	int err =pthread_rwlock_rdlock(&rwlock);
	if (err!=0) {
		perror("wtf: ");
	}
	ERR_FAIL_COND(err!=0);
}

void RWLockPosix::read_unlock() {

	pthread_rwlock_unlock(&rwlock);
}

Error RWLockPosix::read_try_lock() {

	if (pthread_rwlock_tryrdlock(&rwlock)!=0) {
		return ERR_BUSY;
	} else {
		return OK;
	}

}

void RWLockPosix::write_lock() {

	int err = pthread_rwlock_wrlock(&rwlock);
	ERR_FAIL_COND(err!=0);
}

void RWLockPosix::write_unlock() {

	pthread_rwlock_unlock(&rwlock);
}

Error RWLockPosix::write_try_lock() {
	if (pthread_rwlock_trywrlock(&rwlock)!=0) {
		return ERR_BUSY;
	} else {
		return OK;
	}
}

RWLock *RWLockPosix::create_func_posix() {

	return memnew( RWLockPosix );
}

void RWLockPosix::make_default() {

	create_func=create_func_posix;
}

RWLockPosix::RWLockPosix() {

	rwlock=PTHREAD_RWLOCK_INITIALIZER;
}

RWLockPosix::~RWLockPosix() {

	pthread_rwlock_destroy(&rwlock);

}

#endif
<commit_msg>Use more compatible initializarion of RWLockPosix<commit_after>
#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)

#include "os/memory.h"
#include "rw_lock_posix.h"
#include "error_macros.h"
#include <stdio.h>

void RWLockPosix::read_lock() {

	int err =pthread_rwlock_rdlock(&rwlock);
	if (err!=0) {
		perror("wtf: ");
	}
	ERR_FAIL_COND(err!=0);
}

void RWLockPosix::read_unlock() {

	pthread_rwlock_unlock(&rwlock);
}

Error RWLockPosix::read_try_lock() {

	if (pthread_rwlock_tryrdlock(&rwlock)!=0) {
		return ERR_BUSY;
	} else {
		return OK;
	}

}

void RWLockPosix::write_lock() {

	int err = pthread_rwlock_wrlock(&rwlock);
	ERR_FAIL_COND(err!=0);
}

void RWLockPosix::write_unlock() {

	pthread_rwlock_unlock(&rwlock);
}

Error RWLockPosix::write_try_lock() {
	if (pthread_rwlock_trywrlock(&rwlock)!=0) {
		return ERR_BUSY;
	} else {
		return OK;
	}
}

RWLock *RWLockPosix::create_func_posix() {

	return memnew( RWLockPosix );
}

void RWLockPosix::make_default() {

	create_func=create_func_posix;
}

RWLockPosix::RWLockPosix() {

	//rwlock=PTHREAD_RWLOCK_INITIALIZER; fails on OSX
	pthread_rwlock_init(&rwlock,NULL);
}

RWLockPosix::~RWLockPosix() {

	pthread_rwlock_destroy(&rwlock);

}

#endif
<|endoftext|>


<commit_before>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <malloc.h>

#include "Engine.h"
#include "Tools/File.h"
#include "Tools/Directory.h"
#include "Tools/Error.h"
#ifdef _WIN32
#include "Tools/Win32/getopt.h"
#else
#include <getopt.h>
#endif

#include "Mare.h"
#include "Make.h"
#include "Vcxproj.h"
#include "Vcproj.h"
#include "CodeLite.h"
#include "CodeBlocks.h"
#include "CMake.h"
#include "NetBeans.h"

static const char* VERSION   = "0.3";
static const char* COPYRIGHT = "Copyright (C) 2011-2013 Colin Graf";

static void errorHandler(void* userData, const String& file, int line, const String& message)
{
  if(line < 0)
    fprintf(stderr, "%s: %s\n", (const char*)userData, message.getData());
  else
  {
    if(line > 0)
      fprintf(stderr, "%s:%u: error: %s\n", file.getData(), line, message.getData());
    else
      fprintf(stderr, "%s: %s\n", file.getData(), message.getData());
  }
}

static void showVersion(bool andExit)
{
  printf("mare %s, the lightweight build system\n", VERSION);
  puts(COPYRIGHT);
  //printf("Author(s): %s\n", AUTHORS);
  puts("This program comes with ABSOLUTELY NO WARRANTY.");
  puts("This is free software, and you are welcome to redistribute it under certain");
  puts("conditions.");
  if(andExit)
    exit(EXIT_SUCCESS);
}

static void showUsage(const char* executable)
{
  String basename = File::getBasename(String(executable, -1));
  showVersion(false);
  puts("");
  printf("Usage: %s [ -f <file> ] [ <options> ] [ config=<config> ] [ <target> ]\n", basename.getData());
  puts("        [ platform=<platform> ] [ <variable>=<value> ] [ clean | rebuild ]");
  puts("");
  puts("Options:");
  puts("");
  puts("    -f <file>, --file=<file>");
  puts("        Use <file> as input marefile.");
  puts("        The default value of <file> is \"Marefile\".");
  puts("");
  puts("    --vcxproj[=<version>]");
  puts("        Convert the marefile into a .sln and .vcxproj files for Visual Studio.");
  puts("        <version> can be set to 2010, 2012, 2013 or 2015.");
  puts("");
  puts("    --vcproj[=<version>]");
  puts("        Convert the marefile into a .sln and .vcproj files for Visual Studio.");
  puts("        <version> can be set to 2008.");
  puts("");
  puts("    --make");
  puts("        Try to translate the marefile into a Makefile. (experimental)");
  puts("");
  puts("    --codelite");
  puts("        Try to translate the marefile into a .workspace and .project files for");
  puts("        CodeLite. (experimental)");
  puts("");
  puts("    --codeblocks");
  puts("        Try to translate the marefile into a .workspace and .cbp files for");
  puts("        Code::Blocks. (experimental)");
  puts("");
  puts("    --cmake");
  puts("        Try to translate the marefile into a CMakeLists.txt files for cmake.");
  puts("        (experimental)");
  puts("");
  puts("    --netbeans");
  puts("        Generate project files for NetBeans. (experimental)");
  puts("");
  puts("    config=<config>, --config=<config>");
  puts("        Build using configuration <config> as declared in the marefile (Debug");
  puts("        and Release by default). Multiple configurations can be used by adding");
  puts("        config=<config> multiple times.");
  puts("");
  puts("    <target>, target=<target>, --target=<target>");
  puts("        Build <target> as declared in the marefile. Multiple targets can be");
  puts("        used.");
  puts("");
  puts("    platform=<config>, --platform=<config>");
  puts("        Build the target for platform <platform>. By default the native");
  puts("        build platform of the mare executable or the native platform of a");
  puts("        generator (e.g. \"Win32\" for vcxproj) will be used. Multiple platforms");
  puts("        can be used by adding platform=<platform> multiple times. Available");
  puts("        platforms can be declared in the mare.");
  puts("");
  puts("    <variable>=<value>, --<variable>[=<value>]");
  puts("        Set any variable <variable> to <value>. This can be used to set");
  puts("        various options with a meaning defined by the marefile.");
  puts("");
  puts("    clean, --clean");
  puts("        Delete all output files instead of building the selected target.");
  puts("");
  puts("    rebuild, --rebuild");
  puts("        Rebuild all output files of the selected target.");
  puts("");
  puts("    -C <dir>, --directory=<dir>");
  puts("        Change working directory to <dir> before doing anything else.");
  puts("");
  puts("    -d");
  puts("        Print debugging information while processing normally.");
  puts("");
  puts("    -j <jobs>");
  puts("        Use <jobs> processes in parallel for building alle targets. The default");
  puts("        value for <jobs> is the number of processors on the host system.");
  puts("");
  puts("    --ignore-dependencies");
  puts("        Do not respect dependencies between build targets.");
  puts("");
  puts("    -h, --help");
  puts("        Display this help message or a help message declared in the marefile.");
  puts("");
  puts("    -v, --version");
  puts("        Display version information.");
  puts("");
  exit(EXIT_SUCCESS);
}

static void showHelp(const char* executable)
{
  fprintf(stderr, "Type '%s --help' for help\n", executable);
  exit(EXIT_FAILURE);
}

int main(int argc, char* argv[])
{
  Map<String, String> userArgs;
  List<String> inputPlatforms, inputConfigs, inputTargets;
  String inputFile("Marefile"), inputDir;
  bool showHelp = false;
  bool showDebug = false;
  bool clean = false;
  bool rebuild = false;
  bool ignoreDependencies = false;
  int jobs = 0;
  bool generateMake = false;
  int generateVcxproj = 0;
  int generateVcproj = 0;
  bool generateCodeLite = false;
  bool generateCodeBlocks = false;
  bool generateCMake = false;
  bool generateNetBeans = false;

  // parse args
  {
    int c, option_index;
    static struct option long_options[] = {
      {"file", required_argument , 0, 'f'},
      {"help", no_argument , 0, 'h'},
      {"version", no_argument , 0, 'v'},
      {"directory", required_argument , 0, 'C'},
      {"clean", no_argument , 0, 0},
      {"rebuild", no_argument , 0, 0},
      {"ignore-dependencies", no_argument , 0, 0},
      {"make", no_argument , 0, 0},
      {"vcxproj", optional_argument , 0, 0},
      {"vcproj", optional_argument , 0, 0},
      {"codelite", no_argument , 0, 0},
      {"codeblocks", no_argument , 0, 0},
      {"cmake", no_argument , 0, 0},
      {"netbeans", no_argument , 0, 0},
      {0, 0, 0, 0}
    };

    // find and remove all user arguments
    char** nargv = (char**)alloca(sizeof(char*) * argc);
    int nargc = 1;
    nargv[0] = argv[0];
    for(int i = 1; i < argc; ++i)
    {
      if(strncmp(argv[i], "--", 2) != 0)
        nargv[nargc++] = argv[i];
      else
      {
        const char* arg = argv[i] + 2;
        unsigned int arglen = strlen(arg);
        const char* argarg = strchr(arg, '=');
        if(argarg)
          arglen = argarg - arg;
        for(struct option* opt = long_options; opt->name; ++opt)
          if(strncmp(arg, opt->name, arglen) == 0 && strlen(opt->name) == arglen)
          {
            nargv[nargc++] = argv[i];
            goto nextarg;
          }
        const char* sep = strchr(arg, '=');
        if(sep)
        {
          String key(arg, sep - arg);
          String val(sep + 1, -1);
          if(key == "platform")
            inputPlatforms.append(val);
          else if(key == "config")
            inputConfigs.append(val);
          else if(key == "target")
            inputTargets.append(val);
          else
            userArgs.append(key, val);
        }
        else
          userArgs.append(String(arg, -1), String());
      }
    nextarg:;
    }
    argc = nargc;
    argv = nargv;

    // parse normal arguments
    while((c = getopt_long(argc, argv, "C:df:hj:v", long_options, &option_index)) != -1)
      switch(c)
      {
      case 0:
        {
          String opt(long_options[option_index].name, -1);
          if(opt == "make")
            generateMake = true;
          else if(opt == "vcxproj")
          {
            generateVcxproj = 2010;
            if(optarg)
            {
              if(strcmp(optarg, "2010") == 0)
                generateVcxproj = 2010;
              else if(strcmp(optarg, "2012") == 0)
                generateVcxproj = 2012;
              else if(strcmp(optarg, "2013") == 0)
                generateVcxproj = 2013;
			  else if (strcmp(optarg, "2015") == 0)
				  generateVcxproj = 2015;
              else // unknown version
                ::showHelp(argv[0]);
            }
          }
          else if(opt == "vcproj")
          {
            generateVcproj = 2008;
            if(optarg)
            {
              if(strcmp(optarg, "2008") == 0)
                generateVcproj = 2008;
              else // unknown version
                ::showHelp(argv[0]);
            }
          }
          else if(opt == "codelite")
            generateCodeLite = true;
          else if(opt == "codeblocks")
            generateCodeBlocks = true;
          else if(opt == "cmake")
            generateCMake = true;
          else if(opt == "netbeans")
            generateNetBeans = true;
          else if(opt == "clean")
            clean = true;
          else if(opt == "rebuild")
            rebuild = true;
          else if(opt == "ignore-dependencies")
            ignoreDependencies = true;
        }
        break;
      case 'C':
        inputDir = String(optarg, -1);
        break;
      case 'd':
        showDebug = true;
        break;
      case 'f':
        inputFile = String(optarg, -1);
        break;
      case 'h':
        showHelp = true;
        break;
      case 'j':
        jobs = atoi(optarg);
        break;
      case 'v':
        showVersion(true);
        break;
      default:
        ::showHelp(argv[0]);
        break;
      }
    while(optind < argc)
    {
      const char* arg = argv[optind++];
      const char* sep = strchr(arg, '=');
      if(sep)
      {
        String key(arg, sep - arg);
        String val(sep + 1, -1);
        if(key == "platform")
          inputPlatforms.append(val);
        else if(key == "config")
          inputConfigs.append(val);
        else if(key == "target")
          inputTargets.append(val);
        else
          userArgs.append(key, val);
      }
      else
      {
        String target(arg, -1);
        if(target == "clean")
          clean = true;
        else if(target == "rebuild")
          rebuild = true;
        else
          inputTargets.append(target);
      }
    }
  }

  // change working directory?
  if(!inputDir.isEmpty())
  {
    if(!Directory::change(inputDir))
    {
      // TODO: error message
      return EXIT_FAILURE;
    }
  }

  // start the engine
  {
    Engine engine(errorHandler, argv[0]);
    if(!engine.load(inputFile))
    {
      if(showHelp)
        showUsage(argv[0]);

      return EXIT_FAILURE;
    }

    // show help only?
    if(showHelp)
    {
      engine.enterRootKey();
      if(engine.enterKey("help"))
      {
        List<String> help;
        engine.getText(help);
        for(List<String>::Node* node = help.getFirst(); node; node = node->getNext())
          puts(node->data.getData());
        return EXIT_SUCCESS;
      }
      else
        showUsage(argv[0]);
    }

    // generate Makefile mode?
    if(generateMake)
    {
      Make make(engine);
      if(!make.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate vcxproj mode?
    if(generateVcxproj)
    {
      Vcxproj vcxprog(engine, generateVcxproj);
      if(!vcxprog.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate vcproj mode?
    if(generateVcproj)
    {
      Vcproj vcproj(engine, generateVcproj);
      if(!vcproj.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate codelite mode?
    if(generateCodeLite)
    {
      CodeLite codeLite(engine);
      if(!codeLite.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate codeblocks mode?
    if(generateCodeBlocks)
    {
      CodeBlocks codeBlocks(engine);
      if(!codeBlocks.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate codeblocks mode?
    if(generateCMake)
    {
      CMake cMake(engine, inputConfigs);
      if(!cMake.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate codeblocks mode?
    if(generateNetBeans)
    {
      NetBeans netBeans(engine);
      if(!netBeans.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // direct build
    {
      Mare mare(engine, inputPlatforms, inputConfigs, inputTargets, showDebug, clean, rebuild, jobs, ignoreDependencies);
      if(!mare.build(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }
  }
}
<commit_msg>Formatting<commit_after>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <malloc.h>

#include "Engine.h"
#include "Tools/File.h"
#include "Tools/Directory.h"
#include "Tools/Error.h"
#ifdef _WIN32
#include "Tools/Win32/getopt.h"
#else
#include <getopt.h>
#endif

#include "Mare.h"
#include "Make.h"
#include "Vcxproj.h"
#include "Vcproj.h"
#include "CodeLite.h"
#include "CodeBlocks.h"
#include "CMake.h"
#include "NetBeans.h"

static const char* VERSION   = "0.3";
static const char* COPYRIGHT = "Copyright (C) 2011-2013 Colin Graf";

static void errorHandler(void* userData, const String& file, int line, const String& message)
{
  if(line < 0)
    fprintf(stderr, "%s: %s\n", (const char*)userData, message.getData());
  else
  {
    if(line > 0)
      fprintf(stderr, "%s:%u: error: %s\n", file.getData(), line, message.getData());
    else
      fprintf(stderr, "%s: %s\n", file.getData(), message.getData());
  }
}

static void showVersion(bool andExit)
{
  printf("mare %s, the lightweight build system\n", VERSION);
  puts(COPYRIGHT);
  //printf("Author(s): %s\n", AUTHORS);
  puts("This program comes with ABSOLUTELY NO WARRANTY.");
  puts("This is free software, and you are welcome to redistribute it under certain");
  puts("conditions.");
  if(andExit)
    exit(EXIT_SUCCESS);
}

static void showUsage(const char* executable)
{
  String basename = File::getBasename(String(executable, -1));
  showVersion(false);
  puts("");
  printf("Usage: %s [ -f <file> ] [ <options> ] [ config=<config> ] [ <target> ]\n", basename.getData());
  puts("        [ platform=<platform> ] [ <variable>=<value> ] [ clean | rebuild ]");
  puts("");
  puts("Options:");
  puts("");
  puts("    -f <file>, --file=<file>");
  puts("        Use <file> as input marefile.");
  puts("        The default value of <file> is \"Marefile\".");
  puts("");
  puts("    --vcxproj[=<version>]");
  puts("        Convert the marefile into a .sln and .vcxproj files for Visual Studio.");
  puts("        <version> can be set to 2010, 2012, 2013 or 2015.");
  puts("");
  puts("    --vcproj[=<version>]");
  puts("        Convert the marefile into a .sln and .vcproj files for Visual Studio.");
  puts("        <version> can be set to 2008.");
  puts("");
  puts("    --make");
  puts("        Try to translate the marefile into a Makefile. (experimental)");
  puts("");
  puts("    --codelite");
  puts("        Try to translate the marefile into a .workspace and .project files for");
  puts("        CodeLite. (experimental)");
  puts("");
  puts("    --codeblocks");
  puts("        Try to translate the marefile into a .workspace and .cbp files for");
  puts("        Code::Blocks. (experimental)");
  puts("");
  puts("    --cmake");
  puts("        Try to translate the marefile into a CMakeLists.txt files for cmake.");
  puts("        (experimental)");
  puts("");
  puts("    --netbeans");
  puts("        Generate project files for NetBeans. (experimental)");
  puts("");
  puts("    config=<config>, --config=<config>");
  puts("        Build using configuration <config> as declared in the marefile (Debug");
  puts("        and Release by default). Multiple configurations can be used by adding");
  puts("        config=<config> multiple times.");
  puts("");
  puts("    <target>, target=<target>, --target=<target>");
  puts("        Build <target> as declared in the marefile. Multiple targets can be");
  puts("        used.");
  puts("");
  puts("    platform=<config>, --platform=<config>");
  puts("        Build the target for platform <platform>. By default the native");
  puts("        build platform of the mare executable or the native platform of a");
  puts("        generator (e.g. \"Win32\" for vcxproj) will be used. Multiple platforms");
  puts("        can be used by adding platform=<platform> multiple times. Available");
  puts("        platforms can be declared in the mare.");
  puts("");
  puts("    <variable>=<value>, --<variable>[=<value>]");
  puts("        Set any variable <variable> to <value>. This can be used to set");
  puts("        various options with a meaning defined by the marefile.");
  puts("");
  puts("    clean, --clean");
  puts("        Delete all output files instead of building the selected target.");
  puts("");
  puts("    rebuild, --rebuild");
  puts("        Rebuild all output files of the selected target.");
  puts("");
  puts("    -C <dir>, --directory=<dir>");
  puts("        Change working directory to <dir> before doing anything else.");
  puts("");
  puts("    -d");
  puts("        Print debugging information while processing normally.");
  puts("");
  puts("    -j <jobs>");
  puts("        Use <jobs> processes in parallel for building alle targets. The default");
  puts("        value for <jobs> is the number of processors on the host system.");
  puts("");
  puts("    --ignore-dependencies");
  puts("        Do not respect dependencies between build targets.");
  puts("");
  puts("    -h, --help");
  puts("        Display this help message or a help message declared in the marefile.");
  puts("");
  puts("    -v, --version");
  puts("        Display version information.");
  puts("");
  exit(EXIT_SUCCESS);
}

static void showHelp(const char* executable)
{
  fprintf(stderr, "Type '%s --help' for help\n", executable);
  exit(EXIT_FAILURE);
}

int main(int argc, char* argv[])
{
  Map<String, String> userArgs;
  List<String> inputPlatforms, inputConfigs, inputTargets;
  String inputFile("Marefile"), inputDir;
  bool showHelp = false;
  bool showDebug = false;
  bool clean = false;
  bool rebuild = false;
  bool ignoreDependencies = false;
  int jobs = 0;
  bool generateMake = false;
  int generateVcxproj = 0;
  int generateVcproj = 0;
  bool generateCodeLite = false;
  bool generateCodeBlocks = false;
  bool generateCMake = false;
  bool generateNetBeans = false;

  // parse args
  {
    int c, option_index;
    static struct option long_options[] = {
      {"file", required_argument , 0, 'f'},
      {"help", no_argument , 0, 'h'},
      {"version", no_argument , 0, 'v'},
      {"directory", required_argument , 0, 'C'},
      {"clean", no_argument , 0, 0},
      {"rebuild", no_argument , 0, 0},
      {"ignore-dependencies", no_argument , 0, 0},
      {"make", no_argument , 0, 0},
      {"vcxproj", optional_argument , 0, 0},
      {"vcproj", optional_argument , 0, 0},
      {"codelite", no_argument , 0, 0},
      {"codeblocks", no_argument , 0, 0},
      {"cmake", no_argument , 0, 0},
      {"netbeans", no_argument , 0, 0},
      {0, 0, 0, 0}
    };

    // find and remove all user arguments
    char** nargv = (char**)alloca(sizeof(char*) * argc);
    int nargc = 1;
    nargv[0] = argv[0];
    for(int i = 1; i < argc; ++i)
    {
      if(strncmp(argv[i], "--", 2) != 0)
        nargv[nargc++] = argv[i];
      else
      {
        const char* arg = argv[i] + 2;
        unsigned int arglen = strlen(arg);
        const char* argarg = strchr(arg, '=');
        if(argarg)
          arglen = argarg - arg;
        for(struct option* opt = long_options; opt->name; ++opt)
          if(strncmp(arg, opt->name, arglen) == 0 && strlen(opt->name) == arglen)
          {
            nargv[nargc++] = argv[i];
            goto nextarg;
          }
        const char* sep = strchr(arg, '=');
        if(sep)
        {
          String key(arg, sep - arg);
          String val(sep + 1, -1);
          if(key == "platform")
            inputPlatforms.append(val);
          else if(key == "config")
            inputConfigs.append(val);
          else if(key == "target")
            inputTargets.append(val);
          else
            userArgs.append(key, val);
        }
        else
          userArgs.append(String(arg, -1), String());
      }
    nextarg:;
    }
    argc = nargc;
    argv = nargv;

    // parse normal arguments
    while((c = getopt_long(argc, argv, "C:df:hj:v", long_options, &option_index)) != -1)
      switch(c)
      {
      case 0:
        {
          String opt(long_options[option_index].name, -1);
          if(opt == "make")
            generateMake = true;
          else if(opt == "vcxproj")
          {
            generateVcxproj = 2010;
            if(optarg)
            {
              if(strcmp(optarg, "2010") == 0)
                generateVcxproj = 2010;
              else if(strcmp(optarg, "2012") == 0)
                generateVcxproj = 2012;
              else if(strcmp(optarg, "2013") == 0)
                generateVcxproj = 2013;
              else if (strcmp(optarg, "2015") == 0)
                generateVcxproj = 2015;
              else // unknown version
                ::showHelp(argv[0]);
            }
          }
          else if(opt == "vcproj")
          {
            generateVcproj = 2008;
            if(optarg)
            {
              if(strcmp(optarg, "2008") == 0)
                generateVcproj = 2008;
              else // unknown version
                ::showHelp(argv[0]);
            }
          }
          else if(opt == "codelite")
            generateCodeLite = true;
          else if(opt == "codeblocks")
            generateCodeBlocks = true;
          else if(opt == "cmake")
            generateCMake = true;
          else if(opt == "netbeans")
            generateNetBeans = true;
          else if(opt == "clean")
            clean = true;
          else if(opt == "rebuild")
            rebuild = true;
          else if(opt == "ignore-dependencies")
            ignoreDependencies = true;
        }
        break;
      case 'C':
        inputDir = String(optarg, -1);
        break;
      case 'd':
        showDebug = true;
        break;
      case 'f':
        inputFile = String(optarg, -1);
        break;
      case 'h':
        showHelp = true;
        break;
      case 'j':
        jobs = atoi(optarg);
        break;
      case 'v':
        showVersion(true);
        break;
      default:
        ::showHelp(argv[0]);
        break;
      }
    while(optind < argc)
    {
      const char* arg = argv[optind++];
      const char* sep = strchr(arg, '=');
      if(sep)
      {
        String key(arg, sep - arg);
        String val(sep + 1, -1);
        if(key == "platform")
          inputPlatforms.append(val);
        else if(key == "config")
          inputConfigs.append(val);
        else if(key == "target")
          inputTargets.append(val);
        else
          userArgs.append(key, val);
      }
      else
      {
        String target(arg, -1);
        if(target == "clean")
          clean = true;
        else if(target == "rebuild")
          rebuild = true;
        else
          inputTargets.append(target);
      }
    }
  }

  // change working directory?
  if(!inputDir.isEmpty())
  {
    if(!Directory::change(inputDir))
    {
      // TODO: error message
      return EXIT_FAILURE;
    }
  }

  // start the engine
  {
    Engine engine(errorHandler, argv[0]);
    if(!engine.load(inputFile))
    {
      if(showHelp)
        showUsage(argv[0]);

      return EXIT_FAILURE;
    }

    // show help only?
    if(showHelp)
    {
      engine.enterRootKey();
      if(engine.enterKey("help"))
      {
        List<String> help;
        engine.getText(help);
        for(List<String>::Node* node = help.getFirst(); node; node = node->getNext())
          puts(node->data.getData());
        return EXIT_SUCCESS;
      }
      else
        showUsage(argv[0]);
    }

    // generate Makefile mode?
    if(generateMake)
    {
      Make make(engine);
      if(!make.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate vcxproj mode?
    if(generateVcxproj)
    {
      Vcxproj vcxprog(engine, generateVcxproj);
      if(!vcxprog.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate vcproj mode?
    if(generateVcproj)
    {
      Vcproj vcproj(engine, generateVcproj);
      if(!vcproj.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate codelite mode?
    if(generateCodeLite)
    {
      CodeLite codeLite(engine);
      if(!codeLite.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate codeblocks mode?
    if(generateCodeBlocks)
    {
      CodeBlocks codeBlocks(engine);
      if(!codeBlocks.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate codeblocks mode?
    if(generateCMake)
    {
      CMake cMake(engine, inputConfigs);
      if(!cMake.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // generate codeblocks mode?
    if(generateNetBeans)
    {
      NetBeans netBeans(engine);
      if(!netBeans.generate(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }

    // direct build
    {
      Mare mare(engine, inputPlatforms, inputConfigs, inputTargets, showDebug, clean, rebuild, jobs, ignoreDependencies);
      if(!mare.build(userArgs))
        return EXIT_FAILURE;
      return EXIT_SUCCESS;
    }
  }
}
<|endoftext|>