<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "txdb.h"
#include "main.h"
#include "auxpow.h"
#include "hash.h"

using namespace std;

void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) {
    if (coins.IsPruned())
        batch.Erase(make_pair('c', hash));
    else
        batch.Write(make_pair('c', hash), coins);
}

void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
    batch.Write('B', hash);
}

CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
}

bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) {
    return db.Read(make_pair('c', txid), coins);
}

bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) {
    CLevelDBBatch batch;
    BatchWriteCoins(batch, txid, coins);
    return db.WriteBatch(batch);
}

bool CCoinsViewDB::HaveCoins(const uint256 &txid) {
    return db.Exists(make_pair('c', txid));
}

CBlockIndex *CCoinsViewDB::GetBestBlock() {
    uint256 hashBestChain;
    if (!db.Read('B', hashBestChain))
        return NULL;
    std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(hashBestChain);
    if (it == mapBlockIndex.end())
        return NULL;
    return it->second;
}

bool CCoinsViewDB::SetBestBlock(CBlockIndex *pindex) {
    CLevelDBBatch batch;
    BatchWriteHashBestChain(batch, pindex->GetBlockHash());
    return db.WriteBatch(batch);
}

bool CCoinsViewDB::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) {
    printf("Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());

    CLevelDBBatch batch;
    for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
        BatchWriteCoins(batch, it->first, it->second);
    if (pindex)
        BatchWriteHashBestChain(batch, pindex->GetBlockHash());

    return db.WriteBatch(batch);
}

CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDB(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
}

bool CBlockTreeDB::WriteDiskBlockIndex(const CDiskBlockIndex& diskblockindex)
{
    return Write(boost::tuples::make_tuple('b', *diskblockindex.phashBlock, 'a'), diskblockindex);
}

bool CBlockTreeDB::WriteBlockIndex(const CBlockIndex& blockindex)
{
    return Write(boost::tuples::make_tuple('b', blockindex.GetBlockHash(), 'b'), blockindex);
}

bool CBlockTreeDB::ReadDiskBlockIndex(const uint256 &blkid, CDiskBlockIndex &diskblockindex) {
    return Read(boost::tuples::make_tuple('b', blkid, 'a'), diskblockindex);
}

bool CBlockTreeDB::ReadBestInvalidWork(CBigNum& bnBestInvalidWork)
{
    return Read('I', bnBestInvalidWork);
}

bool CBlockTreeDB::WriteBestInvalidWork(const CBigNum& bnBestInvalidWork)
{
    return Write('I', bnBestInvalidWork);
}

bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) {
    return Write(make_pair('f', nFile), info);
}

bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
    return Read(make_pair('f', nFile), info);
}

bool CBlockTreeDB::WriteLastBlockFile(int nFile) {
    return Write('l', nFile);
}

bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
    if (fReindexing)
        return Write('R', '1');
    else
        return Erase('R');
}

bool CBlockTreeDB::ReadReindexing(bool &fReindexing) {
    fReindexing = Exists('R');
    return true;
}

bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
    return Read('l', nFile);
}

bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
    boost::scoped_ptr<leveldb::Iterator> pcursor(db.NewIterator());
    pcursor->SeekToFirst();

    CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
    stats.hashBlock = GetBestBlock()->GetBlockHash();
    ss << stats.hashBlock;
    int64 nTotalAmount = 0;
    while (pcursor->Valid()) {
        boost::this_thread::interruption_point();
        try {
            leveldb::Slice slKey = pcursor->key();
            CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
            char chType;
            ssKey >> chType;
            if (chType == 'c') {
                leveldb::Slice slValue = pcursor->value();
                CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
                CCoins coins;
                ssValue >> coins;
                uint256 txhash;
                ssKey >> txhash;
                ss << txhash;
                ss << VARINT(coins.nVersion);
                ss << (coins.fCoinBase ? 'c' : 'n');
                ss << VARINT(coins.nHeight);
                stats.nTransactions++;
                for (unsigned int i=0; i<coins.vout.size(); i++) {
                    const CTxOut &out = coins.vout[i];
                    if (!out.IsNull()) {
                        stats.nTransactionOutputs++;
                        ss << VARINT(i+1);
                        ss << out;
                        nTotalAmount += out.nValue;
                    }
                }
                stats.nSerializedSize += 32 + slValue.size();
                ss << VARINT(0);
            }
            pcursor->Next();
        } catch (std::exception &e) {
            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
        }
    }
    delete pcursor;
    stats.nHeight = GetBestBlock()->nHeight;
    stats.hashSerialized = ss.GetHash();
    stats.nTotalAmount = nTotalAmount;
    return true;
}

bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
    return Read(make_pair('t', txid), pos);
}

bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
    CLevelDBBatch batch;
    for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
        batch.Write(make_pair('t', it->first), it->second);
    return WriteBatch(batch);
}

bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
    return Write(std::make_pair('F', name), fValue ? '1' : '0');
}

bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
    char ch;
    if (!Read(std::make_pair('F', name), ch))
        return false;
    fValue = ch == '1';
    return true;
}

bool CBlockTreeDB::LoadBlockIndexGuts()
{
    boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator());

    CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
    ssKeySet << boost::tuples::make_tuple('b', uint256(0), 'a'); // 'b' is the prefix for BlockIndex, 'a' sigifies the first part
    uint256 hash;
    char cType;
    pcursor->Seek(ssKeySet.str());

    // Load mapBlockIndex
    while (pcursor->Valid()) {
        boost::this_thread::interruption_point();
        try {
            leveldb::Slice slKey = pcursor->key();
            CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
            ssKey >> cType;
            if (cType == 'b') {
                if (slKey.size() < ssKeySet.size()) {
                    return error("Database key size is %d expected %d, require reindex to upgrade.", slKey.size(), ssKeySet.size());
                }
                ssKey >> hash;

                leveldb::Slice slValue = pcursor->value();
                CDataStream ssValue_immutable(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
                CDiskBlockIndex diskindex;
                ssValue_immutable >> diskindex; // read all immutable data

                // Construct immutable parts of block index object
                CBlockIndex* pindexNew = InsertBlockIndex(hash);
                assert(diskindex.CalcBlockHash() == *pindexNew->phashBlock); // paranoia check

                pindexNew->pprev          = InsertBlockIndex(diskindex.hashPrev);
                pindexNew->nHeight        = diskindex.nHeight;
                pindexNew->nVersion       = diskindex.nVersion;
                pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
                pindexNew->nTime          = diskindex.nTime;
                pindexNew->nBits          = diskindex.nBits;
                pindexNew->nNonce         = diskindex.nNonce;
                pindexNew->nTx            = diskindex.nTx;
				CTransaction::hashData = true;
				if(pindexNew->nHeight >= GetAuxPowStartBlock())
				{
					CTransaction::hashData = false;
				}
                // Watch for genesis block
                if (pindexGenesisBlock == NULL && pindexNew->GetBlockHash() == hashGenesisBlock)
                    pindexGenesisBlock = pindexNew;

                // CheckIndex needs phashBlock to be set
                diskindex.phashBlock = pindexNew->phashBlock;
                if (!diskindex.CheckIndex())
                    return error("LoadBlockIndex() : CheckIndex failed: %s", pindexNew->ToString().c_str());

                pcursor->Next(); // now we should be on the 'b' subkey

                assert(pcursor->Valid());

                slValue = pcursor->value();
                CDataStream ssValue_mutable(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
                ssValue_mutable >> *pindexNew;      // read all mutable data

                pcursor->Next();
            } else {
                break; // if shutdown requested or finished loading block index
            }
        } catch (std::exception &e) {
            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
        }
    }

    return true;
}
<commit_msg>typo caught during compile<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "txdb.h"
#include "main.h"
#include "auxpow.h"
#include "hash.h"

using namespace std;

void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) {
    if (coins.IsPruned())
        batch.Erase(make_pair('c', hash));
    else
        batch.Write(make_pair('c', hash), coins);
}

void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
    batch.Write('B', hash);
}

CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
}

bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) {
    return db.Read(make_pair('c', txid), coins);
}

bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) {
    CLevelDBBatch batch;
    BatchWriteCoins(batch, txid, coins);
    return db.WriteBatch(batch);
}

bool CCoinsViewDB::HaveCoins(const uint256 &txid) {
    return db.Exists(make_pair('c', txid));
}

CBlockIndex *CCoinsViewDB::GetBestBlock() {
    uint256 hashBestChain;
    if (!db.Read('B', hashBestChain))
        return NULL;
    std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(hashBestChain);
    if (it == mapBlockIndex.end())
        return NULL;
    return it->second;
}

bool CCoinsViewDB::SetBestBlock(CBlockIndex *pindex) {
    CLevelDBBatch batch;
    BatchWriteHashBestChain(batch, pindex->GetBlockHash());
    return db.WriteBatch(batch);
}

bool CCoinsViewDB::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) {
    printf("Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());

    CLevelDBBatch batch;
    for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
        BatchWriteCoins(batch, it->first, it->second);
    if (pindex)
        BatchWriteHashBestChain(batch, pindex->GetBlockHash());

    return db.WriteBatch(batch);
}

CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDB(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
}

bool CBlockTreeDB::WriteDiskBlockIndex(const CDiskBlockIndex& diskblockindex)
{
    return Write(boost::tuples::make_tuple('b', *diskblockindex.phashBlock, 'a'), diskblockindex);
}

bool CBlockTreeDB::WriteBlockIndex(const CBlockIndex& blockindex)
{
    return Write(boost::tuples::make_tuple('b', blockindex.GetBlockHash(), 'b'), blockindex);
}

bool CBlockTreeDB::ReadDiskBlockIndex(const uint256 &blkid, CDiskBlockIndex &diskblockindex) {
    return Read(boost::tuples::make_tuple('b', blkid, 'a'), diskblockindex);
}

bool CBlockTreeDB::ReadBestInvalidWork(CBigNum& bnBestInvalidWork)
{
    return Read('I', bnBestInvalidWork);
}

bool CBlockTreeDB::WriteBestInvalidWork(const CBigNum& bnBestInvalidWork)
{
    return Write('I', bnBestInvalidWork);
}

bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) {
    return Write(make_pair('f', nFile), info);
}

bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
    return Read(make_pair('f', nFile), info);
}

bool CBlockTreeDB::WriteLastBlockFile(int nFile) {
    return Write('l', nFile);
}

bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
    if (fReindexing)
        return Write('R', '1');
    else
        return Erase('R');
}

bool CBlockTreeDB::ReadReindexing(bool &fReindexing) {
    fReindexing = Exists('R');
    return true;
}

bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
    return Read('l', nFile);
}

bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
    boost::scoped_ptr<leveldb::Iterator> pcursor(db.NewIterator());
    pcursor->SeekToFirst();

    CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
    stats.hashBlock = GetBestBlock()->GetBlockHash();
    ss << stats.hashBlock;
    int64 nTotalAmount = 0;
    while (pcursor->Valid()) {
        boost::this_thread::interruption_point();
        try {
            leveldb::Slice slKey = pcursor->key();
            CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
            char chType;
            ssKey >> chType;
            if (chType == 'c') {
                leveldb::Slice slValue = pcursor->value();
                CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
                CCoins coins;
                ssValue >> coins;
                uint256 txhash;
                ssKey >> txhash;
                ss << txhash;
                ss << VARINT(coins.nVersion);
                ss << (coins.fCoinBase ? 'c' : 'n');
                ss << VARINT(coins.nHeight);
                stats.nTransactions++;
                for (unsigned int i=0; i<coins.vout.size(); i++) {
                    const CTxOut &out = coins.vout[i];
                    if (!out.IsNull()) {
                        stats.nTransactionOutputs++;
                        ss << VARINT(i+1);
                        ss << out;
                        nTotalAmount += out.nValue;
                    }
                }
                stats.nSerializedSize += 32 + slValue.size();
                ss << VARINT(0);
            }
            pcursor->Next();
        } catch (std::exception &e) {
            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
        }

    stats.nHeight = GetBestBlock()->nHeight;
    stats.hashSerialized = ss.GetHash();
    stats.nTotalAmount = nTotalAmount;
    return true;
}

bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
    return Read(make_pair('t', txid), pos);
}

bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
    CLevelDBBatch batch;
    for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
        batch.Write(make_pair('t', it->first), it->second);
    return WriteBatch(batch);
}

bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
    return Write(std::make_pair('F', name), fValue ? '1' : '0');
}

bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
    char ch;
    if (!Read(std::make_pair('F', name), ch))
        return false;
    fValue = ch == '1';
    return true;
}

bool CBlockTreeDB::LoadBlockIndexGuts()
{
    boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator());

    CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
    ssKeySet << boost::tuples::make_tuple('b', uint256(0), 'a'); // 'b' is the prefix for BlockIndex, 'a' sigifies the first part
    uint256 hash;
    char cType;
    pcursor->Seek(ssKeySet.str());

    // Load mapBlockIndex
    while (pcursor->Valid()) {
        boost::this_thread::interruption_point();
        try {
            leveldb::Slice slKey = pcursor->key();
            CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
            ssKey >> cType;
            if (cType == 'b') {
                if (slKey.size() < ssKeySet.size()) {
                    return error("Database key size is %d expected %d, require reindex to upgrade.", slKey.size(), ssKeySet.size());
                }
                ssKey >> hash;

                leveldb::Slice slValue = pcursor->value();
                CDataStream ssValue_immutable(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
                CDiskBlockIndex diskindex;
                ssValue_immutable >> diskindex; // read all immutable data

                // Construct immutable parts of block index object
                CBlockIndex* pindexNew = InsertBlockIndex(hash);
                assert(diskindex.CalcBlockHash() == *pindexNew->phashBlock); // paranoia check

                pindexNew->pprev          = InsertBlockIndex(diskindex.hashPrev);
                pindexNew->nHeight        = diskindex.nHeight;
                pindexNew->nVersion       = diskindex.nVersion;
                pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
                pindexNew->nTime          = diskindex.nTime;
                pindexNew->nBits          = diskindex.nBits;
                pindexNew->nNonce         = diskindex.nNonce;
                pindexNew->nTx            = diskindex.nTx;
				CTransaction::hashData = true;
				if(pindexNew->nHeight >= GetAuxPowStartBlock())
				{
					CTransaction::hashData = false;
				}
                // Watch for genesis block
                if (pindexGenesisBlock == NULL && pindexNew->GetBlockHash() == hashGenesisBlock)
                    pindexGenesisBlock = pindexNew;

                // CheckIndex needs phashBlock to be set
                diskindex.phashBlock = pindexNew->phashBlock;
                if (!diskindex.CheckIndex())
                    return error("LoadBlockIndex() : CheckIndex failed: %s", pindexNew->ToString().c_str());

                pcursor->Next(); // now we should be on the 'b' subkey

                assert(pcursor->Valid());

                slValue = pcursor->value();
                CDataStream ssValue_mutable(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
                ssValue_mutable >> *pindexNew;      // read all mutable data

                pcursor->Next();
            } else {
                break; // if shutdown requested or finished loading block index
            }
        } catch (std::exception &e) {
            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
        }
    }

    return true;
}
<|endoftext|>


<commit_before>#include <fstream>
#include <regex>
#include <string>
#include <sstream>

#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/variant/get.hpp>

#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/IR/IRBuilder.h>
#include "llvm/IR/LLVMContext.h"
#include <llvm/IR/Module.h>
#include <llvm/Support/raw_ostream.h>

#include "parser.h"
#include "codegen.h"

using namespace marklar;
using namespace parser;

using namespace llvm;
using namespace std;
namespace po = boost::program_options;

bool generateOutput(const string& inputFilename, const string& outputBitCodeName) {
	ifstream in(inputFilename.c_str());

	const string fileContents(static_cast<stringstream const&>(stringstream() << in.rdbuf()).str());

	// Parse the source file
	cout << "Parsing..." << endl;
	base_expr_node rootAst;
	if (!parse(fileContents, rootAst)) {
		cerr << "Failed to parse source file!" << endl;
		return false;
	}

	// Generate the code
	cout << "Generating code..." << endl;
	LLVMContext &context = getGlobalContext();
	unique_ptr<Module> module(new Module("", context));
	IRBuilder<> builder(getGlobalContext());

	ast_codegen codeGenerator(module.get(), builder);

	// Generate code for each expression at the root level
	const base_expr* expr = boost::get<base_expr>(&rootAst);
	for (auto& itr : expr->children) {
		boost::apply_visitor(codeGenerator, itr);
	}

	// Perform an LLVM verify as a sanity check
	string errorInfo;
	raw_string_ostream errorOut(errorInfo);

	if (verifyModule(*module, &errorOut)) {
		cerr << "Failed to generate LLVM IR: " << errorInfo << endl;

		module->print(errorOut, nullptr);
		cerr << "Module:" << endl << errorInfo << endl;
		return false;
	}

	// Dump the LLVM IR to a file
	llvm::raw_fd_ostream outStream(outputBitCodeName.c_str(), errorInfo, llvm::sys::fs::F_Binary);
	llvm::WriteBitcodeToFile(module.get(), outStream);

	return true;
}

bool optimizeAndLink(const string& bitCodeFilename, const string& exeName = "") {
	// Optimize the generated bitcode with LLVM 'opt'
	{
		cout << "Optimizing..." << endl;
	}

	// Transform the bitcode into an object file with LLVM 'llc'
	{
		cout << "Linking..." << endl;

		const string tmpObjName = "output.o";
		const string llcCmd = "llc-3.5 -filetype=obj output.bc -o " + tmpObjName;

		const int retval = system(llcCmd.c_str());
		if (retval != 0) {
			cerr << "Error running 'llc'" << endl;
			return false;
		}
	}

	// Leverage gcc here to link the object file into the final executable
	// this is mainly to bypass the more complicated options that the system 'ld' needs
	{
		const string outputExeName = (exeName.empty() ? "a.out" : exeName);
		const string gccCmd = "gcc -o " + outputExeName + " output.o";

		const int retval = system(gccCmd.c_str());
		if (retval != 0) {
			cerr << "Error running 'gcc': \"" << gccCmd << "\"" << " -- returned: " << retval << endl;
			return false;
		}
	}

	return true;
}

int main(int argc, char** argv) {
	// Build the supported options
	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "produce help message")
		("input-file,i", po::value<string>(), "input file")
		("output-file,o", po::value<string>(), "output file")
	;

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	if (vm.count("help") > 0) {
		cout << desc << endl;
		return 1;
	}

	if (vm.count("input-file") > 0) {
		const string inputFilename = vm["input-file"].as<string>();
		const string tmpBitCodeFile = "output.bc";
		string outputFilename = "a.out";

		if (vm.count("output-file") > 0) {
			outputFilename = vm["output-file"].as<string>();
		}

		if (!generateOutput(inputFilename, tmpBitCodeFile)) {
			return 2;
		}

		if (!optimizeAndLink(tmpBitCodeFile, outputFilename)) {
			return 3;
		}
	}

	cout << "Executable complete!" << endl;

	return 0;
}

<commit_msg>Added llvm bitcode optimizations to the main driver<commit_after>#include <fstream>
#include <regex>
#include <string>
#include <sstream>

#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/variant/get.hpp>

#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/IR/IRBuilder.h>
#include "llvm/IR/LLVMContext.h"
#include <llvm/IR/Module.h>
#include <llvm/Support/raw_ostream.h>

#include "parser.h"
#include "codegen.h"

using namespace marklar;
using namespace parser;

using namespace llvm;
using namespace std;
namespace po = boost::program_options;

bool generateOutput(const string& inputFilename, const string& outputBitCodeName) {
	ifstream in(inputFilename.c_str());

	const string fileContents(static_cast<stringstream const&>(stringstream() << in.rdbuf()).str());

	// Parse the source file
	cout << "Parsing..." << endl;
	base_expr_node rootAst;
	if (!parse(fileContents, rootAst)) {
		cerr << "Failed to parse source file!" << endl;
		return false;
	}

	// Generate the code
	cout << "Generating code..." << endl;
	LLVMContext &context = getGlobalContext();
	unique_ptr<Module> module(new Module("", context));
	IRBuilder<> builder(getGlobalContext());

	ast_codegen codeGenerator(module.get(), builder);

	// Generate code for each expression at the root level
	const base_expr* expr = boost::get<base_expr>(&rootAst);
	for (auto& itr : expr->children) {
		boost::apply_visitor(codeGenerator, itr);
	}

	// Perform an LLVM verify as a sanity check
	string errorInfo;
	raw_string_ostream errorOut(errorInfo);

	if (verifyModule(*module, &errorOut)) {
		cerr << "Failed to generate LLVM IR: " << errorInfo << endl;

		module->print(errorOut, nullptr);
		cerr << "Module:" << endl << errorInfo << endl;
		return false;
	}

	// Dump the LLVM IR to a file
	llvm::raw_fd_ostream outStream(outputBitCodeName.c_str(), errorInfo, llvm::sys::fs::F_Binary);
	llvm::WriteBitcodeToFile(module.get(), outStream);

	return true;
}

bool optimizeAndLink(const string& bitCodeFilename, const string& exeName = "") {
	const string tmpOptBCName = "output_opt.bc";
	const string tmpObjName = "output.o";

	// Optimize the generated bitcode with LLVM 'opt', produces an optimized bitcode file
	{
		cout << "Optimizing..." << endl;

		const string optCmd = "opt-3.5 -filetype=obj -o " + tmpOptBCName + " output.bc";

		const int retval = system(optCmd.c_str());
		if (retval != 0) {
			cerr << "Error running 'opt': \"" << optCmd << "\"" << endl;
			return false;
		}
	}

	// Transform the bitcode into an object file with LLVM 'llc'
	{
		cout << "Linking..." << endl;

		const string llcCmd = "llc-3.5 -filetype=obj -o " + tmpObjName + " " + tmpOptBCName;

		const int retval = system(llcCmd.c_str());
		if (retval != 0) {
			cerr << "Error running 'llc': \"" << llcCmd << "\"" << endl;
			return false;
		}
	}

	// Leverage gcc here to link the object file into the final executable
	// this is mainly to bypass the more complicated options that the system 'ld' needs
	{
		const string outputExeName = (exeName.empty() ? "a.out" : exeName);
		const string gccCmd = "gcc -o " + outputExeName + " " + tmpObjName;

		const int retval = system(gccCmd.c_str());
		if (retval != 0) {
			cerr << "Error running 'gcc': \"" << gccCmd << "\"" << " -- returned: " << retval << endl;
			return false;
		}
	}

	return true;
}

int main(int argc, char** argv) {
	// Build the supported options
	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "produce help message")
		("input-file,i", po::value<string>(), "input file")
		("output-file,o", po::value<string>(), "output file")
	;

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	if (vm.count("help") > 0) {
		cout << desc << endl;
		return 1;
	}

	if (vm.count("input-file") > 0) {
		const string inputFilename = vm["input-file"].as<string>();
		const string tmpBitCodeFile = "output.bc";
		string outputFilename = "a.out";

		if (vm.count("output-file") > 0) {
			outputFilename = vm["output-file"].as<string>();
		}

		if (!generateOutput(inputFilename, tmpBitCodeFile)) {
			return 2;
		}

		if (!optimizeAndLink(tmpBitCodeFile, outputFilename)) {
			return 3;
		}
	}

	cout << "Executable complete!" << endl;

	return 0;
}

<|endoftext|>


<commit_before>#include "shell-readline.hpp"
#include "shell_bison.hh"
#include "command.hpp"

extern FILE * yyin;
extern FILE * yyout;

extern int yylex();
extern int yyparse();

extern void yyrestart (FILE * in);
extern void yyerror(const char * s);
extern read_line reader;

int main()
{
	bool is_interactive = false;
	Command::currentCommand.set_interactive((is_interactive = isatty(0)));

	std::string expanded_home = tilde_expand("~/.yashrc");

	char * rcfile = strndup(expanded_home.c_str(), expanded_home.size());

	yyin = fopen(rcfile, "r"); free(rcfile);

	/* From Brian P. Hays */
	if (yyin != NULL) {
		Command::currentCommand.printPrompt = false;
		yyparse();
		fclose(yyin);

		yyin = stdin;
		yyrestart(yyin);
		Command::currentCommand.printPrompt = true;
	}

	if (is_interactive) {
		/* loop until we are in the foreground */
		for (; tcgetpgrp(STDIN_FILENO) != (Command::currentCommand.m_pgid = getpgrp());) {
			kill(- Command::currentCommand.m_pgid, SIGTTIN);
		}

		/* Ignore interactive and job-control signals */
		signal(SIGINT,  SIG_IGN);
		signal(SIGQUIT, SIG_IGN);
		signal(SIGTSTP, SIG_IGN);
		signal(SIGTTIN, SIG_IGN);
		signal(SIGTTOU, SIG_IGN);
		signal(SIGCHLD, SIG_IGN);

		/* go to our process group */
		pid_t shell_pgid = getpid();
		Command::currentCommand.m_pgid = shell_pgid;
		if (setpgid(shell_pgid, shell_pgid) < 0) {
		   perror("setpgid");
		   std::cerr<<"pgid: "<<shell_pgid<<std::endl;
		   /* exit(1); */
		}
	}

	Command::currentCommand.prompt();
	yyparse();

	return 0;
}
<commit_msg>Uh -- ok. I'm not sure about anything anymore.<commit_after>#include "shell-readline.hpp"
#include "shell_bison.hh"
#include "command.hpp"

extern FILE * yyin;
extern FILE * yyout;

extern int yylex();
extern int yyparse();

extern void yyrestart (FILE * in);
extern void yyerror(const char * s);
extern read_line reader;

int main()
{
	bool is_interactive = false;
	Command::currentCommand.set_interactive((is_interactive = isatty(0)));

	std::string expanded_home = tilde_expand("~/.yashrc");

	char * rcfile = strndup(expanded_home.c_str(), expanded_home.size());

	yyin = fopen(rcfile, "r"); free(rcfile);

	/* From Brian P. Hays */
	if (yyin != NULL) {
		Command::currentCommand.printPrompt = false;
		yyparse();
		fclose(yyin);

		yyin = stdin;
		yyrestart(yyin);
		Command::currentCommand.printPrompt = true;
	}

	if (is_interactive) {
		/* loop until we are in the foreground */
		for (; tcgetpgrp(STDIN_FILENO) != (Command::currentCommand.m_pgid = getpgrp());) {
			kill(- Command::currentCommand.m_pgid, SIGTTIN);
		}

		/* go to our process group */
		pid_t shell_pgid = getpid();
		if ((getpgrp() != getpid()) && (setpgid(shell_pgid, shell_pgid) < 0)) {
		   perror("setpgid");
		   std::cerr<<"pgid: "<<getpgrp()<<std::endl;
		   std::cerr<<"pid: "<<getpid()<<std::endl;
		   /* exit(1); */
		}
		Command::currentCommand.m_pgid = shell_pgid;
		/* Ignore interactive and job-control signals */
		signal(SIGINT,  SIG_IGN);
		signal(SIGQUIT, SIG_IGN);
		signal(SIGTSTP, SIG_IGN);
		signal(SIGTTIN, SIG_IGN);
		signal(SIGTTOU, SIG_IGN);
		signal(SIGCHLD, SIG_IGN);
	}

	Command::currentCommand.prompt();
	yyparse();

	return 0;
}
<|endoftext|>


<commit_before>#include "../ui/mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
#ifdef Q_OS_LINUX
  QCoreApplication::addLibraryPath("/usr/lib/viqo");
#endif

  QApplication a(argc, argv);

  QCoreApplication::setApplicationName("Viqo");
  QCoreApplication::setApplicationVersion("2.0");

  QCommandLineParser parser;
  parser.setApplicationDescription(
        QStringLiteral("Qt で作成されたマルチプラットフォームコメントビューワです"));
  parser.addHelpOption();
  parser.addVersionOption();

  // Process the actual command line arguments given by the user
  parser.process(a);

  MainWindow w;
  w.show();

  return a.exec();
}
<commit_msg>update version info to 2.1<commit_after>#include "../ui/mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
#ifdef Q_OS_LINUX
  QCoreApplication::addLibraryPath("/usr/lib/viqo");
#endif

  QApplication a(argc, argv);

  QCoreApplication::setApplicationName("Viqo");
  QCoreApplication::setApplicationVersion("2.1");

  QCommandLineParser parser;
  parser.setApplicationDescription(
        QStringLiteral("Qt で作成されたマルチプラットフォームコメントビューワです"));
  parser.addHelpOption();
  parser.addVersionOption();

  // Process the actual command line arguments given by the user
  parser.process(a);

  MainWindow w;
  w.show();

  return a.exec();
}
<|endoftext|>


<commit_before>#include <tr1/memory>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <signal.h>
#include <getopt.h>
#include "barrier.h"
#include "stream.h"
#include "socket.h"
#include <unistd.h>

using std::vector;
using std::tr1::shared_ptr;

static bool run = true;

static void terminate(void)
{
	run = false;
}

int main(int argc, char** argv)
{
	unsigned num_conns = 1;
	unsigned remote_port = 0;
	unsigned local_port = 0;
	unsigned interval = 0;
	unsigned length = 0;

	// Parse program arguments and options
	int opt;
	while ((opt = getopt(argc, argv, ":hc:p:q:n:i:")) != -1) {
		char* ptr;
		switch (opt) {

			// Missing a value for the option
			case ':':
				fprintf(stderr, "Option %s requires a value\n", argv[optind-1]);
				return ':';

			// Unknown option was given
			case '?':
				fprintf(stderr, "Ignoring unknown option '%c'\n", optopt);
				break;

			// Print program usage and quit
			case 'h':
				// TODO: Give usage
				return 'h';

			// Set number of connections
			case 'c':
				ptr = NULL;
				if ((num_conns = strtoul(optarg, &ptr, 0)) > 1024 || num_conns < 1 || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -c requires a valid number of connections [1-1024]\n");
					return 'c';
				}
				break;

			// Set the remote starting port
			case 'p':
				ptr = NULL;
				if ((remote_port = strtoul(optarg, &ptr, 0)) > 0xffff || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -p requires a valid port number [0-65535]\n");
					return 'p';
				}
				break;

			// Set the local starting port
			case 'q':
				ptr = NULL;
				if ((local_port = strtoul(optarg, &ptr, 0)) > 0xffff || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -q requires a valid port number [0-65535]\n");
					return 'p';
				}
				break;

			// Set the size of the byte chunk to be sent
			case 'n':
				ptr = NULL;
				if ((length = strtoul(optarg, &ptr, 0)) > BUFFER_SIZE || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -n requires a chunk size in bytes [1-%d] or 0 for off\n", BUFFER_SIZE);
					return 'n';
				}
				break;

			// Set the interval between each time a chunk is sent
			case 'i':
				ptr = NULL;
				if ((interval = strtoul(optarg, &ptr, 0)) > 0xffff || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -i requires an interval in milliseconds [1-65535] or 0 for off\n");
					return 'i';
				}
				break;
		}
	}

	// Check if all mandatory options were set
	if (optind < argc && remote_port == 0) {
		fprintf(stderr, "Option -p is required for client\n");
		return 'p';
	} else if (optind == argc && local_port == 0) {
		fprintf(stderr, "Option -q is required for server\n");
		return 'q';
	}

	// Handle interrupt signal
	signal(SIGINT, (void (*)(int)) &terminate);

	// Create a barrier
	Barrier barrier(num_conns + 1);

	// Start connections
	vector<shared_ptr<Stream> > conns;

	for (unsigned i = 0; i < num_conns; ++i) {
		if (optind < argc) {
			Client* client = new Client(barrier, argv[optind], remote_port);
			if (local_port > 0) {
				client->bind(local_port + i);
			}

			conns.push_back(shared_ptr<Stream>( static_cast<Stream*>(client) ));
		} else {
			conns.push_back(shared_ptr<Stream>( new Server(barrier, local_port + i) ));
		}
	}

	// Synchronize with connections
	barrier.wait();

	// Run until completion
	while (run);

	return 0;
}
<commit_msg>forgot call to start<commit_after>#include <tr1/memory>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <signal.h>
#include <getopt.h>
#include "barrier.h"
#include "stream.h"
#include "socket.h"
#include <unistd.h>

using std::vector;
using std::tr1::shared_ptr;

static bool run = true;

static void terminate(void)
{
	run = false;
}

int main(int argc, char** argv)
{
	unsigned num_conns = 1;
	unsigned remote_port = 0;
	unsigned local_port = 0;
	unsigned interval = 0;
	unsigned length = 0;

	// Parse program arguments and options
	int opt;
	while ((opt = getopt(argc, argv, ":hc:p:q:n:i:")) != -1) {
		char* ptr;
		switch (opt) {

			// Missing a value for the option
			case ':':
				fprintf(stderr, "Option %s requires a value\n", argv[optind-1]);
				return ':';

			// Unknown option was given
			case '?':
				fprintf(stderr, "Ignoring unknown option '%c'\n", optopt);
				break;

			// Print program usage and quit
			case 'h':
				// TODO: Give usage
				return 'h';

			// Set number of connections
			case 'c':
				ptr = NULL;
				if ((num_conns = strtoul(optarg, &ptr, 0)) > 1024 || num_conns < 1 || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -c requires a valid number of connections [1-1024]\n");
					return 'c';
				}
				break;

			// Set the remote starting port
			case 'p':
				ptr = NULL;
				if ((remote_port = strtoul(optarg, &ptr, 0)) > 0xffff || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -p requires a valid port number [0-65535]\n");
					return 'p';
				}
				break;

			// Set the local starting port
			case 'q':
				ptr = NULL;
				if ((local_port = strtoul(optarg, &ptr, 0)) > 0xffff || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -q requires a valid port number [0-65535]\n");
					return 'p';
				}
				break;

			// Set the size of the byte chunk to be sent
			case 'n':
				ptr = NULL;
				if ((length = strtoul(optarg, &ptr, 0)) > BUFFER_SIZE || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -n requires a chunk size in bytes [1-%d] or 0 for off\n", BUFFER_SIZE);
					return 'n';
				}
				break;

			// Set the interval between each time a chunk is sent
			case 'i':
				ptr = NULL;
				if ((interval = strtoul(optarg, &ptr, 0)) > 0xffff || ptr == NULL || *ptr != '\0') {
					fprintf(stderr, "Option -i requires an interval in milliseconds [1-65535] or 0 for off\n");
					return 'i';
				}
				break;
		}
	}

	// Check if all mandatory options were set
	if (optind < argc && remote_port == 0) {
		fprintf(stderr, "Option -p is required for client\n");
		return 'p';
	} else if (optind == argc && local_port == 0) {
		fprintf(stderr, "Option -q is required for server\n");
		return 'q';
	}

	// Handle interrupt signal
	signal(SIGINT, (void (*)(int)) &terminate);

	// Create a barrier
	Barrier barrier(num_conns + 1);

	vector<shared_ptr<Stream> > conns;

	// Start connections
	fprintf(stderr, "Starting %u connections...\n", num_conns);
	for (unsigned i = 0; i < num_conns; ++i) {
		if (optind < argc) {
			Client* client = new Client(barrier, argv[optind], remote_port);
			if (local_port > 0) {
				client->bind(local_port + i);
			}

			client->start();
			conns.push_back(shared_ptr<Stream>( static_cast<Stream*>(client) ));
		} else {
			Server* server = new Server(barrier, local_port + i);
			server->start();
			conns.push_back(shared_ptr<Stream>( static_cast<Stream*>(server) ));
		}
	}

	// Synchronize with connections
	barrier.wait();

	// TODO: Count number of established connections

	// Run until completion
	while (run);

	return 0;
}
<|endoftext|>


<commit_before>#include <time.h>

#include "../include/PSATsolver.hpp"
#include "../include/TestGenerator.hpp"

using namespace std;
using namespace arma;

void test(int N, int k, int n, double step, int begin, int end, string prefix);

int main(int argc, char** argv)
{
    bool v;
    if(argc < 20)
        v = true;
    else
        v = false;

    if (argc < 2)
    {
        std::cout << "I need a input file " << "\n";
        return -1;
    }

    if((string) argv[1] == "--maketest")
    {
        TestGenerator t(atoi(argv[2]));
        t.createAll(atoi(argv[3]),
                    atoi(argv[4]),
                    atoi(argv[5]),
                    atof(argv[6]),
                    atoi(argv[7]),
                    atoi(argv[8]),
                    argv[9]);
        return 1;
    }

    if((string) argv[1] == "--test")
    {
        test(atoi(argv[2]),
             atoi(argv[3]),
             atoi(argv[4]),
             atof(argv[5]),
             atoi(argv[6]),
             atoi(argv[7]),
             argv[8]);
        return 1;
    }

    int** matrix;
    int**& M = matrix;
    vector<double> pi;
    double time;

    PSATsolver::solve(M, pi, &time, argv[1], true);

    return 1;
}

void test(int N,     int k,   int n,         double step,
          int begin, int end, string prefix)
{
    int** matrix;
    int**& M = matrix;
    vector<double> pi;
    ofstream outtime;
    ofstream outsat;
    outtime.open("./data/time.txt");
    outsat.open("./data/sat.txt");
    for(double i = begin; i <= end; i+=step)
    {
        double y = 0;
        double sat = 0;
        for(int j = 0; j < N; j++)
        {
            double time = 0;
            int m = round(n*i);
            string file = prefix;
            file += "_K" + to_string(k)
                 +  "_N" + to_string(n)
                 +  "_M" + to_string(m)
                 +  "_"  + to_string(j)
                 +  ".pcnf";
            cout << file << ": ";

            PSATsolver::solve(M, pi, &time,
                             (char*) file.c_str(), false);

            if (pi[0] == 1)
            {
                sat += 1.0/N;
                cout << "sat, time: ";
            }
            else cout << "unsat, time: ";

            cout << time << "\n";
            y += time/N;
        }
        outtime << i << " " << y << "\n";
        outsat << i << " " << sat << "\n";
        cout <<"media tempo: "<< y << "\n";
        cout <<"media sat: " << sat << "\n";
    }
    outtime.close();
    outsat.close();
}
<commit_msg>A more stable version<commit_after>#include <time.h>

#include "../include/PSATsolver.hpp"
#include "../include/TestGenerator.hpp"

using namespace std;
using namespace arma;

void test(int N, int k, int n, double step, int begin, int end, string prefix);

int main(int argc, char** argv)
{
    bool v;
    if(argc < 20)
        v = true;
    else
        v = false;

    if (argc < 2)
    {
        std::cout << "I need a input file " << "\n";
        return -1;
    }

    if((string) argv[1] == "--maketest")
    {
        TestGenerator t(atoi(argv[2]));
        t.createAll(atoi(argv[3]),
                    atoi(argv[4]),
                    atoi(argv[5]),
                    atof(argv[6]),
                    atoi(argv[7]),
                    atoi(argv[8]),
                    argv[9]);
        return 1;
    }

    if((string) argv[1] == "--test")
    {
        test(atoi(argv[2]),
             atoi(argv[3]),
             atoi(argv[4]),
             atof(argv[5]),
             atoi(argv[6]),
             atoi(argv[7]),
             argv[8]);
        return 1;
    }

    int** matrix;
    int**& M = matrix;
    vector<double> pi;
    double time;

    PSATsolver::solve(M, pi, &time, argv[1], true);

    return 1;
}

void test(int N,     int k,   int n,         double step,
          int begin, int end, string prefix)
{
    int** matrix;
    int**& M = matrix;
    vector<double> pi;
    ofstream outtime;
    ofstream outsat;
    for(double i = begin; i <= end; i+=step)
    {
        outtime.open("./data/time" + to_string((int) (i*10)) + ".txt");
        outsat.open("./data/sat" + to_string((int) (i*10)) + ".txt");
        double y = 0;
        double sat = 0;
        for(int j = 0; j < N; j++)
        {
            double time = 0;
            int m = round(n*i);
            string file = prefix;
            file += "_K" + to_string(k)
                 +  "_N" + to_string(n)
                 +  "_M" + to_string(m)
                 +  "_"  + to_string(j)
                 +  ".pcnf";
            cout << file << ": ";

            PSATsolver::solve(M, pi, &time,
                             (char*) file.c_str(), false);

            if (pi[0] == 1)
            {
                sat += 1.0/N;
                cout << "sat, time: ";
            }
            else cout << "unsat, time: ";

            cout << time << "\n";
            y += time/N;
        }
        outtime << i << " " << y << "\n";
        outsat << i << " " << sat << "\n";
        cout <<
        cout <<"media tempo: "<< y << "\n";
        cout <<"media sat: " << sat << "\n";
        outtime.close();
        outsat.close();
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2004-2014 ZNC, see the NOTICE file for details.
 *
 * 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.
 */

#include <znc/znc.h>
#include <signal.h>

using std::cout;
using std::endl;
using std::set;

#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
#else
#define no_argument 0
#define required_argument 1
#define optional_argument 2

struct option {
	const char *a;
	int opt;
	int *flag;
	int val;
};

static inline int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *, int *)
{
	return getopt(argc, argv, optstring);
}
#endif

static const struct option g_LongOpts[] = {
	{ "help",        no_argument,       0, 'h' },
	{ "version",     no_argument,       0, 'v' },
	{ "debug",       no_argument,       0, 'D' },
	{ "foreground",  no_argument,       0, 'f' },
	{ "no-color",    no_argument,       0, 'n' },
	{ "allow-root",  no_argument,       0, 'r' },
	{ "makeconf",    no_argument,       0, 'c' },
	{ "makepass",    no_argument,       0, 's' },
	{ "makepem",     no_argument,       0, 'p' },
	{ "datadir",     required_argument, 0, 'd' },
	{ 0, 0, 0, 0 }
};

static void GenerateHelp(const char *appname) {
	CUtils::PrintMessage("USAGE: " + CString(appname) + " [options]");
	CUtils::PrintMessage("Options are:");
	CUtils::PrintMessage("\t-h, --help         List available command line options (this page)");
	CUtils::PrintMessage("\t-v, --version      Output version information and exit");
	CUtils::PrintMessage("\t-f, --foreground   Don't fork into the background");
	CUtils::PrintMessage("\t-D, --debug        Output debugging information (Implies -f)");
	CUtils::PrintMessage("\t-n, --no-color     Don't use escape sequences in the output");
	CUtils::PrintMessage("\t-r, --allow-root   Don't complain if ZNC is run as root");
	CUtils::PrintMessage("\t-c, --makeconf     Interactively create a new config");
	CUtils::PrintMessage("\t-s, --makepass     Generates a password for use in config");
#ifdef HAVE_LIBSSL
	CUtils::PrintMessage("\t-p, --makepem      Generates a pemfile for use with SSL");
#endif /* HAVE_LIBSSL */
	CUtils::PrintMessage("\t-d, --datadir      Set a different ZNC repository (default is ~/.znc)");
}

static void die(int sig) {
	signal(SIGPIPE, SIG_DFL);

	CUtils::PrintMessage("Exiting on SIG [" + CString(sig) + "]");

	CZNC::DestroyInstance();
	exit(sig);
}

static void signalHandler(int sig) {
	switch (sig) {
	case SIGHUP:
		CUtils::PrintMessage("Caught SIGHUP");
		CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_REHASH);
		break;
	case SIGUSR1:
		CUtils::PrintMessage("Caught SIGUSR1");
		CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE);
		break;
	default:
		CUtils::PrintMessage("WTF? Signal handler called for a signal it doesn't know?");
	}
}

static bool isRoot() {
	// User root? If one of these were root, we could switch the others to root, too
	return (geteuid() == 0 || getuid() == 0);
}

static void seedPRNG() {
	struct timeval tv;
	unsigned int seed;

	// Try to find a seed which can't be as easily guessed as only time()

	if (gettimeofday(&tv, NULL) == 0) {
		seed = (unsigned int)tv.tv_sec;

		// This is in [0:1e6], which means that roughly 20 bits are
		// actually used, let's try to shuffle the high bits.
		seed ^= uint32_t((tv.tv_usec << 10) | tv.tv_usec);
	} else
		seed = (unsigned int)time(NULL);

	seed ^= rand();
	seed ^= getpid();

	srand(seed);
}

int main(int argc, char** argv) {
	CString sConfig;
	CString sDataDir = "";

	seedPRNG();
	CDebug::SetStdoutIsTTY(isatty(1));

	int iArg, iOptIndex = -1;
	bool bMakeConf = false;
	bool bMakePass = false;
	bool bAllowRoot = false;
	bool bForeground = false;
#ifdef ALWAYS_RUN_IN_FOREGROUND
	bForeground = true;
#endif
#ifdef HAVE_LIBSSL
	bool bMakePem = false;
#endif

	while ((iArg = getopt_long(argc, argv, "hvnrcspd:Df", g_LongOpts, &iOptIndex)) != -1) {
		switch (iArg) {
		case 'h':
			GenerateHelp(argv[0]);
			return 0;
		case 'v':
			cout << CZNC::GetTag() << endl;
			cout << CZNC::GetCompileOptionsString() << endl;
			return 0;
		case 'n':
			CDebug::SetStdoutIsTTY(false);
			break;
		case 'r':
			bAllowRoot = true;
			break;
		case 'c':
			bMakeConf = true;
			break;
		case 's':
			bMakePass = true;
			break;
		case 'p':
#ifdef HAVE_LIBSSL
			bMakePem = true;
			break;
#else
			CUtils::PrintError("ZNC is compiled without SSL support.");
			return 1;
#endif /* HAVE_LIBSSL */
		case 'd':
			sDataDir = CString(optarg);
			break;
		case 'f':
			bForeground = true;
			break;
		case 'D':
			bForeground = true;
			CDebug::SetDebug(true);
			break;
		case '?':
		default:
			GenerateHelp(argv[0]);
			return 1;
		}
	}

	if (optind < argc) {
		CUtils::PrintError("Specifying a config file as an argument isn't supported anymore.");
		CUtils::PrintError("Use --datadir instead.");
		return 1;
	}

	CZNC::CreateInstance();

	CZNC* pZNC = &CZNC::Get();
	pZNC->InitDirs(((argc) ? argv[0] : ""), sDataDir);

#ifdef HAVE_LIBSSL
	if (bMakePem) {
		pZNC->WritePemFile();

		CZNC::DestroyInstance();
		return 0;
	}
#endif /* HAVE_LIBSSL */

	if (bMakePass) {
		CString sSalt;
		CUtils::PrintMessage("Type your new password.");
		CString sHash = CUtils::GetSaltedHashPass(sSalt);
		CUtils::PrintMessage("Kill ZNC process, if it's running.");
		CUtils::PrintMessage("Then replace password in the <User> section of your config with this:");
		// Not PrintMessage(), to remove [**] from the beginning, to ease copypasting
		std::cout << "<Pass password>" << std::endl;
		std::cout << "\tMethod = " << CUtils::sDefaultHash << std::endl;
		std::cout << "\tHash = " << sHash << std::endl;
		std::cout << "\tSalt = " << sSalt << std::endl;
		std::cout << "</Pass>" << std::endl;
		CUtils::PrintMessage("After that start ZNC again, and you should be able to login with the new password.");

		CZNC::DestroyInstance();
		return 0;
	}

	{
		set<CModInfo> ssGlobalMods;
		set<CModInfo> ssUserMods;
		set<CModInfo> ssNetworkMods;
		CUtils::PrintAction("Checking for list of available modules");
		pZNC->GetModules().GetAvailableMods(ssGlobalMods, CModInfo::GlobalModule);
		pZNC->GetModules().GetAvailableMods(ssUserMods, CModInfo::UserModule);
		pZNC->GetModules().GetAvailableMods(ssNetworkMods, CModInfo::NetworkModule);
		if (ssGlobalMods.empty() && ssUserMods.empty() && ssNetworkMods.empty()) {
			CUtils::PrintStatus(false, "");
			CUtils::PrintError("No modules found. Perhaps you didn't install ZNC properly?");
			CUtils::PrintError("Read http://wiki.znc.in/Installation for instructions.");
			if (!CUtils::GetBoolInput("Do you really want to run ZNC without any modules?", false)) {
				CZNC::DestroyInstance();
				return 1;
			}
		}
		CUtils::PrintStatus(true, "");
	}

	if (isRoot()) {
		CUtils::PrintError("You are running ZNC as root! Don't do that! There are not many valid");
		CUtils::PrintError("reasons for this and it can, in theory, cause great damage!");
		if (!bAllowRoot) {
			CZNC::DestroyInstance();
			return 1;
		}
		CUtils::PrintError("You have been warned.");
		CUtils::PrintError("Hit CTRL+C now if you don't want to run ZNC as root.");
		CUtils::PrintError("ZNC will start in 30 seconds.");
		sleep(30);
	}

	if (bMakeConf) {
		if (!pZNC->WriteNewConfig(sConfig)) {
			CZNC::DestroyInstance();
			return 0;
		}
		/* Fall through to normal bootup */
	}

	CString sConfigError;
	if (!pZNC->ParseConfig(sConfig, sConfigError)) {
		CUtils::PrintError("Unrecoverable config error.");
		CZNC::DestroyInstance();
		return 1;
	}

	if (!pZNC->OnBoot()) {
		CUtils::PrintError("Exiting due to module boot errors.");
		CZNC::DestroyInstance();
		return 1;
	}

	if (bForeground) {
		int iPid = getpid();
		CUtils::PrintMessage("Staying open for debugging [pid: " + CString(iPid) + "]");

		pZNC->WritePidFile(iPid);
		CUtils::PrintMessage(CZNC::GetTag());
	} else {
		CUtils::PrintAction("Forking into the background");

		int iPid = fork();

		if (iPid == -1) {
			CUtils::PrintStatus(false, strerror(errno));
			CZNC::DestroyInstance();
			return 1;
		}

		if (iPid > 0) {
			// We are the parent. We are done and will go to bed.
			CUtils::PrintStatus(true, "[pid: " + CString(iPid) + "]");

			pZNC->WritePidFile(iPid);
			CUtils::PrintMessage(CZNC::GetTag());
			/* Don't destroy pZNC here or it will delete the pid file. */
			return 0;
		}

		/* fcntl() locks don't necessarily propagate to forked()
		 *   children.  Reacquire the lock here.  Use the blocking
		 *   call to avoid race condition with parent exiting.
		 */
		if (!pZNC->WaitForChildLock()) {
			CUtils::PrintError("Child was unable to obtain lock on config file.");
			CZNC::DestroyInstance();
			return 1;
		}

		// Redirect std in/out/err to /dev/null
		close(0); open("/dev/null", O_RDONLY);
		close(1); open("/dev/null", O_WRONLY);
		close(2); open("/dev/null", O_WRONLY);

		CDebug::SetStdoutIsTTY(false);

		// We are the child. There is no way we can be a process group
		// leader, thus setsid() must succeed.
		setsid();
		// Now we are in our own process group and session (no
		// controlling terminal). We are independent!
	}

	struct sigaction sa;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);

	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, (struct sigaction*) NULL);

	sa.sa_handler = signalHandler;
	sigaction(SIGHUP,  &sa, (struct sigaction*) NULL);
	sigaction(SIGUSR1, &sa, (struct sigaction*) NULL);

	// Once this signal is caught, the signal handler is reset
	// to SIG_DFL. This avoids endless loop with signals.
	sa.sa_flags = SA_RESETHAND;
	sa.sa_handler = die;
	sigaction(SIGINT,  &sa, (struct sigaction*) NULL);
	sigaction(SIGQUIT, &sa, (struct sigaction*) NULL);
	sigaction(SIGTERM, &sa, (struct sigaction*) NULL);

	int iRet = 0;

	try {
		pZNC->Loop();
	} catch (const CException& e) {
		switch (e.GetType()) {
			case CException::EX_Shutdown:
				iRet = 0;
				break;
			case CException::EX_Restart: {
				// strdup() because GCC is stupid
				char *args[] = {
					strdup(argv[0]),
					strdup("--datadir"),
					strdup(pZNC->GetZNCPath().c_str()),
					NULL,
					NULL,
					NULL,
					NULL
				};
				int pos = 3;
				if (CDebug::Debug())
					args[pos++] = strdup("--debug");
				else if (bForeground)
					args[pos++] = strdup("--foreground");
				if (!CDebug::StdoutIsTTY())
					args[pos++] = strdup("--no-color");
				if (bAllowRoot)
					args[pos++] = strdup("--allow-root");
				// The above code adds 3 entries to args tops
				// which means the array should be big enough

				CZNC::DestroyInstance();
				execvp(args[0], args);
				CUtils::PrintError("Unable to restart ZNC [" + CString(strerror(errno)) + "]");
			} /* Fall through */
			default:
				iRet = 1;
		}
	}

	CZNC::DestroyInstance();

	return iRet;
}
<commit_msg>Initialize OpenSSL locking functions<commit_after>/*
 * Copyright (C) 2004-2014 ZNC, see the NOTICE file for details.
 *
 * 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.
 */

#include <znc/znc.h>
#include <signal.h>

#if defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD)
#include <znc/Threads.h>
#include <openssl/crypto.h>
#include <memory>

static std::vector<std::unique_ptr<CMutex> > lock_cs;

static void locking_callback(int mode, int type, const char *file, int line) {
	if(mode & CRYPTO_LOCK) {
		lock_cs[type]->lock();
	} else {
		lock_cs[type]->unlock();
	}
}

static unsigned long thread_id_callback() {
	return (unsigned long)pthread_self();
}

static CRYPTO_dynlock_value *dyn_create_callback(const char *file, int line) {
	return (CRYPTO_dynlock_value*)new CMutex;
}

static void dyn_lock_callback(int mode, CRYPTO_dynlock_value *dlock, const char *file, int line) {
	CMutex *mtx = (CMutex*)dlock;

	if(mode & CRYPTO_LOCK) {
		mtx->lock();
	} else {
		mtx->unlock();
	}
}

static void dyn_destroy_callback(CRYPTO_dynlock_value *dlock, const char *file, int line) {
	CMutex *mtx = (CMutex*)dlock;

	delete mtx;
}

static void thread_setup() {
	lock_cs.resize(CRYPTO_num_locks());

	for(std::unique_ptr<CMutex> &mtx: lock_cs)
		mtx = std::unique_ptr<CMutex>(new CMutex());

	CRYPTO_set_id_callback(&thread_id_callback);
	CRYPTO_set_locking_callback(&locking_callback);

	CRYPTO_set_dynlock_create_callback(&dyn_create_callback);
	CRYPTO_set_dynlock_lock_callback(&dyn_lock_callback);
	CRYPTO_set_dynlock_destroy_callback(&dyn_destroy_callback);
}

#else
#define thread_setup()
#endif

using std::cout;
using std::endl;
using std::set;

#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
#else
#define no_argument 0
#define required_argument 1
#define optional_argument 2

struct option {
	const char *a;
	int opt;
	int *flag;
	int val;
};

static inline int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *, int *)
{
	return getopt(argc, argv, optstring);
}
#endif

static const struct option g_LongOpts[] = {
	{ "help",        no_argument,       0, 'h' },
	{ "version",     no_argument,       0, 'v' },
	{ "debug",       no_argument,       0, 'D' },
	{ "foreground",  no_argument,       0, 'f' },
	{ "no-color",    no_argument,       0, 'n' },
	{ "allow-root",  no_argument,       0, 'r' },
	{ "makeconf",    no_argument,       0, 'c' },
	{ "makepass",    no_argument,       0, 's' },
	{ "makepem",     no_argument,       0, 'p' },
	{ "datadir",     required_argument, 0, 'd' },
	{ 0, 0, 0, 0 }
};

static void GenerateHelp(const char *appname) {
	CUtils::PrintMessage("USAGE: " + CString(appname) + " [options]");
	CUtils::PrintMessage("Options are:");
	CUtils::PrintMessage("\t-h, --help         List available command line options (this page)");
	CUtils::PrintMessage("\t-v, --version      Output version information and exit");
	CUtils::PrintMessage("\t-f, --foreground   Don't fork into the background");
	CUtils::PrintMessage("\t-D, --debug        Output debugging information (Implies -f)");
	CUtils::PrintMessage("\t-n, --no-color     Don't use escape sequences in the output");
	CUtils::PrintMessage("\t-r, --allow-root   Don't complain if ZNC is run as root");
	CUtils::PrintMessage("\t-c, --makeconf     Interactively create a new config");
	CUtils::PrintMessage("\t-s, --makepass     Generates a password for use in config");
#ifdef HAVE_LIBSSL
	CUtils::PrintMessage("\t-p, --makepem      Generates a pemfile for use with SSL");
#endif /* HAVE_LIBSSL */
	CUtils::PrintMessage("\t-d, --datadir      Set a different ZNC repository (default is ~/.znc)");
}

static void die(int sig) {
	signal(SIGPIPE, SIG_DFL);

	CUtils::PrintMessage("Exiting on SIG [" + CString(sig) + "]");

	CZNC::DestroyInstance();
	exit(sig);
}

static void signalHandler(int sig) {
	switch (sig) {
	case SIGHUP:
		CUtils::PrintMessage("Caught SIGHUP");
		CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_REHASH);
		break;
	case SIGUSR1:
		CUtils::PrintMessage("Caught SIGUSR1");
		CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE);
		break;
	default:
		CUtils::PrintMessage("WTF? Signal handler called for a signal it doesn't know?");
	}
}

static bool isRoot() {
	// User root? If one of these were root, we could switch the others to root, too
	return (geteuid() == 0 || getuid() == 0);
}

static void seedPRNG() {
	struct timeval tv;
	unsigned int seed;

	// Try to find a seed which can't be as easily guessed as only time()

	if (gettimeofday(&tv, NULL) == 0) {
		seed = (unsigned int)tv.tv_sec;

		// This is in [0:1e6], which means that roughly 20 bits are
		// actually used, let's try to shuffle the high bits.
		seed ^= uint32_t((tv.tv_usec << 10) | tv.tv_usec);
	} else
		seed = (unsigned int)time(NULL);

	seed ^= rand();
	seed ^= getpid();

	srand(seed);
}

int main(int argc, char** argv) {
	CString sConfig;
	CString sDataDir = "";

	thread_setup();

	seedPRNG();
	CDebug::SetStdoutIsTTY(isatty(1));

	int iArg, iOptIndex = -1;
	bool bMakeConf = false;
	bool bMakePass = false;
	bool bAllowRoot = false;
	bool bForeground = false;
#ifdef ALWAYS_RUN_IN_FOREGROUND
	bForeground = true;
#endif
#ifdef HAVE_LIBSSL
	bool bMakePem = false;
#endif

	while ((iArg = getopt_long(argc, argv, "hvnrcspd:Df", g_LongOpts, &iOptIndex)) != -1) {
		switch (iArg) {
		case 'h':
			GenerateHelp(argv[0]);
			return 0;
		case 'v':
			cout << CZNC::GetTag() << endl;
			cout << CZNC::GetCompileOptionsString() << endl;
			return 0;
		case 'n':
			CDebug::SetStdoutIsTTY(false);
			break;
		case 'r':
			bAllowRoot = true;
			break;
		case 'c':
			bMakeConf = true;
			break;
		case 's':
			bMakePass = true;
			break;
		case 'p':
#ifdef HAVE_LIBSSL
			bMakePem = true;
			break;
#else
			CUtils::PrintError("ZNC is compiled without SSL support.");
			return 1;
#endif /* HAVE_LIBSSL */
		case 'd':
			sDataDir = CString(optarg);
			break;
		case 'f':
			bForeground = true;
			break;
		case 'D':
			bForeground = true;
			CDebug::SetDebug(true);
			break;
		case '?':
		default:
			GenerateHelp(argv[0]);
			return 1;
		}
	}

	if (optind < argc) {
		CUtils::PrintError("Specifying a config file as an argument isn't supported anymore.");
		CUtils::PrintError("Use --datadir instead.");
		return 1;
	}

	CZNC::CreateInstance();

	CZNC* pZNC = &CZNC::Get();
	pZNC->InitDirs(((argc) ? argv[0] : ""), sDataDir);

#ifdef HAVE_LIBSSL
	if (bMakePem) {
		pZNC->WritePemFile();

		CZNC::DestroyInstance();
		return 0;
	}
#endif /* HAVE_LIBSSL */

	if (bMakePass) {
		CString sSalt;
		CUtils::PrintMessage("Type your new password.");
		CString sHash = CUtils::GetSaltedHashPass(sSalt);
		CUtils::PrintMessage("Kill ZNC process, if it's running.");
		CUtils::PrintMessage("Then replace password in the <User> section of your config with this:");
		// Not PrintMessage(), to remove [**] from the beginning, to ease copypasting
		std::cout << "<Pass password>" << std::endl;
		std::cout << "\tMethod = " << CUtils::sDefaultHash << std::endl;
		std::cout << "\tHash = " << sHash << std::endl;
		std::cout << "\tSalt = " << sSalt << std::endl;
		std::cout << "</Pass>" << std::endl;
		CUtils::PrintMessage("After that start ZNC again, and you should be able to login with the new password.");

		CZNC::DestroyInstance();
		return 0;
	}

	{
		set<CModInfo> ssGlobalMods;
		set<CModInfo> ssUserMods;
		set<CModInfo> ssNetworkMods;
		CUtils::PrintAction("Checking for list of available modules");
		pZNC->GetModules().GetAvailableMods(ssGlobalMods, CModInfo::GlobalModule);
		pZNC->GetModules().GetAvailableMods(ssUserMods, CModInfo::UserModule);
		pZNC->GetModules().GetAvailableMods(ssNetworkMods, CModInfo::NetworkModule);
		if (ssGlobalMods.empty() && ssUserMods.empty() && ssNetworkMods.empty()) {
			CUtils::PrintStatus(false, "");
			CUtils::PrintError("No modules found. Perhaps you didn't install ZNC properly?");
			CUtils::PrintError("Read http://wiki.znc.in/Installation for instructions.");
			if (!CUtils::GetBoolInput("Do you really want to run ZNC without any modules?", false)) {
				CZNC::DestroyInstance();
				return 1;
			}
		}
		CUtils::PrintStatus(true, "");
	}

	if (isRoot()) {
		CUtils::PrintError("You are running ZNC as root! Don't do that! There are not many valid");
		CUtils::PrintError("reasons for this and it can, in theory, cause great damage!");
		if (!bAllowRoot) {
			CZNC::DestroyInstance();
			return 1;
		}
		CUtils::PrintError("You have been warned.");
		CUtils::PrintError("Hit CTRL+C now if you don't want to run ZNC as root.");
		CUtils::PrintError("ZNC will start in 30 seconds.");
		sleep(30);
	}

	if (bMakeConf) {
		if (!pZNC->WriteNewConfig(sConfig)) {
			CZNC::DestroyInstance();
			return 0;
		}
		/* Fall through to normal bootup */
	}

	CString sConfigError;
	if (!pZNC->ParseConfig(sConfig, sConfigError)) {
		CUtils::PrintError("Unrecoverable config error.");
		CZNC::DestroyInstance();
		return 1;
	}

	if (!pZNC->OnBoot()) {
		CUtils::PrintError("Exiting due to module boot errors.");
		CZNC::DestroyInstance();
		return 1;
	}

	if (bForeground) {
		int iPid = getpid();
		CUtils::PrintMessage("Staying open for debugging [pid: " + CString(iPid) + "]");

		pZNC->WritePidFile(iPid);
		CUtils::PrintMessage(CZNC::GetTag());
	} else {
		CUtils::PrintAction("Forking into the background");

		int iPid = fork();

		if (iPid == -1) {
			CUtils::PrintStatus(false, strerror(errno));
			CZNC::DestroyInstance();
			return 1;
		}

		if (iPid > 0) {
			// We are the parent. We are done and will go to bed.
			CUtils::PrintStatus(true, "[pid: " + CString(iPid) + "]");

			pZNC->WritePidFile(iPid);
			CUtils::PrintMessage(CZNC::GetTag());
			/* Don't destroy pZNC here or it will delete the pid file. */
			return 0;
		}

		/* fcntl() locks don't necessarily propagate to forked()
		 *   children.  Reacquire the lock here.  Use the blocking
		 *   call to avoid race condition with parent exiting.
		 */
		if (!pZNC->WaitForChildLock()) {
			CUtils::PrintError("Child was unable to obtain lock on config file.");
			CZNC::DestroyInstance();
			return 1;
		}

		// Redirect std in/out/err to /dev/null
		close(0); open("/dev/null", O_RDONLY);
		close(1); open("/dev/null", O_WRONLY);
		close(2); open("/dev/null", O_WRONLY);

		CDebug::SetStdoutIsTTY(false);

		// We are the child. There is no way we can be a process group
		// leader, thus setsid() must succeed.
		setsid();
		// Now we are in our own process group and session (no
		// controlling terminal). We are independent!
	}

	struct sigaction sa;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);

	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, (struct sigaction*) NULL);

	sa.sa_handler = signalHandler;
	sigaction(SIGHUP,  &sa, (struct sigaction*) NULL);
	sigaction(SIGUSR1, &sa, (struct sigaction*) NULL);

	// Once this signal is caught, the signal handler is reset
	// to SIG_DFL. This avoids endless loop with signals.
	sa.sa_flags = SA_RESETHAND;
	sa.sa_handler = die;
	sigaction(SIGINT,  &sa, (struct sigaction*) NULL);
	sigaction(SIGQUIT, &sa, (struct sigaction*) NULL);
	sigaction(SIGTERM, &sa, (struct sigaction*) NULL);

	int iRet = 0;

	try {
		pZNC->Loop();
	} catch (const CException& e) {
		switch (e.GetType()) {
			case CException::EX_Shutdown:
				iRet = 0;
				break;
			case CException::EX_Restart: {
				// strdup() because GCC is stupid
				char *args[] = {
					strdup(argv[0]),
					strdup("--datadir"),
					strdup(pZNC->GetZNCPath().c_str()),
					NULL,
					NULL,
					NULL,
					NULL
				};
				int pos = 3;
				if (CDebug::Debug())
					args[pos++] = strdup("--debug");
				else if (bForeground)
					args[pos++] = strdup("--foreground");
				if (!CDebug::StdoutIsTTY())
					args[pos++] = strdup("--no-color");
				if (bAllowRoot)
					args[pos++] = strdup("--allow-root");
				// The above code adds 3 entries to args tops
				// which means the array should be big enough

				CZNC::DestroyInstance();
				execvp(args[0], args);
				CUtils::PrintError("Unable to restart ZNC [" + CString(strerror(errno)) + "]");
			} /* Fall through */
			default:
				iRet = 1;
		}
	}

	CZNC::DestroyInstance();

	return iRet;
}
<|endoftext|>


<commit_before>#ifndef units_hh_INCLUDED
#define units_hh_INCLUDED

#include "hash.hh"

#include <type_traits>

namespace Kakoune
{

template<typename RealType, typename ValueType = int>
class StronglyTypedNumber
{
public:
    [[gnu::always_inline]]
    explicit constexpr StronglyTypedNumber(ValueType value)
        : m_value(value)
    {
        static_assert(std::is_base_of<StronglyTypedNumber, RealType>::value,
                     "RealType is not derived from StronglyTypedNumber");
    }

    [[gnu::always_inline]]
    constexpr RealType operator+(RealType other) const
    { return RealType(m_value + other.m_value); }

    [[gnu::always_inline]]
    constexpr RealType operator-(RealType other) const
    { return RealType(m_value - other.m_value); }

    [[gnu::always_inline]]
    constexpr RealType operator*(RealType other) const
    { return RealType(m_value * other.m_value); }

    [[gnu::always_inline]]
    constexpr RealType operator/(RealType other) const
    { return RealType(m_value / other.m_value); }

    [[gnu::always_inline]]
    RealType& operator+=(RealType other)
    { m_value += other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator-=(RealType other)
    { m_value -= other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator*=(RealType other)
    { m_value *= other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator/=(RealType other)
    { m_value /= other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator++()
    { ++m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator--()
    { --m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType operator++(int)
    { RealType backup(static_cast<RealType&>(*this)); ++m_value; return backup; }

    [[gnu::always_inline]]
    RealType operator--(int)
    { RealType backup(static_cast<RealType&>(*this)); --m_value; return backup; }

    [[gnu::always_inline]]
    constexpr RealType operator-() const { return RealType(-m_value); }

    [[gnu::always_inline]]
    constexpr RealType operator%(RealType other) const
    { return RealType(m_value % other.m_value); }

    [[gnu::always_inline]]
    RealType& operator%=(RealType other)
    { m_value %= other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    constexpr bool operator==(RealType other) const
    { return m_value == other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator!=(RealType other) const
    { return m_value != other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator<(RealType other) const
    { return m_value < other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator<=(RealType other) const
    { return m_value <= other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator>(RealType other) const
    { return m_value > other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator>=(RealType other) const
    { return m_value >= other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator!() const
    { return !m_value; }

    [[gnu::always_inline]]
    explicit constexpr operator ValueType() const { return m_value; }
    [[gnu::always_inline]]
    explicit constexpr operator bool() const { return m_value; }

    friend size_t hash_value(RealType val) { return hash_value(val.m_value); }

private:
    ValueType m_value;
};

struct LineCount : public StronglyTypedNumber<LineCount, int>
{
    [[gnu::always_inline]]
    constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
};

[[gnu::always_inline]]
inline constexpr LineCount operator"" _line(unsigned long long int value)
{
    return LineCount(value);
}

struct ByteCount : public StronglyTypedNumber<ByteCount, int>
{
    [[gnu::always_inline]]
    constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
};

[[gnu::always_inline]]
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
{
    return ByteCount(value);
}

struct CharCount : public StronglyTypedNumber<CharCount, int>
{
    [[gnu::always_inline]]
    constexpr CharCount(int value = 0) : StronglyTypedNumber<CharCount>(value) {}
};

[[gnu::always_inline]]
inline constexpr CharCount operator"" _char(unsigned long long int value)
{
    return CharCount(value);
}

}

#endif // units_hh_INCLUDED
<commit_msg>Add a 'abs' friend function to StronglyTypedNumber<commit_after>#ifndef units_hh_INCLUDED
#define units_hh_INCLUDED

#include "hash.hh"

#include <type_traits>

namespace Kakoune
{

template<typename RealType, typename ValueType = int>
class StronglyTypedNumber
{
public:
    [[gnu::always_inline]]
    explicit constexpr StronglyTypedNumber(ValueType value)
        : m_value(value)
    {
        static_assert(std::is_base_of<StronglyTypedNumber, RealType>::value,
                     "RealType is not derived from StronglyTypedNumber");
    }

    [[gnu::always_inline]]
    constexpr RealType operator+(RealType other) const
    { return RealType(m_value + other.m_value); }

    [[gnu::always_inline]]
    constexpr RealType operator-(RealType other) const
    { return RealType(m_value - other.m_value); }

    [[gnu::always_inline]]
    constexpr RealType operator*(RealType other) const
    { return RealType(m_value * other.m_value); }

    [[gnu::always_inline]]
    constexpr RealType operator/(RealType other) const
    { return RealType(m_value / other.m_value); }

    [[gnu::always_inline]]
    RealType& operator+=(RealType other)
    { m_value += other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator-=(RealType other)
    { m_value -= other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator*=(RealType other)
    { m_value *= other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator/=(RealType other)
    { m_value /= other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator++()
    { ++m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType& operator--()
    { --m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    RealType operator++(int)
    { RealType backup(static_cast<RealType&>(*this)); ++m_value; return backup; }

    [[gnu::always_inline]]
    RealType operator--(int)
    { RealType backup(static_cast<RealType&>(*this)); --m_value; return backup; }

    [[gnu::always_inline]]
    constexpr RealType operator-() const { return RealType(-m_value); }

    [[gnu::always_inline]]
    constexpr RealType operator%(RealType other) const
    { return RealType(m_value % other.m_value); }

    [[gnu::always_inline]]
    RealType& operator%=(RealType other)
    { m_value %= other.m_value; return static_cast<RealType&>(*this); }

    [[gnu::always_inline]]
    constexpr bool operator==(RealType other) const
    { return m_value == other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator!=(RealType other) const
    { return m_value != other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator<(RealType other) const
    { return m_value < other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator<=(RealType other) const
    { return m_value <= other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator>(RealType other) const
    { return m_value > other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator>=(RealType other) const
    { return m_value >= other.m_value; }

    [[gnu::always_inline]]
    constexpr bool operator!() const
    { return !m_value; }

    [[gnu::always_inline]]
    explicit constexpr operator ValueType() const { return m_value; }
    [[gnu::always_inline]]
    explicit constexpr operator bool() const { return m_value; }

    friend size_t hash_value(RealType val) { return hash_value(val.m_value); }
    friend size_t abs(RealType val) { return abs(val.m_value); }

private:
    ValueType m_value;
};

struct LineCount : public StronglyTypedNumber<LineCount, int>
{
    [[gnu::always_inline]]
    constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
};

[[gnu::always_inline]]
inline constexpr LineCount operator"" _line(unsigned long long int value)
{
    return LineCount(value);
}

struct ByteCount : public StronglyTypedNumber<ByteCount, int>
{
    [[gnu::always_inline]]
    constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
};

[[gnu::always_inline]]
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
{
    return ByteCount(value);
}

struct CharCount : public StronglyTypedNumber<CharCount, int>
{
    [[gnu::always_inline]]
    constexpr CharCount(int value = 0) : StronglyTypedNumber<CharCount>(value) {}
};

[[gnu::always_inline]]
inline constexpr CharCount operator"" _char(unsigned long long int value)
{
    return CharCount(value);
}

}

#endif // units_hh_INCLUDED
<|endoftext|>


<commit_before>/*

Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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.

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 "Library/OSRM.h"

#include "Server/ServerFactory.h"

#include "Util/GitDescription.h"
#include "Util/InputFileUtil.h"
#include "Util/ProgramOptions.h"
#include "Util/SimpleLogger.h"
#include "Util/UUID.h"

#ifdef __linux__
#include <sys/mman.h>
#endif

#include <signal.h>

#include <boost/bind.hpp>
// #include <boost/date_time.hpp>
#include <boost/thread.hpp>

#include <iostream>

#ifdef _WIN32
boost::function0<void> console_ctrl_function;

BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
{
  switch (ctrl_type)
  {
  case CTRL_C_EVENT:
  case CTRL_BREAK_EVENT:
  case CTRL_CLOSE_EVENT:
  case CTRL_SHUTDOWN_EVENT:
    console_ctrl_function();
    return TRUE;
  default:
    return FALSE;
  }
}
#endif

int main (int argc, const char * argv[])
{
    try
    {
        LogPolicy::GetInstance().Unmute();

        bool use_shared_memory = false, trial = false;
        std::string ip_address;
        int ip_port, requested_thread_num;

        ServerPaths server_paths;

        const unsigned init_result = GenerateServerProgramOptions(argc, argv, server_paths, ip_address, ip_port, requested_thread_num, use_shared_memory, trial);
        if (init_result == INIT_OK_DO_NOT_START_ENGINE)
        {
            return 0;
        }
        if (init_result == INIT_FAILED)
        {
            return 1;
        }

#ifdef __linux__
        const int lock_flags = MCL_CURRENT | MCL_FUTURE;
        if (-1 == mlockall(lock_flags))
        {
            SimpleLogger().Write(logWARNING) << "Process " << argv[0] << " could not be locked to RAM";
        }
#endif
        SimpleLogger().Write() <<
            "starting up engines, " << g_GIT_DESCRIPTION << ", " <<
            "compiled at " << __DATE__ << ", " __TIME__;

        if(use_shared_memory)
        {
            SimpleLogger().Write(logDEBUG) << "Loading from shared memory";
        }
        else
        {
            SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
            SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"];
            SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"];
            SimpleLogger().Write(logDEBUG) << "Geometry file:\t" << server_paths["geometries"];
            SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"];
            SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"];
            SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"];
            SimpleLogger().Write(logDEBUG) << "Timestamp file:\t" << server_paths["timestamp"];
            SimpleLogger().Write(logDEBUG) << "Threads:\t" << requested_thread_num;
            SimpleLogger().Write(logDEBUG) << "IP address:\t" << ip_address;
            SimpleLogger().Write(logDEBUG) << "IP port:\t" << ip_port;
        }
#ifndef _WIN32
        int sig = 0;
        sigset_t new_mask;
        sigset_t old_mask;
        sigfillset(&new_mask);
        pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
#endif

        OSRM osrm_lib(server_paths, use_shared_memory);
        Server * routing_server = ServerFactory::CreateServer(
                        ip_address,
                        ip_port,
                        requested_thread_num
                     );

        routing_server->GetRequestHandlerPtr().RegisterRoutingMachine(&osrm_lib);

        if( trial )
        {
            SimpleLogger().Write() << "trial run, quitting after successful initialization";
        }
        else
        {
            boost::thread server_thread(boost::bind(&Server::Run, routing_server));

#ifndef _WIN32
            sigset_t wait_mask;
            pthread_sigmask(SIG_SETMASK, &old_mask, 0);
            sigemptyset(&wait_mask);
            sigaddset(&wait_mask, SIGINT);
            sigaddset(&wait_mask, SIGQUIT);
            sigaddset(&wait_mask, SIGTERM);
            pthread_sigmask(SIG_BLOCK, &wait_mask, 0);
            SimpleLogger().Write() << "running and waiting for requests";
            sigwait(&wait_mask, &sig);
#else
            // Set console control handler to allow server to be stopped.
            console_ctrl_function = boost::bind(&Server::Stop, routing_server);
            SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
            SimpleLogger().Write() << "running and waiting for requests";
            routing_server->Run();
#endif
            SimpleLogger().Write() << "initiating shutdown";
            routing_server->Stop();
            SimpleLogger().Write() << "stopping threads";

            if (!server_thread.timed_join(boost::posix_time::seconds(2)))
            {
                SimpleLogger().Write(logDEBUG) << "Threads did not finish within 2 seconds. Hard abort!";
            }
        }

        SimpleLogger().Write() << "freeing objects";
        delete routing_server;
        SimpleLogger().Write() << "shutdown completed";
    }
    catch (const std::exception& e)
    {
        SimpleLogger().Write(logWARNING) << "exception: " << e.what();
        return 1;
    }
#ifdef __linux__
    munlockall();
#endif

    return 0;
}
<commit_msg>make function call more legible<commit_after>/*

Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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.

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 "Library/OSRM.h"

#include "Server/ServerFactory.h"

#include "Util/GitDescription.h"
#include "Util/InputFileUtil.h"
#include "Util/ProgramOptions.h"
#include "Util/SimpleLogger.h"
#include "Util/UUID.h"

#ifdef __linux__
#include <sys/mman.h>
#endif

#include <signal.h>

#include <boost/bind.hpp>
// #include <boost/date_time.hpp>
#include <boost/thread.hpp>

#include <iostream>

#ifdef _WIN32
boost::function0<void> console_ctrl_function;

BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
{
  switch (ctrl_type)
  {
  case CTRL_C_EVENT:
  case CTRL_BREAK_EVENT:
  case CTRL_CLOSE_EVENT:
  case CTRL_SHUTDOWN_EVENT:
    console_ctrl_function();
    return TRUE;
  default:
    return FALSE;
  }
}
#endif

int main (int argc, const char * argv[])
{
    try
    {
        LogPolicy::GetInstance().Unmute();

        bool use_shared_memory = false, trial = false;
        std::string ip_address;
        int ip_port, requested_thread_num;

        ServerPaths server_paths;

        const unsigned init_result = GenerateServerProgramOptions(argc,
                                                                  argv,
                                                                  server_paths,
                                                                  ip_address,
                                                                  ip_port,
                                                                  requested_thread_num,
                                                                  use_shared_memory,
                                                                  trial);
        if (init_result == INIT_OK_DO_NOT_START_ENGINE)
        {
            return 0;
        }
        if (init_result == INIT_FAILED)
        {
            return 1;
        }

#ifdef __linux__
        const int lock_flags = MCL_CURRENT | MCL_FUTURE;
        if (-1 == mlockall(lock_flags))
        {
            SimpleLogger().Write(logWARNING) << "Process " << argv[0] << " could not be locked to RAM";
        }
#endif
        SimpleLogger().Write() <<
            "starting up engines, " << g_GIT_DESCRIPTION << ", " <<
            "compiled at " << __DATE__ << ", " __TIME__;

        if(use_shared_memory)
        {
            SimpleLogger().Write(logDEBUG) << "Loading from shared memory";
        }
        else
        {
            SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
            SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"];
            SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"];
            SimpleLogger().Write(logDEBUG) << "Geometry file:\t" << server_paths["geometries"];
            SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"];
            SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"];
            SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"];
            SimpleLogger().Write(logDEBUG) << "Timestamp file:\t" << server_paths["timestamp"];
            SimpleLogger().Write(logDEBUG) << "Threads:\t" << requested_thread_num;
            SimpleLogger().Write(logDEBUG) << "IP address:\t" << ip_address;
            SimpleLogger().Write(logDEBUG) << "IP port:\t" << ip_port;
        }
#ifndef _WIN32
        int sig = 0;
        sigset_t new_mask;
        sigset_t old_mask;
        sigfillset(&new_mask);
        pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
#endif

        OSRM osrm_lib(server_paths, use_shared_memory);
        Server * routing_server = ServerFactory::CreateServer(
                        ip_address,
                        ip_port,
                        requested_thread_num
                     );

        routing_server->GetRequestHandlerPtr().RegisterRoutingMachine(&osrm_lib);

        if( trial )
        {
            SimpleLogger().Write() << "trial run, quitting after successful initialization";
        }
        else
        {
            boost::thread server_thread(boost::bind(&Server::Run, routing_server));

#ifndef _WIN32
            sigset_t wait_mask;
            pthread_sigmask(SIG_SETMASK, &old_mask, 0);
            sigemptyset(&wait_mask);
            sigaddset(&wait_mask, SIGINT);
            sigaddset(&wait_mask, SIGQUIT);
            sigaddset(&wait_mask, SIGTERM);
            pthread_sigmask(SIG_BLOCK, &wait_mask, 0);
            SimpleLogger().Write() << "running and waiting for requests";
            sigwait(&wait_mask, &sig);
#else
            // Set console control handler to allow server to be stopped.
            console_ctrl_function = boost::bind(&Server::Stop, routing_server);
            SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
            SimpleLogger().Write() << "running and waiting for requests";
            routing_server->Run();
#endif
            SimpleLogger().Write() << "initiating shutdown";
            routing_server->Stop();
            SimpleLogger().Write() << "stopping threads";

            if (!server_thread.timed_join(boost::posix_time::seconds(2)))
            {
                SimpleLogger().Write(logDEBUG) << "Threads did not finish within 2 seconds. Hard abort!";
            }
        }

        SimpleLogger().Write() << "freeing objects";
        delete routing_server;
        SimpleLogger().Write() << "shutdown completed";
    }
    catch (const std::exception& e)
    {
        SimpleLogger().Write(logWARNING) << "exception: " << e.what();
        return 1;
    }
#ifdef __linux__
    munlockall();
#endif

    return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2021 Google LLC
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.
*/

#include "Poco/JSON/JSON.h"
#include "Poco/JSON/ParserImpl.h"
#include "Poco/JSON/Parser.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
        std::string json(reinterpret_cast<const char*>(data), size);
        Poco::JSON::Parser parser;

        Poco::Dynamic::Var result;
        try
        {
                result = parser.parse(json);
        }
        catch(const std::exception& e)
        {
                return 0;
        }
        return 0;
}
<commit_msg>[poco] Add exception to fuzzer (#5835)<commit_after>/* Copyright 2021 Google LLC
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.
*/

#include "Poco/JSON/JSON.h"
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/ParserImpl.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  std::string json(reinterpret_cast<const char *>(data), size);
  Poco::JSON::Parser parser;

  Poco::Dynamic::Var result;
  try {
    result = parser.parse(json);
  } catch (Poco::Exception &e) {
    return 0;
  } catch (const std::exception &e) {
    return 0;
  }
  return 0;
}
<|endoftext|>


<commit_before>#define VERSION "0.3"

#define MAX_COUNT 255
#define TAG_DENSITY 90
#define CONNECTED_THRESHOLD 0

namespace khmer {
  // largest number we can count up to, exactly. (8 bytes)
  typedef unsigned long long int ExactCounterType;

  // largest number we're going to hash into. (8 bytes/64 bits/32 nt)
  typedef unsigned long long int HashIntoType;

  // largest size 'k' value for k-mer calculations.  (1 byte/255)
  typedef unsigned char WordLength;

  // largest number we can count up to, approximately. (8 bytes/127).
  // see MAX_COUNT, above.
  typedef unsigned char BoundedCounterType;

  typedef void (*CallbackFn)(const char * info, void * callback_data,
			     unsigned int n_reads, unsigned long long other);
};
<commit_msg>set default to something sane for metagenomics<commit_after>#define VERSION "0.3"

#define MAX_COUNT 255
#define TAG_DENSITY 40
#define CONNECTED_THRESHOLD 0

namespace khmer {
  // largest number we can count up to, exactly. (8 bytes)
  typedef unsigned long long int ExactCounterType;

  // largest number we're going to hash into. (8 bytes/64 bits/32 nt)
  typedef unsigned long long int HashIntoType;

  // largest size 'k' value for k-mer calculations.  (1 byte/255)
  typedef unsigned char WordLength;

  // largest number we can count up to, approximately. (8 bytes/127).
  // see MAX_COUNT, above.
  typedef unsigned char BoundedCounterType;

  typedef void (*CallbackFn)(const char * info, void * callback_data,
			     unsigned int n_reads, unsigned long long other);
};
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2009, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
//     Free Software Foundation, Inc.,
//     51 Franklin Street, Fifth Floor,
//     Boston, MA
//     02110-1301
//     USA
//
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include "Context.h"

Context context;

int main (int argc, char** argv)
{
  // Set up randomness.
#ifdef HAVE_SRANDOM
  srandom (time (NULL));
#else
  srand (time (NULL));
#endif

  int status = 0;

  try
  {
    context.initialize (argc, argv);
    if (context.program.find ("itask") != std::string::npos)
      status = context.interactive ();
    else
      status = context.run ();
  }

  catch (std::string& error)
  {
    std::cout << error << std::endl;
    return -1;
  }

  catch (...)
  {
    std::cerr << context.stringtable.get (100, "Unknown error.") << std::endl;
    return -2;
  }

  return status;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Bug Fix<commit_after>////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2009, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
//     Free Software Foundation, Inc.,
//     51 Franklin Street, Fifth Floor,
//     Boston, MA
//     02110-1301
//     USA
//
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <stdlib.h>
#include "Context.h"

Context context;

int main (int argc, char** argv)
{
  // Set up randomness.
#ifdef HAVE_SRANDOM
  srandom (time (NULL));
#else
  srand (time (NULL));
#endif

  int status = 0;

  try
  {
    context.initialize (argc, argv);
    if (context.program.find ("itask") != std::string::npos)
      status = context.interactive ();
    else
      status = context.run ();
  }

  catch (std::string& error)
  {
    std::cout << error << std::endl;
    return -1;
  }

  catch (...)
  {
    std::cerr << context.stringtable.get (100, "Unknown error.") << std::endl;
    return -2;
  }

  return status;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>#include <avr/io.h>
#include <util/delay.h>
#include "Led.h"

/**
 * \brief main loop
 */
int main(void) {
    Led led(&PORTB, &DDRB, PINB0);

    while (1) {
        led.toggle();
        _delay_ms(500);
    }
}<commit_msg>first pwm test<commit_after>//#include <avr/io.h>
//#include <util/delay.h>
//#include "Led.h"

/**
 * \brief main loop
 */
//int main(void) {
//    Led led(&PORTB, &DDRB, PINB0);
//
//    while (1) {
//        led.toggle();
//        _delay_ms(500);
//    }
//}

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB   |= (1 << PB0);                   // PWM output on PB0
    TCCR0A = (1 << COM0A1) | (1 << WGM00);  // phase correct PWM mode
    OCR0A  = 0x10;                          // initial PWM pulse width

    TCCR0B = (1 << CS01);   // clock source = CLK/8, start PWM

    uint8_t brightness;

    while(1)
    {
        // increasing brightness
        for (brightness = 0; brightness < 255; ++brightness)
        {
            // set the brightness as duty cycle
            OCR0A = brightness;

            // delay so as to make the user "see" the change in brightness
            _delay_ms(10);
        }

        // decreasing brightness
        for (brightness = 255; brightness > 0; --brightness)
        {
            // set the brightness as duty cycle
            OCR0A = brightness;

            // delay so as to make the user "see" the change in brightness
            _delay_ms(10);
        }

    }
}
<|endoftext|>