<commit_before>// Copyright (c) 2014 The Cryptocoin Revival Foundation
// Copyright (c) 2015-2021 The CryptoCoderz Team / Espers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "core/main.h"
#include "database/txdb.h"
#include "velocity.h"
#include "rpc/rpcserver.h"
#include "core/blockparams.h"

bool VELOCITY_FACTOR = false;
uint256 RollingBlock;
int64_t RollingHeight;

/* VelocityI(int nHeight) ? i : -1
   Returns i or -1 if not found */
int VelocityI(int nHeight)
{
    if (FACTOR_TOGGLE(nHeight)) {
        VELOCITY_FACTOR = true;
    }
    return nHeight;
}

/* Velocity(int nHeight) ? true : false
   Returns true if nHeight is higher or equal to VELOCITY_HEIGHT */
bool Velocity_check(int nHeight)
{
    LogPrintf("Checking for Velocity on block %u: ",nHeight);
    if(VelocityI(nHeight) >= 0)
    {
        LogPrintf("Velocity is currently Enabled\n");
        return true;
    }
    LogPrintf("Velocity is currently disabled\n");
    return false;
}

/* Velocity(CBlockIndex* prevBlock, CBlock* block) ? true : false
   Goes close to the top of CBlock::AcceptBlock
   Returns true if proposed Block matches constrains */
bool Velocity(CBlockIndex* prevBlock, CBlock* block)
{
    // Define values
    CAmount tx_inputs_values = 0;
    CAmount tx_outputs_values = 0;
    CAmount tx_MapIn_values = 0;
    CAmount tx_MapOut_values = 0;
    CAmount tx_threshold = 0;
    int64_t TXcount = block->vtx.size();
    int64_t TXrate = 0;
    int64_t CURvalstamp  = 0;
    int64_t OLDvalstamp  = 0;
    int64_t CURstamp = 0;
    int64_t OLDstamp = 0;
    int64_t TXstampC = 0;
    int64_t TXstampO = 0;
    int64_t SYScrntstamp = 0;
    int64_t SYSbaseStamp = 0;
    int nHeight = prevBlock->nHeight+1;
    int i = VelocityI(nHeight);
    // Set stanard values
    TXrate = block->GetBlockTime() - prevBlock->GetBlockTime();
    TXstampC = block->nTime;
    TXstampO = prevBlock->nTime;
    CURstamp = block->GetBlockTime();
    OLDstamp = prevBlock->GetBlockTime();
    CURvalstamp = prevBlock->GetBlockTime() + VELOCITY_MIN_RATE[i];
    OLDvalstamp = prevBlock->pprev->GetBlockTime() + VELOCITY_MIN_RATE[i];
    SYScrntstamp = GetAdjustedTime() + VELOCITY_MIN_RATE[i];
    SYSbaseStamp = GetTime() + VELOCITY_MIN_RATE[i];

    if(block->IsProofOfStake()) {
        tx_threshold = GetProofOfStakeReward(0, 0);
    } else {
        tx_threshold = GetProofOfWorkReward(pindexBest->nHeight, 0);
    }

    // Factor in TXs for Velocity constraints
    if(VELOCITY_FACTOR == true)
    {
        // Set factor values
        BOOST_FOREACH(const CTransaction& tx, block->vtx)
        {
            // Load TX inputs
            CTxDB txdb("r");
            MapPrevTx mapInputs;
            map<uint256, CTxIndex> mapUnused;
            bool fInvalid = false;
            bool fNoIn = false;
            // Ensure we can fetch inputs
            if (!tx.FetchInputs(txdb, mapUnused, true, false, mapInputs, fInvalid))
            {
                if(nHeight > 982300) {
                    LogPrintf("DENIED: Invalid TX found during FetchInputs\n");
                    return false;
                } else {
                    LogPrintf("WARNING: Potentially Invalid TX found during FetchInputs\n");
                    fNoIn = true;
                }
            }
            // Authenticate submitted block's TXs
            if(!fNoIn) {
                tx_MapIn_values = tx.GetValueMapIn(mapInputs);
                if(tx_inputs_values + tx_MapIn_values >= 0) {
                    tx_inputs_values += tx_MapIn_values;
                } else {
                    LogPrintf("DENIED: overflow detected tx_inputs_values + tx.GetValueMapIn(mapInputs)\n");
                    return false;
                }
            }
            tx_MapOut_values = tx.GetValueOut();
            if(tx_outputs_values + tx_MapOut_values >= 0) {
                tx_outputs_values += tx_MapOut_values;
            } else {
                LogPrintf("DENIED: overflow detected tx_outputs_values + tx.GetValueOut()\n");
                return false;
            }
        }
        // Ensure input/output sanity of transactions in the block
        if((tx_inputs_values + tx_threshold) < tx_outputs_values)
        {
            if(nHeight < 981135 || nHeight > 982300) {// skip trouble blocks during initial rushed patch
                LogPrintf("DENIED: block contains a tx input that is less that output\n");
                return false;
            }
        }
        // Ensure expected coin supply matches actualy coin supply of block
        if((prevBlock->nMoneySupply + tx_threshold) < (tx_outputs_values))
        {
            LogPrintf("DENIED: block contains invalid coin supply amount\n");
            return false;
        }
        // Check for and enforce minimum TXs per block (Minimum TXs are disabled for Espers)
        if(VELOCITY_MIN_TX[i] > 0 && TXcount < VELOCITY_MIN_TX[i])
        {
            LogPrintf("DENIED: Not enough TXs in block\n");
            return false;
        }
    }

    // Verify minimum Velocity rate
    if( VELOCITY_RATE[i] > 0 && TXrate >= VELOCITY_MIN_RATE[i] )
    {
        LogPrintf("CHECK_PASSED: block spacing has met Velocity constraints\n");
    }
    // Rates that are too rapid are rejected without exception
    else if( VELOCITY_RATE[i] > 0 && TXrate < VELOCITY_MIN_RATE[i] )
    {
        LogPrintf("DENIED: Minimum block spacing not met for Velocity\n");
        return false;
    }

    // Validate timestamp is logical based on previous block history
    if(CURstamp < CURvalstamp || TXstampC < CURvalstamp)
    {
        LogPrintf("DENIED: Block timestamp is not logical\n");
        return false;
    }
    else if(OLDstamp < OLDvalstamp || TXstampO < OLDvalstamp)
    {
        if(nHeight != VELOCITY_HEIGHT[i])
        {
            LogPrintf("DENIED: Block timestamp is not logical\n");
            return false;
        }
    }

    // Validate timestamp is logical based on system time
    if(CURstamp > SYSbaseStamp || CURstamp > SYScrntstamp)
    {
        LogPrintf("DENIED: Block timestamp is not logical\n");
        return false;
    }
    else if(TXstampC > SYSbaseStamp || TXstampC > SYScrntstamp)
    {
        LogPrintf("DENIED: Block timestamp is not logical\n");
        return false;
    }

    // Constrain Velocity
    if(VELOCITY_EXPLICIT[i])
    {
        if(VELOCITY_MIN_TX[i] > 0)
            return false;
        if(VELOCITY_MIN_VALUE[i] > 0)
            return false;
        if(VELOCITY_MIN_FEE[i] > 0)
            return false;
    }
    // Velocity constraints met, return block acceptance
    return true;
}

bool RollingCheckpoints(int nHeight)
{
    // Skip chain start
    if (nHeight < 5000) {
        return false;
    }
    // Define values
    CBlockIndex* pindexCurrentBlock = pindexBest;
    CBlockIndex* pindexPastBlock = pindexCurrentBlock;
    // Set count and loop
    int pastBLOCK_1 = (pindexCurrentBlock->nHeight - BLOCK_TEMP_CHECKPOINT_DEPTH);
    while (pastBLOCK_1 < pindexCurrentBlock->nHeight) {
        // Index backwards
        pindexPastBlock = pindexPastBlock->pprev;
        pastBLOCK_1 ++;
    }
    // Set output values
    RollingBlock = pindexPastBlock->GetBlockHash();
    RollingHeight = pindexPastBlock->nHeight;
    // Success
    return true;
}
<commit_msg>Update velocity.cpp<commit_after>// Copyright (c) 2014 The Cryptocoin Revival Foundation
// Copyright (c) 2015-2021 The CryptoCoderz Team / Espers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "core/main.h"
#include "database/txdb.h"
#include "velocity.h"
#include "rpc/rpcserver.h"
#include "core/blockparams.h"

bool VELOCITY_FACTOR = false;
uint256 RollingBlock;
int64_t RollingHeight;

/* VelocityI(int nHeight) ? i : -1
   Returns i or -1 if not found */
int VelocityI(int nHeight)
{
    if (FACTOR_TOGGLE(nHeight)) {
        VELOCITY_FACTOR = true;
    }
    return nHeight;
}

/* Velocity(int nHeight) ? true : false
   Returns true if nHeight is higher or equal to VELOCITY_HEIGHT */
bool Velocity_check(int nHeight)
{
    LogPrintf("Checking for Velocity on block %u: ",nHeight);
    if(VelocityI(nHeight) >= VELOCITY_TOGGLE)
    {
        LogPrintf("Velocity is currently Enabled\n");
        return true;
    }
    LogPrintf("Velocity is currently disabled\n");
    return false;
}

/* Velocity(CBlockIndex* prevBlock, CBlock* block) ? true : false
   Goes close to the top of CBlock::AcceptBlock
   Returns true if proposed Block matches constrains */
bool Velocity(CBlockIndex* prevBlock, CBlock* block)
{
    // Define values
    CAmount tx_inputs_values = 0;
    CAmount tx_outputs_values = 0;
    CAmount tx_MapIn_values = 0;
    CAmount tx_MapOut_values = 0;
    CAmount tx_threshold = 0;
    int64_t TXcount = block->vtx.size();
    int64_t TXrate = 0;
    int64_t CURvalstamp  = 0;
    int64_t OLDvalstamp  = 0;
    int64_t CURstamp = 0;
    int64_t OLDstamp = 0;
    int64_t TXstampC = 0;
    int64_t TXstampO = 0;
    int64_t SYScrntstamp = 0;
    int64_t SYSbaseStamp = 0;
    int nHeight = prevBlock->nHeight+1;
    int i = VelocityI(nHeight);
    // Set stanard values
    TXrate = block->GetBlockTime() - prevBlock->GetBlockTime();
    TXstampC = block->nTime;
    TXstampO = prevBlock->nTime;
    CURstamp = block->GetBlockTime();
    OLDstamp = prevBlock->GetBlockTime();
    CURvalstamp = prevBlock->GetBlockTime() + VELOCITY_MIN_RATE[i];
    OLDvalstamp = prevBlock->pprev->GetBlockTime() + VELOCITY_MIN_RATE[i];
    SYScrntstamp = GetAdjustedTime() + VELOCITY_MIN_RATE[i];
    SYSbaseStamp = GetTime() + VELOCITY_MIN_RATE[i];

    if(block->IsProofOfStake()) {
        tx_threshold = GetProofOfStakeReward(0, 0);
    } else {
        tx_threshold = GetProofOfWorkReward(pindexBest->nHeight, 0);
    }

    // Factor in TXs for Velocity constraints
    if(VELOCITY_FACTOR == true)
    {
        // Set factor values
        BOOST_FOREACH(const CTransaction& tx, block->vtx)
        {
            // Load TX inputs
            CTxDB txdb("r");
            MapPrevTx mapInputs;
            map<uint256, CTxIndex> mapUnused;
            bool fInvalid = false;
            bool fNoIn = false;
            // Ensure we can fetch inputs
            if (!tx.FetchInputs(txdb, mapUnused, true, false, mapInputs, fInvalid))
            {
                if(nHeight > 982300) {
                    LogPrintf("DENIED: Invalid TX found during FetchInputs\n");
                    return false;
                } else {
                    LogPrintf("WARNING: Potentially Invalid TX found during FetchInputs\n");
                    fNoIn = true;
                }
            }
            // Authenticate submitted block's TXs
            if(!fNoIn) {
                tx_MapIn_values = tx.GetValueMapIn(mapInputs);
                if(tx_inputs_values + tx_MapIn_values >= 0) {
                    tx_inputs_values += tx_MapIn_values;
                } else {
                    LogPrintf("DENIED: overflow detected tx_inputs_values + tx.GetValueMapIn(mapInputs)\n");
                    return false;
                }
            }
            tx_MapOut_values = tx.GetValueOut();
            if(tx_outputs_values + tx_MapOut_values >= 0) {
                tx_outputs_values += tx_MapOut_values;
            } else {
                LogPrintf("DENIED: overflow detected tx_outputs_values + tx.GetValueOut()\n");
                return false;
            }
        }
        // Ensure input/output sanity of transactions in the block
        if((tx_inputs_values + tx_threshold) < tx_outputs_values)
        {
            if(nHeight < 981135 || nHeight > 982300) {// skip trouble blocks during initial rushed patch
                LogPrintf("DENIED: block contains a tx input that is less that output\n");
                return false;
            }
        }
        // Ensure expected coin supply matches actualy coin supply of block
        if((prevBlock->nMoneySupply + tx_threshold) < (tx_outputs_values))
        {
            LogPrintf("DENIED: block contains invalid coin supply amount\n");
            return false;
        }
        // Check for and enforce minimum TXs per block (Minimum TXs are disabled for Espers)
        if(VELOCITY_MIN_TX[i] > 0 && TXcount < VELOCITY_MIN_TX[i])
        {
            LogPrintf("DENIED: Not enough TXs in block\n");
            return false;
        }
    }

    // Verify minimum Velocity rate
    if( VELOCITY_RATE[i] > 0 && TXrate >= VELOCITY_MIN_RATE[i] )
    {
        LogPrintf("CHECK_PASSED: block spacing has met Velocity constraints\n");
    }
    // Rates that are too rapid are rejected without exception
    else if( VELOCITY_RATE[i] > 0 && TXrate < VELOCITY_MIN_RATE[i] )
    {
        LogPrintf("DENIED: Minimum block spacing not met for Velocity\n");
        return false;
    }

    // Validate timestamp is logical based on previous block history
    if(CURstamp < CURvalstamp || TXstampC < CURvalstamp)
    {
        LogPrintf("DENIED: Block timestamp is not logical\n");
        return false;
    }
    else if(OLDstamp < OLDvalstamp || TXstampO < OLDvalstamp)
    {
        if(nHeight != VELOCITY_HEIGHT[i])
        {
            LogPrintf("DENIED: Block timestamp is not logical\n");
            return false;
        }
    }

    // Validate timestamp is logical based on system time
    if(CURstamp > SYSbaseStamp || CURstamp > SYScrntstamp)
    {
        LogPrintf("DENIED: Block timestamp is not logical\n");
        return false;
    }
    else if(TXstampC > SYSbaseStamp || TXstampC > SYScrntstamp)
    {
        LogPrintf("DENIED: Block timestamp is not logical\n");
        return false;
    }

    // Constrain Velocity
    if(VELOCITY_EXPLICIT[i])
    {
        if(VELOCITY_MIN_TX[i] > 0)
            return false;
        if(VELOCITY_MIN_VALUE[i] > 0)
            return false;
        if(VELOCITY_MIN_FEE[i] > 0)
            return false;
    }
    // Velocity constraints met, return block acceptance
    return true;
}

bool RollingCheckpoints(int nHeight)
{
    // Skip chain start
    if (nHeight < 5000) {
        return false;
    }
    // Define values
    CBlockIndex* pindexCurrentBlock = pindexBest;
    CBlockIndex* pindexPastBlock = pindexCurrentBlock;
    // Set count and loop
    int pastBLOCK_1 = (pindexCurrentBlock->nHeight - BLOCK_TEMP_CHECKPOINT_DEPTH);
    while (pastBLOCK_1 < pindexCurrentBlock->nHeight) {
        // Index backwards
        pindexPastBlock = pindexPastBlock->pprev;
        pastBLOCK_1 ++;
    }
    // Set output values
    RollingBlock = pindexPastBlock->GetBlockHash();
    RollingHeight = pindexPastBlock->nHeight;
    // Success
    return true;
}
<|endoftext|>


<commit_before>#include "core/Apportionment.hpp"
#include <algorithm>
#include <random>

Apportionment::Apportionment(
	PopulationNode * upperNode,
	ApportionmentFunction * apportionment,
	AggregationFunction * aggregator
) {
	// TODO: Empirically determine a sane default for try-on count
	this->init(
		upperNode,
		apportionment,
		aggregator,
		upperNode->populationSize()
	);
}

Apportionment::Apportionment(
	PopulationNode * upperNode,
	ApportionmentFunction * apportionment,
	AggregationFunction * aggregator,
	unsigned int tryOns
) {
	this->init(upperNode, apportionment, aggregator, tryOns);
}

Apportionment::~Apportionment() {}

void Apportionment::init(
	PopulationNode * upperNode,
	ApportionmentFunction * apportionment,
	AggregationFunction * aggregator,
	unsigned int tryOns
) {
	this->upperNode = upperNode;
	this->apportionment = apportionment;
	this->aggregator = aggregator;
	this->tryOns = tryOns;
}

Genome * Apportionment::getOperableGenome(Genome * genome) {
	return new Genome(genome->flattenGenome());
}

std::vector<unsigned int> Apportionment::getComponentIndices(
	Genome * upper,
	Genome * target
) {
	return upper->getFlattenedIndices(target);
}

void Apportionment::evaluatePair(
	Genome * upper,
	Genome * target,
	int upperFitness,
	std::vector<int> & apportionedFitnesses
) {
	std::vector<unsigned int> componentIndices =
		this->getComponentIndices(upper, target);

	Genome * provider = this->getOperableGenome(upper);
	for (unsigned int i = 0; i < componentIndices.size(); i++)
		apportionedFitnesses.push_back(
			this->apportionment->apportionFitness(
				target,
				provider,
				componentIndices[i],
				upperFitness
			)
		);
	delete(provider);
}

// TODO: Refactor this function
int Apportionment::checkFitness(Genome * genome) {
	std::vector<int> apportionedFitnesses;
	std::vector<bool> tried(this->upperNode->populationSize(), false);
	unsigned int triedOn = 0;
	Genome flattened = genome->flattenGenome();

	for (unsigned int i = 0; i < this->upperNode->populationSize(); i++) {
		if (this->upperNode->getIndex(i)->usesComponent(genome)) {
			this->evaluatePair(
				this->upperNode->getIndex(i),
				&flattened,
				this->upperNode->getFitnessAtIndex(i),
				apportionedFitnesses
			);
			triedOn++;
			tried[i] = true;
		}
	}

	// TODO: Refactor this into the class def
	mt19937 generator;
	uniform_int_distribution<unsigned int> selDist(
		0,
		this->upperNode->populationSize() - 1
	);

	unsigned int tryOns = std::min(
		this->upperNode->populationSize() - 1,
		this->tryOns
	);

	while (triedOn < tryOns) {
		unsigned int index;
		do index = selDist(generator); while(tried[index]);
		Genome * provider = this->upperNode->getIndex(index)
			->replaceComponent(genome);
		this->evaluatePair(
			provider,
			&flattened,
			this->upperNode->evaluateFitness(provider),
			apportionedFitnesses
		);
		delete(provider);
		triedOn++;
		tried[index] = true;
	}

	return this->aggregateFitnesses(apportionedFitnesses);
}

int Apportionment::aggregateFitnesses(std::vector<int> apportionedFitnesses) {
	return this->aggregator->aggregateFitnesses(apportionedFitnesses);
}

bool Apportionment::isApportioning() {
	return true;
}

ApportionmentFunction * Apportionment::getApportionmentFunction() {
	return this->apportionment;
}

AggregationFunction * Apportionment::getAggregationFunction() {
	return this->aggregator;
}
<commit_msg>[Apportionment]: Used proper arguments to min<commit_after>#include "core/Apportionment.hpp"
#include <algorithm>
#include <random>

Apportionment::Apportionment(
	PopulationNode * upperNode,
	ApportionmentFunction * apportionment,
	AggregationFunction * aggregator
) {
	// TODO: Empirically determine a sane default for try-on count
	this->init(
		upperNode,
		apportionment,
		aggregator,
		upperNode->populationSize()
	);
}

Apportionment::Apportionment(
	PopulationNode * upperNode,
	ApportionmentFunction * apportionment,
	AggregationFunction * aggregator,
	unsigned int tryOns
) {
	this->init(upperNode, apportionment, aggregator, tryOns);
}

Apportionment::~Apportionment() {}

void Apportionment::init(
	PopulationNode * upperNode,
	ApportionmentFunction * apportionment,
	AggregationFunction * aggregator,
	unsigned int tryOns
) {
	this->upperNode = upperNode;
	this->apportionment = apportionment;
	this->aggregator = aggregator;
	this->tryOns = tryOns;
}

Genome * Apportionment::getOperableGenome(Genome * genome) {
	return new Genome(genome->flattenGenome());
}

std::vector<unsigned int> Apportionment::getComponentIndices(
	Genome * upper,
	Genome * target
) {
	return upper->getFlattenedIndices(target);
}

void Apportionment::evaluatePair(
	Genome * upper,
	Genome * target,
	int upperFitness,
	std::vector<int> & apportionedFitnesses
) {
	std::vector<unsigned int> componentIndices =
		this->getComponentIndices(upper, target);

	Genome * provider = this->getOperableGenome(upper);
	for (unsigned int i = 0; i < componentIndices.size(); i++)
		apportionedFitnesses.push_back(
			this->apportionment->apportionFitness(
				target,
				provider,
				componentIndices[i],
				upperFitness
			)
		);
	delete(provider);
}

// TODO: Refactor this function
int Apportionment::checkFitness(Genome * genome) {
	std::vector<int> apportionedFitnesses;
	std::vector<bool> tried(this->upperNode->populationSize(), false);
	unsigned int triedOn = 0;
	Genome flattened = genome->flattenGenome();

	for (unsigned int i = 0; i < this->upperNode->populationSize(); i++) {
		if (this->upperNode->getIndex(i)->usesComponent(genome)) {
			this->evaluatePair(
				this->upperNode->getIndex(i),
				&flattened,
				this->upperNode->getFitnessAtIndex(i),
				apportionedFitnesses
			);
			triedOn++;
			tried[i] = true;
		}
	}

	// TODO: Refactor this into the class def
	mt19937 generator;
	uniform_int_distribution<unsigned int> selDist(
		0,
		this->upperNode->populationSize() - 1
	);

	unsigned int tryOns = std::min(
		this->upperNode->populationSize(),
		this->tryOns
	);

	while (triedOn < tryOns) {
		unsigned int index;
		do index = selDist(generator); while(tried[index]);
		Genome * provider = this->upperNode->getIndex(index)
			->replaceComponent(genome);
		this->evaluatePair(
			provider,
			&flattened,
			this->upperNode->evaluateFitness(provider),
			apportionedFitnesses
		);
		delete(provider);
		triedOn++;
		tried[index] = true;
	}

	return this->aggregateFitnesses(apportionedFitnesses);
}

int Apportionment::aggregateFitnesses(std::vector<int> apportionedFitnesses) {
	return this->aggregator->aggregateFitnesses(apportionedFitnesses);
}

bool Apportionment::isApportioning() {
	return true;
}

ApportionmentFunction * Apportionment::getApportionmentFunction() {
	return this->apportionment;
}

AggregationFunction * Apportionment::getAggregationFunction() {
	return this->aggregator;
}
<|endoftext|>


<commit_before>//===-- TestCompletion.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/TildeExpressionResolver.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "TestingSupport/MockTildeExpressionResolver.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

namespace fs = llvm::sys::fs;
namespace path = llvm::sys::path;
using namespace llvm;
using namespace lldb_private;

#define ASSERT_NO_ERROR(x)                                                     \
  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
    SmallString<128> MessageStorage;                                           \
    raw_svector_ostream Message(MessageStorage);                               \
    Message << #x ": did not return errc::success.\n"                          \
            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
  } else {                                                                     \
  }

namespace {

class CompletionTest : public testing::Test {
protected:
  /// Unique temporary directory in which all created filesystem entities must
  /// be placed. It is removed at the end of the test suite.
  SmallString<128> BaseDir;

  /// The working directory that we got when starting the test. Every test
  /// should chdir into this directory first because some tests maybe chdir
  /// into another one during their run.
  static SmallString<128> OriginalWorkingDir;

  SmallString<128> DirFoo;
  SmallString<128> DirFooA;
  SmallString<128> DirFooB;
  SmallString<128> DirFooC;
  SmallString<128> DirBar;
  SmallString<128> DirBaz;
  SmallString<128> DirTestFolder;
  SmallString<128> DirNested;

  SmallString<128> FileAA;
  SmallString<128> FileAB;
  SmallString<128> FileAC;
  SmallString<128> FileFoo;
  SmallString<128> FileBar;
  SmallString<128> FileBaz;

  void SetUp() override {
    // chdir back into the original working dir this test binary started with.
    // A previous test may have have changed the working dir.
    ASSERT_NO_ERROR(fs::set_current_path(OriginalWorkingDir));

    // Get the name of the current test. To prevent that by chance two tests
    // get the same temporary directory if createUniqueDirectory fails.
    auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
    ASSERT_TRUE(test_info != nullptr);
    std::string name = test_info->name();
    ASSERT_NO_ERROR(fs::createUniqueDirectory("FsCompletion-" + name, BaseDir));

    const char *DirNames[] = {"foo", "fooa", "foob",        "fooc",
                              "bar", "baz",  "test_folder", "foo/nested"};
    const char *FileNames[] = {"aa1234.tmp",  "ab1234.tmp",  "ac1234.tmp",
                               "foo1234.tmp", "bar1234.tmp", "baz1234.tmp"};
    SmallString<128> *Dirs[] = {&DirFoo, &DirFooA, &DirFooB,       &DirFooC,
                                &DirBar, &DirBaz,  &DirTestFolder, &DirNested};
    for (auto Dir : llvm::zip(DirNames, Dirs)) {
      auto &Path = *std::get<1>(Dir);
      Path = BaseDir;
      path::append(Path, std::get<0>(Dir));
      ASSERT_NO_ERROR(fs::create_directories(Path));
    }

    SmallString<128> *Files[] = {&FileAA,  &FileAB,  &FileAC,
                                 &FileFoo, &FileBar, &FileBaz};
    for (auto File : llvm::zip(FileNames, Files)) {
      auto &Path = *std::get<1>(File);
      Path = BaseDir;
      path::append(Path, std::get<0>(File));
      int FD;
      ASSERT_NO_ERROR(fs::createUniqueFile(Path, FD, Path));
      ::close(FD);
    }
  }

  static void SetUpTestCase() {
    ASSERT_NO_ERROR(fs::current_path(OriginalWorkingDir));
  }

  void TearDown() override { ASSERT_NO_ERROR(fs::remove_directories(BaseDir)); }

  static bool HasEquivalentFile(const Twine &Path, const StringList &Paths) {
    for (size_t I = 0; I < Paths.GetSize(); ++I) {
      if (fs::equivalent(Path, Paths[I]))
        return true;
    }
    return false;
  }

  void DoDirCompletions(const Twine &Prefix,
                        StandardTildeExpressionResolver &Resolver,
                        StringList &Results) {
    // When a partial name matches, it returns all matches.  If it matches both
    // a full name AND some partial names, it returns all of them.
    uint32_t Count =
        CommandCompletions::DiskDirectories(Prefix + "foo", Results, Resolver);
    ASSERT_EQ(4u, Count);
    ASSERT_EQ(Count, Results.GetSize());
    EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
    EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
    EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
    EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));

    // If it matches only partial names, it still works as expected.
    Count = CommandCompletions::DiskDirectories(Twine(Prefix) + "b", Results,
                                                Resolver);
    ASSERT_EQ(2u, Count);
    ASSERT_EQ(Count, Results.GetSize());
    EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
    EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
  }
};

SmallString<128> CompletionTest::OriginalWorkingDir;
}

static std::vector<std::string> toVector(const StringList &SL) {
  std::vector<std::string> Result;
  for (size_t Idx = 0; Idx < SL.GetSize(); ++Idx)
    Result.push_back(SL[Idx]);
  return Result;
}
using testing::UnorderedElementsAre;

TEST_F(CompletionTest, DirCompletionAbsolute) {
  // All calls to DiskDirectories() return only directories, even when
  // there are files which also match.  The tests below all check this
  // by asserting an exact result count, and verifying against known
  // folders.

  std::string Prefixes[] = {(Twine(BaseDir) + "/").str(), ""};

  StandardTildeExpressionResolver Resolver;
  StringList Results;

  // When a directory is specified that doesn't end in a slash, it searches
  // for that directory, not items under it.
  // Sanity check that the path we complete on exists and isn't too long.
  ASSERT_TRUE(llvm::sys::fs::exists(BaseDir));
#ifdef PATH_MAX
  ASSERT_LE(BaseDir.size(), static_cast<size_t>(PATH_MAX));
#endif
  size_t Count =
      CommandCompletions::DiskDirectories(BaseDir, Results, Resolver);
  ASSERT_EQ(1u, Count) << "Failed to get BaseDir completions. BaseDir is '" << BaseDir << "'. Exists: " << llvm::sys::fs::exists(BaseDir) << " Results: " << Results.GetSize() << "\n";
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(BaseDir, Results));

  Count =
    CommandCompletions::DiskDirectories(Twine(BaseDir) + "/.", Results, Resolver);
  ASSERT_EQ(0u, Count);
  ASSERT_EQ(Count, Results.GetSize());

  // When the same directory ends with a slash, it finds all children.
  Count = CommandCompletions::DiskDirectories(Prefixes[0], Results, Resolver);
  ASSERT_EQ(7u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
  EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
  EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
  EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results));

  DoDirCompletions(Twine(BaseDir) + "/", Resolver, Results);
  llvm::sys::fs::set_current_path(BaseDir);
  DoDirCompletions("", Resolver, Results);
}

TEST_F(CompletionTest, FileCompletionAbsolute) {
  // All calls to DiskFiles() return both files and directories  The tests below
  // all check this by asserting an exact result count, and verifying against
  // known folders.

  StandardTildeExpressionResolver Resolver;
  StringList Results;
  // When an item is specified that doesn't end in a slash but exactly matches
  // one item, it returns that item.
  size_t Count = CommandCompletions::DiskFiles(Twine(BaseDir) + "/fooa",
                                               Results, Resolver);
  ASSERT_EQ(1u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));

  // The previous check verified a directory match.  But it should work for
  // files too.
  Count =
      CommandCompletions::DiskFiles(Twine(BaseDir) + "/aa", Results, Resolver);
  ASSERT_EQ(1u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(FileAA, Results));

  // When it ends with a slash, it should find all files and directories.
  Count =
      CommandCompletions::DiskFiles(Twine(BaseDir) + "/", Results, Resolver);
  ASSERT_EQ(13u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
  EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
  EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
  EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results));

  EXPECT_TRUE(HasEquivalentFile(FileAA, Results));
  EXPECT_TRUE(HasEquivalentFile(FileAB, Results));
  EXPECT_TRUE(HasEquivalentFile(FileAC, Results));
  EXPECT_TRUE(HasEquivalentFile(FileFoo, Results));
  EXPECT_TRUE(HasEquivalentFile(FileBar, Results));
  EXPECT_TRUE(HasEquivalentFile(FileBaz, Results));

  // When a partial name matches, it returns all file & directory matches.
  Count =
      CommandCompletions::DiskFiles(Twine(BaseDir) + "/foo", Results, Resolver);
  ASSERT_EQ(5u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
  EXPECT_TRUE(HasEquivalentFile(FileFoo, Results));
}

TEST_F(CompletionTest, DirCompletionUsername) {
  MockTildeExpressionResolver Resolver("James", BaseDir);
  Resolver.AddKnownUser("Kirk", DirFooB);
  Resolver.AddKnownUser("Lars", DirFooC);
  Resolver.AddKnownUser("Jason", DirFoo);
  Resolver.AddKnownUser("Larry", DirFooA);
  std::string sep = path::get_separator();

  // Just resolving current user's home directory by itself should return the
  // directory.
  StringList Results;
  size_t Count = CommandCompletions::DiskDirectories("~", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre("~" + sep));

  // With a slash appended, it should return all items in the directory.
  Count = CommandCompletions::DiskDirectories("~/", Results, Resolver);
  EXPECT_THAT(toVector(Results),
              UnorderedElementsAre(
                  "~/foo" + sep, "~/fooa" + sep, "~/foob" + sep, "~/fooc" + sep,
                  "~/bar" + sep, "~/baz" + sep, "~/test_folder" + sep));
  EXPECT_EQ(Count, Results.GetSize());

  // Check that we can complete directories in nested paths
  Count = CommandCompletions::DiskDirectories("~/foo/", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre("~/foo/nested" + sep));

  Count = CommandCompletions::DiskDirectories("~/foo/nes", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre("~/foo/nested" + sep));

  // With ~username syntax it should return one match if there is an exact
  // match.  It shouldn't translate to the actual directory, it should keep the
  // form the user typed.
  Count = CommandCompletions::DiskDirectories("~Lars", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre("~Lars" + sep));

  // But with a username that is not found, no results are returned.
  Count = CommandCompletions::DiskDirectories("~Dave", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre());

  // And if there are multiple matches, it should return all of them.
  Count = CommandCompletions::DiskDirectories("~La", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results),
              UnorderedElementsAre("~Lars" + sep, "~Larry" + sep));
}
<commit_msg>Revert "Add more logging to TestCompletion.cpp to try to track down bot failure."<commit_after>//===-- TestCompletion.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/TildeExpressionResolver.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "TestingSupport/MockTildeExpressionResolver.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

namespace fs = llvm::sys::fs;
namespace path = llvm::sys::path;
using namespace llvm;
using namespace lldb_private;

#define ASSERT_NO_ERROR(x)                                                     \
  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
    SmallString<128> MessageStorage;                                           \
    raw_svector_ostream Message(MessageStorage);                               \
    Message << #x ": did not return errc::success.\n"                          \
            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
  } else {                                                                     \
  }

namespace {

class CompletionTest : public testing::Test {
protected:
  /// Unique temporary directory in which all created filesystem entities must
  /// be placed. It is removed at the end of the test suite.
  SmallString<128> BaseDir;

  /// The working directory that we got when starting the test. Every test
  /// should chdir into this directory first because some tests maybe chdir
  /// into another one during their run.
  static SmallString<128> OriginalWorkingDir;

  SmallString<128> DirFoo;
  SmallString<128> DirFooA;
  SmallString<128> DirFooB;
  SmallString<128> DirFooC;
  SmallString<128> DirBar;
  SmallString<128> DirBaz;
  SmallString<128> DirTestFolder;
  SmallString<128> DirNested;

  SmallString<128> FileAA;
  SmallString<128> FileAB;
  SmallString<128> FileAC;
  SmallString<128> FileFoo;
  SmallString<128> FileBar;
  SmallString<128> FileBaz;

  void SetUp() override {
    // chdir back into the original working dir this test binary started with.
    // A previous test may have have changed the working dir.
    ASSERT_NO_ERROR(fs::set_current_path(OriginalWorkingDir));

    // Get the name of the current test. To prevent that by chance two tests
    // get the same temporary directory if createUniqueDirectory fails.
    auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
    ASSERT_TRUE(test_info != nullptr);
    std::string name = test_info->name();
    ASSERT_NO_ERROR(fs::createUniqueDirectory("FsCompletion-" + name, BaseDir));

    const char *DirNames[] = {"foo", "fooa", "foob",        "fooc",
                              "bar", "baz",  "test_folder", "foo/nested"};
    const char *FileNames[] = {"aa1234.tmp",  "ab1234.tmp",  "ac1234.tmp",
                               "foo1234.tmp", "bar1234.tmp", "baz1234.tmp"};
    SmallString<128> *Dirs[] = {&DirFoo, &DirFooA, &DirFooB,       &DirFooC,
                                &DirBar, &DirBaz,  &DirTestFolder, &DirNested};
    for (auto Dir : llvm::zip(DirNames, Dirs)) {
      auto &Path = *std::get<1>(Dir);
      Path = BaseDir;
      path::append(Path, std::get<0>(Dir));
      ASSERT_NO_ERROR(fs::create_directories(Path));
    }

    SmallString<128> *Files[] = {&FileAA,  &FileAB,  &FileAC,
                                 &FileFoo, &FileBar, &FileBaz};
    for (auto File : llvm::zip(FileNames, Files)) {
      auto &Path = *std::get<1>(File);
      Path = BaseDir;
      path::append(Path, std::get<0>(File));
      int FD;
      ASSERT_NO_ERROR(fs::createUniqueFile(Path, FD, Path));
      ::close(FD);
    }
  }

  static void SetUpTestCase() {
    ASSERT_NO_ERROR(fs::current_path(OriginalWorkingDir));
  }

  void TearDown() override { ASSERT_NO_ERROR(fs::remove_directories(BaseDir)); }

  static bool HasEquivalentFile(const Twine &Path, const StringList &Paths) {
    for (size_t I = 0; I < Paths.GetSize(); ++I) {
      if (fs::equivalent(Path, Paths[I]))
        return true;
    }
    return false;
  }

  void DoDirCompletions(const Twine &Prefix,
                        StandardTildeExpressionResolver &Resolver,
                        StringList &Results) {
    // When a partial name matches, it returns all matches.  If it matches both
    // a full name AND some partial names, it returns all of them.
    uint32_t Count =
        CommandCompletions::DiskDirectories(Prefix + "foo", Results, Resolver);
    ASSERT_EQ(4u, Count);
    ASSERT_EQ(Count, Results.GetSize());
    EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
    EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
    EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
    EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));

    // If it matches only partial names, it still works as expected.
    Count = CommandCompletions::DiskDirectories(Twine(Prefix) + "b", Results,
                                                Resolver);
    ASSERT_EQ(2u, Count);
    ASSERT_EQ(Count, Results.GetSize());
    EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
    EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
  }
};

SmallString<128> CompletionTest::OriginalWorkingDir;
}

static std::vector<std::string> toVector(const StringList &SL) {
  std::vector<std::string> Result;
  for (size_t Idx = 0; Idx < SL.GetSize(); ++Idx)
    Result.push_back(SL[Idx]);
  return Result;
}
using testing::UnorderedElementsAre;

TEST_F(CompletionTest, DirCompletionAbsolute) {
  // All calls to DiskDirectories() return only directories, even when
  // there are files which also match.  The tests below all check this
  // by asserting an exact result count, and verifying against known
  // folders.

  std::string Prefixes[] = {(Twine(BaseDir) + "/").str(), ""};

  StandardTildeExpressionResolver Resolver;
  StringList Results;

  // When a directory is specified that doesn't end in a slash, it searches
  // for that directory, not items under it.
  // Sanity check that the path we complete on exists and isn't too long.
  ASSERT_TRUE(llvm::sys::fs::exists(BaseDir));
#ifdef PATH_MAX
  ASSERT_LE(BaseDir.size(), static_cast<size_t>(PATH_MAX));
#endif
  size_t Count =
      CommandCompletions::DiskDirectories(BaseDir, Results, Resolver);
  ASSERT_EQ(1u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(BaseDir, Results));

  Count =
    CommandCompletions::DiskDirectories(Twine(BaseDir) + "/.", Results, Resolver);
  ASSERT_EQ(0u, Count);
  ASSERT_EQ(Count, Results.GetSize());

  // When the same directory ends with a slash, it finds all children.
  Count = CommandCompletions::DiskDirectories(Prefixes[0], Results, Resolver);
  ASSERT_EQ(7u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
  EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
  EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
  EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results));

  DoDirCompletions(Twine(BaseDir) + "/", Resolver, Results);
  llvm::sys::fs::set_current_path(BaseDir);
  DoDirCompletions("", Resolver, Results);
}

TEST_F(CompletionTest, FileCompletionAbsolute) {
  // All calls to DiskFiles() return both files and directories  The tests below
  // all check this by asserting an exact result count, and verifying against
  // known folders.

  StandardTildeExpressionResolver Resolver;
  StringList Results;
  // When an item is specified that doesn't end in a slash but exactly matches
  // one item, it returns that item.
  size_t Count = CommandCompletions::DiskFiles(Twine(BaseDir) + "/fooa",
                                               Results, Resolver);
  ASSERT_EQ(1u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));

  // The previous check verified a directory match.  But it should work for
  // files too.
  Count =
      CommandCompletions::DiskFiles(Twine(BaseDir) + "/aa", Results, Resolver);
  ASSERT_EQ(1u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(FileAA, Results));

  // When it ends with a slash, it should find all files and directories.
  Count =
      CommandCompletions::DiskFiles(Twine(BaseDir) + "/", Results, Resolver);
  ASSERT_EQ(13u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
  EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
  EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
  EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results));

  EXPECT_TRUE(HasEquivalentFile(FileAA, Results));
  EXPECT_TRUE(HasEquivalentFile(FileAB, Results));
  EXPECT_TRUE(HasEquivalentFile(FileAC, Results));
  EXPECT_TRUE(HasEquivalentFile(FileFoo, Results));
  EXPECT_TRUE(HasEquivalentFile(FileBar, Results));
  EXPECT_TRUE(HasEquivalentFile(FileBaz, Results));

  // When a partial name matches, it returns all file & directory matches.
  Count =
      CommandCompletions::DiskFiles(Twine(BaseDir) + "/foo", Results, Resolver);
  ASSERT_EQ(5u, Count);
  ASSERT_EQ(Count, Results.GetSize());
  EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
  EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
  EXPECT_TRUE(HasEquivalentFile(FileFoo, Results));
}

TEST_F(CompletionTest, DirCompletionUsername) {
  MockTildeExpressionResolver Resolver("James", BaseDir);
  Resolver.AddKnownUser("Kirk", DirFooB);
  Resolver.AddKnownUser("Lars", DirFooC);
  Resolver.AddKnownUser("Jason", DirFoo);
  Resolver.AddKnownUser("Larry", DirFooA);
  std::string sep = path::get_separator();

  // Just resolving current user's home directory by itself should return the
  // directory.
  StringList Results;
  size_t Count = CommandCompletions::DiskDirectories("~", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre("~" + sep));

  // With a slash appended, it should return all items in the directory.
  Count = CommandCompletions::DiskDirectories("~/", Results, Resolver);
  EXPECT_THAT(toVector(Results),
              UnorderedElementsAre(
                  "~/foo" + sep, "~/fooa" + sep, "~/foob" + sep, "~/fooc" + sep,
                  "~/bar" + sep, "~/baz" + sep, "~/test_folder" + sep));
  EXPECT_EQ(Count, Results.GetSize());

  // Check that we can complete directories in nested paths
  Count = CommandCompletions::DiskDirectories("~/foo/", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre("~/foo/nested" + sep));

  Count = CommandCompletions::DiskDirectories("~/foo/nes", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre("~/foo/nested" + sep));

  // With ~username syntax it should return one match if there is an exact
  // match.  It shouldn't translate to the actual directory, it should keep the
  // form the user typed.
  Count = CommandCompletions::DiskDirectories("~Lars", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre("~Lars" + sep));

  // But with a username that is not found, no results are returned.
  Count = CommandCompletions::DiskDirectories("~Dave", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results), UnorderedElementsAre());

  // And if there are multiple matches, it should return all of them.
  Count = CommandCompletions::DiskDirectories("~La", Results, Resolver);
  EXPECT_EQ(Count, Results.GetSize());
  EXPECT_THAT(toVector(Results),
              UnorderedElementsAre("~Lars" + sep, "~Larry" + sep));
}
<|endoftext|>


<commit_before>/**
 * Created by Jian Chen
 * @since  2016.12.14
 * @author Jian Chen <admin@chensoft.com>
 * @link   http://chensoft.com
 */
#ifdef __linux__

#include <socket/core/reactor.hpp>
#include <chen/sys/sys.hpp>
#include <sys/eventfd.h>
#include <limits>

// -----------------------------------------------------------------------------
// reactor
const int chen::reactor::FlagEdge = EPOLLET;
const int chen::reactor::FlagOnce = EPOLLONESHOT;

chen::reactor::reactor(int count) : _count(count)
{
    // create epoll file descriptor
    // 1 is just a hint, see http://man7.org/linux/man-pages/man2/epoll_create.2.html
    if ((this->_epoll = ::epoll_create(1)) < 0)
        throw std::system_error(sys::error(), "epoll: failed to create epoll");

    // create eventfd to receive wake message
    this->_wake.handle = ::eventfd(0, 0);

    if ((this->_wake.handle < 0) || ::fcntl(this->_wake.handle, F_SETFL, ::fcntl(this->_wake.handle, F_GETFL, 0) | O_NONBLOCK))
    {
        ::close(this->_epoll);
        throw std::system_error(sys::error(), "epoll: failed to create eventfd");
    }

    this->set(&this->_wake, ModeRead, FlagEdge);
}

chen::reactor::~reactor()
{
    ::close(this->_epoll);
    ::close(this->_wake.handle);
}

// modify
void chen::reactor::set(Event *ev, int mode, int flag)
{
    ::epoll_event event{};

    if (mode & ModeRead)
        event.events |= EPOLLIN;

    if (mode & ModeWrite)
        event.events |= EPOLLOUT;

    event.events  |= flag | EPOLLRDHUP;
    event.data.ptr = ev;

    // register event
    if (::epoll_ctl(this->_epoll, EPOLL_CTL_MOD, ev->handle, &event) != 0)
    {
        if ((errno != ENOENT) || (::epoll_ctl(this->_epoll, EPOLL_CTL_ADD, ev->handle, &event) != 0))
            throw std::system_error(sys::error(), "epoll: failed to set event");
    }
}

void chen::reactor::del(Event *ev)
{
    if ((::epoll_ctl(this->_epoll, EPOLL_CTL_DEL, ev->handle, nullptr) != 0) && (errno != ENOENT) && (errno != EBADF))
        throw std::system_error(sys::error(), "epoll: failed to delete event");
}

// run
void chen::reactor::run(double timeout)
{
    while (this->once(timeout))
        ;
}

bool chen::reactor::once(double timeout)
{
    // poll events
    ::epoll_event events[this->_count];  // VLA
    int result = ::epoll_wait(this->_epoll, events, this->_count, timeout < 0 ? -1 : static_cast<int>(timeout * 1000));

    if (result <= 0)
    {
        // EINTR maybe triggered by debugger, treat it as user request to stop
        if ((errno == EINTR) || !result)  // timeout if result is zero
            return false;
        else
            throw std::system_error(sys::error(), "epoll: failed to poll event");
    }

    // invoke callback
    for (int i = 0; i < result; ++i)
    {
        auto &item = events[i];

        // user request to stop
        if (item.data.ptr == &this->_wake)
        {
            ::eventfd_t dummy;
            ::eventfd_read(this->_wake.handle, &dummy);
            return false;
        }

        // check events, multiple events maybe occur
        auto ev = static_cast<Event*>(item.data.ptr);
        if (!ev->callback)
            continue;

        if ((item.events & EPOLLRDHUP) || (item.events & EPOLLERR) || (item.events & EPOLLHUP))
        {
            ev->callback(Type::Closed);
        }
        else
        {
            if (item.events & EPOLLIN)
                ev->callback(Type::Readable);

            if (item.events & EPOLLOUT)
                ev->callback(Type::Writable);
        }
    }

    return result > 0;
}

void chen::reactor::stop()
{
    // notify wake message via eventfd
    if (::eventfd_write(this->_wake.handle, 1) != 0)
        throw std::system_error(sys::error(), "epoll: failed to wake the epoll");
}

#endif<commit_msg>epoll: use std::function pointer, don't need to create a Event object<commit_after>/**
 * Created by Jian Chen
 * @since  2016.12.14
 * @author Jian Chen <admin@chensoft.com>
 * @link   http://chensoft.com
 */
#ifdef __linux__

#include <socket/core/reactor.hpp>
#include <chen/sys/sys.hpp>
#include <sys/eventfd.h>
#include <limits>

// -----------------------------------------------------------------------------
// reactor
const int chen::reactor::FlagEdge = EPOLLET;
const int chen::reactor::FlagOnce = EPOLLONESHOT;

chen::reactor::reactor(int count) : _count(count)
{
    // create epoll file descriptor
    // 1 is just a hint, see http://man7.org/linux/man-pages/man2/epoll_create.2.html
    if ((this->_epoll = ::epoll_create(1)) < 0)
        throw std::system_error(sys::error(), "epoll: failed to create epoll");

    // create eventfd to receive wake message
    this->_wake = ::eventfd(0, 0);

    if ((this->_wake < 0) || ::fcntl(this->_wake, F_SETFL, ::fcntl(this->_wake, F_GETFL, 0) | O_NONBLOCK))
    {
        ::close(this->_epoll);
        throw std::system_error(sys::error(), "epoll: failed to create eventfd");
    }

    this->set(this->_wake, nullptr, ModeRead, FlagEdge);
}

chen::reactor::~reactor()
{
    ::close(this->_epoll);
    ::close(this->_wake);
}

// modify
void chen::reactor::set(handle_t fd, callback *cb, int mode, int flag)
{
    ::epoll_event event{};

    if (mode & ModeRead)
        event.events |= EPOLLIN;

    if (mode & ModeWrite)
        event.events |= EPOLLOUT;

    event.events  |= flag | EPOLLRDHUP;
    event.data.ptr = cb;

    // register event
    if (::epoll_ctl(this->_epoll, EPOLL_CTL_MOD, fd, &event) != 0)
    {
        if ((errno != ENOENT) || (::epoll_ctl(this->_epoll, EPOLL_CTL_ADD, fd, &event) != 0))
            throw std::system_error(sys::error(), "epoll: failed to set event");
    }
}

void chen::reactor::del(handle_t fd)
{
    if ((::epoll_ctl(this->_epoll, EPOLL_CTL_DEL, fd, nullptr) != 0) && (errno != ENOENT) && (errno != EBADF))
        throw std::system_error(sys::error(), "epoll: failed to delete event");
}

// run
void chen::reactor::run(double timeout)
{
    while (this->once(timeout))
        ;
}

bool chen::reactor::once(double timeout)
{
    // poll events
    ::epoll_event events[this->_count];  // VLA
    int result = ::epoll_wait(this->_epoll, events, this->_count, timeout < 0 ? -1 : static_cast<int>(timeout * 1000));

    if (result <= 0)
    {
        // EINTR maybe triggered by debugger, treat it as user request to stop
        if ((errno == EINTR) || !result)  // timeout if result is zero
            return false;
        else
            throw std::system_error(sys::error(), "epoll: failed to poll event");
    }

    // invoke callback
    for (int i = 0; i < result; ++i)
    {
        auto &item = events[i];

        // user request to stop
        if (item.data.ptr == &this->_wake)
        {
            ::eventfd_t dummy;
            ::eventfd_read(this->_wake, &dummy);
            return false;
        }

        // check events, multiple events maybe occur
        auto cb = static_cast<callback*>(item.data.ptr);
        if (!cb)
            continue;

        if ((item.events & EPOLLRDHUP) || (item.events & EPOLLERR) || (item.events & EPOLLHUP))
        {
            (*cb)(Type::Closed);
        }
        else
        {
            if (item.events & EPOLLIN)
                (*cb)(Type::Readable);

            if (item.events & EPOLLOUT)
                (*cb)(Type::Writable);
        }
    }

    return result > 0;
}

void chen::reactor::stop()
{
    // notify wake message via eventfd
    if (::eventfd_write(this->_wake, 1) != 0)
        throw std::system_error(sys::error(), "epoll: failed to wake the epoll");
}

#endif<|endoftext|>


<commit_before>/*
 * Backtrace.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/Backtrace.hpp>

#ifndef _WIN32
# include <core/Algorithm.hpp>
# include <iostream>
# include <boost/regex.hpp>
# include <execinfo.h>
#endif

namespace rstudio {
namespace core {
namespace backtrace {

std::string demangle(const std::string& name)
{
   std::string result = name;

#ifndef _WIN32
   int status = -1;
   char* demangled = ::abi::__cxa_demangle(name.c_str(), NULL, NULL, &status);
   if (status == 0) {
      result = demangled;
      ::free(demangled);
   }
#endif

   return result;
}

void printBacktrace(std::ostream& os)
{
#ifndef _WIN32

   os << "Backtrace (most recent calls first):" << std::endl << std::endl;

   std::size_t maxDepth = 100;
   std::size_t stackDepth;

   void* stackAddrs[maxDepth];
   stackDepth = ::backtrace(stackAddrs, maxDepth);

   char** stackStrings;
   stackStrings = ::backtrace_symbols(stackAddrs, stackDepth);

   std::vector<std::string> demangled;
   demangled.reserve(stackDepth);

   // Each printed string will have output of the form:
   //
   //     (row) (program) (address) (function) + (offset)
   //
   // with variable numbers of spaces separating each field.
   std::string reBacktraceString = std::string() +
         "(\\d+)" +           // stack number
         "(\\s+)" +           // spaces
         "([^\\s]+)" +        // program name
         "(\\s+)" +           // spaces
         "([^\\s]+)" +        // address
         "(\\s+)" +           // spaces
         "([^\\s]+)" +        // (mangled) function name
         "(.*)";              // offset (the rest)

   boost::regex reBacktrace(reBacktraceString);
   boost::cmatch match;

   for (std::size_t i = 0; i < stackDepth; ++i)
   {
      std::string readyForPrinting = stackStrings[i];
      if (boost::regex_match(stackStrings[i], match, reBacktrace))
      {
         std::size_t n = match.length();
         if (n >= 8)
         {
            std::string demangled = demangle(match[7]);

            std::string joined;
            for (std::size_t i = 1; i < 7; ++i)
               joined += match[i];

            joined += demangled;
            if (n > 8)
               joined += match[8];

            readyForPrinting = joined;
         }
      }
      os << readyForPrinting << std::endl;
   }

   if (stackStrings != NULL)
      ::free(stackStrings);

#endif
}

} // namespace debug
} // namespace core
} // namespace rstudio
<commit_msg>include '<cxxabi.h>' (needed for non-OS X platforms)<commit_after>/*
 * Backtrace.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/Backtrace.hpp>

#ifndef _WIN32
# include <core/Algorithm.hpp>
# include <iostream>
# include <boost/regex.hpp>
# include <execinfo.h>
# include <cxxabi.h>
#endif

namespace rstudio {
namespace core {
namespace backtrace {

std::string demangle(const std::string& name)
{
   std::string result = name;

#ifndef _WIN32
   int status = -1;
   char* demangled = ::abi::__cxa_demangle(name.c_str(), NULL, NULL, &status);
   if (status == 0) {
      result = demangled;
      ::free(demangled);
   }
#endif

   return result;
}

void printBacktrace(std::ostream& os)
{
#ifndef _WIN32

   os << "Backtrace (most recent calls first):" << std::endl << std::endl;

   std::size_t maxDepth = 100;
   std::size_t stackDepth;

   void* stackAddrs[maxDepth];
   stackDepth = ::backtrace(stackAddrs, maxDepth);

   char** stackStrings;
   stackStrings = ::backtrace_symbols(stackAddrs, stackDepth);

   std::vector<std::string> demangled;
   demangled.reserve(stackDepth);

   // Each printed string will have output of the form:
   //
   //     (row) (program) (address) (function) + (offset)
   //
   // with variable numbers of spaces separating each field.
   std::string reBacktraceString = std::string() +
         "(\\d+)" +           // stack number
         "(\\s+)" +           // spaces
         "([^\\s]+)" +        // program name
         "(\\s+)" +           // spaces
         "([^\\s]+)" +        // address
         "(\\s+)" +           // spaces
         "([^\\s]+)" +        // (mangled) function name
         "(.*)";              // offset (the rest)

   boost::regex reBacktrace(reBacktraceString);
   boost::cmatch match;

   for (std::size_t i = 0; i < stackDepth; ++i)
   {
      std::string readyForPrinting = stackStrings[i];
      if (boost::regex_match(stackStrings[i], match, reBacktrace))
      {
         std::size_t n = match.length();
         if (n >= 8)
         {
            std::string demangled = demangle(match[7]);

            std::string joined;
            for (std::size_t i = 1; i < 7; ++i)
               joined += match[i];

            joined += demangled;
            if (n > 8)
               joined += match[8];

            readyForPrinting = joined;
         }
      }
      os << readyForPrinting << std::endl;
   }

   if (stackStrings != NULL)
      ::free(stackStrings);

#endif
}

} // namespace debug
} // namespace core
} // namespace rstudio
<|endoftext|>


<commit_before>/*
 * Copyright © 2017 Collabora Ltd.
 *
 * This file is part of vkmark.
 *
 * vkmark is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * vkmark is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with vkmark. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *   Alexandros Frantzis <alexandros.frantzis@collabora.com>
 */

#include "default_benchmarks.h"

std::vector<std::string> DefaultBenchmarks::get()
{
    return std::vector<std::string>{
        "vertex:device-local=true",
        "vertex:device-local=false",
        "shading:shading=gouraud",
        "shading:shading=blinn-phong-inf",
        "shading:shading=phong",
        "shading:shading=cel",
        "cube",
        "clear"
    };
}
<commit_msg>main: Add texture scene variants to default benchmarks<commit_after>/*
 * Copyright © 2017 Collabora Ltd.
 *
 * This file is part of vkmark.
 *
 * vkmark is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * vkmark is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with vkmark. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *   Alexandros Frantzis <alexandros.frantzis@collabora.com>
 */

#include "default_benchmarks.h"

std::vector<std::string> DefaultBenchmarks::get()
{
    return std::vector<std::string>{
        "vertex:device-local=true",
        "vertex:device-local=false",
        "texture:anisotropy=0",
        "texture:anisotropy=16",
        "shading:shading=gouraud",
        "shading:shading=blinn-phong-inf",
        "shading:shading=phong",
        "shading:shading=cel",
        "cube",
        "clear"
    };
}
<|endoftext|>


<commit_before>/*
Dwarf Therapist
Copyright (c) 2009 Trey Stout (chmod)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "gridviewdock.h"
#include "ui_gridviewdock.h"
#include "viewmanager.h"
#include "gridview.h"
#include "gridviewdialog.h"
#include "truncatingfilelogger.h"

GridViewDock::GridViewDock(ViewManager *mgr, QWidget *parent,
                           Qt::WindowFlags flags)
    : QDockWidget(parent, flags)
    , m_manager(mgr)
    , ui(new Ui::GridViewDock)
    , m_tmp_item(0)
{
    ui->setupUi(this);
    setFeatures(QDockWidget::AllDockWidgetFeatures);
    setAllowedAreas(Qt::AllDockWidgetAreas);
    draw_views();

    connect(ui->list_views, SIGNAL(itemActivated(QListWidgetItem*)),
            SLOT(edit_view(QListWidgetItem*)));
    connect(ui->list_views, SIGNAL(customContextMenuRequested(const QPoint &)),
            SLOT(draw_list_context_menu(const QPoint &)));
    connect(ui->btn_add, SIGNAL(clicked()), this, SLOT(add_new_view()));
}

void GridViewDock::draw_views() {
    ui->list_views->clear();
    QStringList view_names;
    foreach(GridView *v, m_manager->views()) {
        view_names << v->name();
    }
    qSort(view_names);
    foreach(QString name, view_names) {
        foreach(GridView *v, m_manager->views()) {
            if (v->name() == name) {
                QListWidgetItem *item = new QListWidgetItem(v->name(),
                                                            ui->list_views);
                if (!v->is_custom()) {
                    item->setForeground(Qt::gray);
                    item->setToolTip(tr("Built-in View. Copy this view to "
                                        "customize it."));
                }
            }
        }
    }
}

void GridViewDock::draw_list_context_menu(const QPoint &pos) {
    m_tmp_item = ui->list_views->itemAt(pos);
    GridView *gv = m_manager->get_view(m_tmp_item->text());
    QMenu m(this);
    if (gv) {
        if (gv->is_custom())
            m.addAction(QIcon(":/img/application_edit.png"), tr("Edit..."),
                        this, SLOT(edit_view()));
        m.addAction(QIcon(":/img/page_copy.png"), tr("Copy..."),
                    this, SLOT(copy_view()));
        if (gv->is_custom()) {
            m.addAction(QIcon(":/img/table_delete.png"), tr("Delete..."),
                        this, SLOT(delete_view()));
        }
    } else { // whitespace
        m.addAction(QIcon(":img/table_add.png"), tr("Add New GridView"),
                    this, SLOT(add_new_view()));
    }
    m.exec(ui->list_views->mapToGlobal(pos));
}

void GridViewDock::add_new_view() {
    GridView *view = new GridView("", m_manager);
    GridViewDialog *d = new GridViewDialog(m_manager, view, this);
    int accepted = d->exec();
    if (accepted == QDialog::Accepted) {
        GridView *new_view = d->pending_view();
        new_view->set_active(false);
        m_manager->add_view(new_view);
        draw_views();
    }
}

void GridViewDock::edit_view(QListWidgetItem *item) {
    m_tmp_item = item;
    edit_view();
}

void GridViewDock::edit_view() {
    if (!m_tmp_item)
        return;

    GridView *view = m_manager->get_view(m_tmp_item->text());
    if (!view)
        return;
    if (!view->is_custom()) {
        return; // can't edit non-custom views
    }
    GridViewDialog *d = new GridViewDialog(m_manager, view, this);
    int accepted = d->exec();
    if (accepted == QDialog::Accepted) {
        m_manager->replace_view(view, d->pending_view());
        draw_views();
    }
    m_tmp_item = 0;
}

void GridViewDock::copy_view() {
    if (!m_tmp_item)
        return;

    GridView *view = m_manager->get_view(m_tmp_item->text());
    if (!view)
        return;

    GridView *copy = new GridView(*view);
    copy->set_is_custom(true); // all copies are custom
    copy->set_name(view->name() + "(COPY)");
    m_manager->add_view(copy);
    m_manager->write_views();
    draw_views();
    m_tmp_item = 0;
}

void GridViewDock::delete_view() {
    if (!m_tmp_item)
        return;
    GridView *view = m_manager->get_view(m_tmp_item->text());
    if (!view)
        return;

    int answer = QMessageBox::question(
        0, tr("Delete View"),
        tr("Deleting '%1' will permanently delete it from disk.
Really "
           "delete '%1'?

There is no undo!
").arg(view->name()),
        QMessageBox::Yes | QMessageBox::No);
    if (answer == QMessageBox::Yes) {
        LOGI << "permanently deleting set" << view->name();
        m_manager->remove_view(view);
        draw_views();
        view->deleteLater();
    }
    m_tmp_item = 0;
}
<commit_msg> * Fixed crash on right click in grid views dock (Fixes issue 219)<commit_after>/*
Dwarf Therapist
Copyright (c) 2009 Trey Stout (chmod)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "gridviewdock.h"
#include "ui_gridviewdock.h"
#include "viewmanager.h"
#include "gridview.h"
#include "gridviewdialog.h"
#include "truncatingfilelogger.h"

GridViewDock::GridViewDock(ViewManager *mgr, QWidget *parent,
                           Qt::WindowFlags flags)
    : QDockWidget(parent, flags)
    , m_manager(mgr)
    , ui(new Ui::GridViewDock)
    , m_tmp_item(0)
{
    ui->setupUi(this);
    setFeatures(QDockWidget::AllDockWidgetFeatures);
    setAllowedAreas(Qt::AllDockWidgetAreas);
    draw_views();

    connect(ui->list_views, SIGNAL(itemActivated(QListWidgetItem*)),
            SLOT(edit_view(QListWidgetItem*)));
    connect(ui->list_views, SIGNAL(customContextMenuRequested(const QPoint &)),
            SLOT(draw_list_context_menu(const QPoint &)));
    connect(ui->btn_add, SIGNAL(clicked()), this, SLOT(add_new_view()));
}

void GridViewDock::draw_views() {
    ui->list_views->clear();
    QStringList view_names;
    foreach(GridView *v, m_manager->views()) {
        view_names << v->name();
    }
    qSort(view_names);
    foreach(QString name, view_names) {
        foreach(GridView *v, m_manager->views()) {
            if (v->name() == name) {
                QListWidgetItem *item = new QListWidgetItem(v->name(),
                                                            ui->list_views);
                if (!v->is_custom()) {
                    item->setForeground(Qt::gray);
                    item->setToolTip(tr("Built-in View. Copy this view to "
                                        "customize it."));
                }
            }
        }
    }
}

void GridViewDock::draw_list_context_menu(const QPoint &pos) {
    m_tmp_item = ui->list_views->itemAt(pos);
    QString item_text;
    if (m_tmp_item)
        item_text = m_tmp_item->text();
    GridView *gv = m_manager->get_view(item_text);
    QMenu m(this);
    if (gv) {
        if (gv->is_custom())
            m.addAction(QIcon(":/img/application_edit.png"), tr("Edit..."),
                        this, SLOT(edit_view()));
        m.addAction(QIcon(":/img/page_copy.png"), tr("Copy..."),
                    this, SLOT(copy_view()));
        if (gv->is_custom()) {
            m.addAction(QIcon(":/img/table_delete.png"), tr("Delete..."),
                        this, SLOT(delete_view()));
        }
    } else { // whitespace
        m.addAction(QIcon(":img/table_add.png"), tr("Add New GridView"),
                    this, SLOT(add_new_view()));
    }
    m.exec(ui->list_views->mapToGlobal(pos));
}

void GridViewDock::add_new_view() {
    GridView *view = new GridView("", m_manager);
    GridViewDialog *d = new GridViewDialog(m_manager, view, this);
    int accepted = d->exec();
    if (accepted == QDialog::Accepted) {
        GridView *new_view = d->pending_view();
        new_view->set_active(false);
        m_manager->add_view(new_view);
        draw_views();
    }
}

void GridViewDock::edit_view(QListWidgetItem *item) {
    m_tmp_item = item;
    edit_view();
}

void GridViewDock::edit_view() {
    if (!m_tmp_item)
        return;

    GridView *view = m_manager->get_view(m_tmp_item->text());
    if (!view)
        return;
    if (!view->is_custom()) {
        return; // can't edit non-custom views
    }
    GridViewDialog *d = new GridViewDialog(m_manager, view, this);
    int accepted = d->exec();
    if (accepted == QDialog::Accepted) {
        m_manager->replace_view(view, d->pending_view());
        draw_views();
    }
    m_tmp_item = 0;
}

void GridViewDock::copy_view() {
    if (!m_tmp_item)
        return;

    GridView *view = m_manager->get_view(m_tmp_item->text());
    if (!view)
        return;

    GridView *copy = new GridView(*view);
    copy->set_is_custom(true); // all copies are custom
    copy->set_name(view->name() + "(COPY)");
    m_manager->add_view(copy);
    m_manager->write_views();
    draw_views();
    m_tmp_item = 0;
}

void GridViewDock::delete_view() {
    if (!m_tmp_item)
        return;
    GridView *view = m_manager->get_view(m_tmp_item->text());
    if (!view)
        return;

    int answer = QMessageBox::question(
        0, tr("Delete View"),
        tr("Deleting '%1' will permanently delete it from disk.
Really "
           "delete '%1'?

There is no undo!
").arg(view->name()),
        QMessageBox::Yes | QMessageBox::No);
    if (answer == QMessageBox::Yes) {
        LOGI << "permanently deleting set" << view->name();
        m_manager->remove_view(view);
        draw_views();
        view->deleteLater();
    }
    m_tmp_item = 0;
}
<|endoftext|>


<commit_before>#include "drivers/lsm303dlhc.hpp"

#include <algorithm>
#include <array>
#include <cstddef>

void LSM303DLHC::init() {
  // Wake up device and enable X, Y, and Z outputs.
  writeRegister(LSM303_I2C_AD_CTRL_REG1_A, (1 << 7) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0));
}

accelerometer_reading_t LSM303DLHC::readAccel() {
  std::fill(std::begin(txbuf), std::end(txbuf), 0);
  txbuf[0] = LSM303_I2C_AD_OUT_X_L_A | 0x80;

  exchange(1, 6);

  // Swapped for board orientation
  std::array<std::int16_t, 3> raw;
  raw[0] = -((rxbuf[1] << 8) | rxbuf[0]);
  raw[1] = -((rxbuf[3] << 8) | rxbuf[2]);
  raw[2] = -((rxbuf[5] << 8) | rxbuf[4]);

  accelerometer_reading_t reading;

  for(std::size_t i = 0; i < 3; i++) {
    // TODO: Scale to m/s^2
    reading.axes[i] = (float) raw[i];
  }

  return reading;
}

uint8_t LSM303DLHC::readRegister(uint8_t reg) {
  std::fill(std::begin(txbuf), std::end(txbuf), 0);
  txbuf[0] = reg;

  exchange(1, 1);

  return rxbuf[0];
}

void LSM303DLHC::writeRegister(uint8_t reg, uint8_t val) {
  std::fill(std::begin(txbuf), std::end(txbuf), 0);
  txbuf[0] = reg;
  txbuf[1] = val;

  exchange(2, 0);
}
<commit_msg>Don't bother clearing I2CDevice buffer every transmission.<commit_after>#include "drivers/lsm303dlhc.hpp"

#include <algorithm>
#include <array>
#include <cstddef>

void LSM303DLHC::init() {
  // Wake up device and enable X, Y, and Z outputs.
  writeRegister(LSM303_I2C_AD_CTRL_REG1_A, (1 << 7) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0));
}

accelerometer_reading_t LSM303DLHC::readAccel() {
  txbuf[0] = LSM303_I2C_AD_OUT_X_L_A | 0x80;

  exchange(1, 6);

  // Swapped for board orientation
  std::array<std::int16_t, 3> raw;
  raw[0] = -((rxbuf[1] << 8) | rxbuf[0]);
  raw[1] = -((rxbuf[3] << 8) | rxbuf[2]);
  raw[2] = -((rxbuf[5] << 8) | rxbuf[4]);

  accelerometer_reading_t reading;

  for(std::size_t i = 0; i < 3; i++) {
    // TODO: Scale to m/s^2
    reading.axes[i] = (float) raw[i];
  }

  return reading;
}

uint8_t LSM303DLHC::readRegister(uint8_t reg) {
  txbuf[0] = reg;

  exchange(1, 1);

  return rxbuf[0];
}

void LSM303DLHC::writeRegister(uint8_t reg, uint8_t val) {
  txbuf[0] = reg;
  txbuf[1] = val;

  exchange(2, 0);
}
<|endoftext|>


<commit_before>//===- DomPrinter.cpp - DOT printer for the dominance trees    ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
// program, with a graph of the dominance/postdominance tree of that
// function.
//
// There are also passes available to directly call dotty ('-view-dom' or
// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
// names of the bbs are printed, but the content is hidden.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DomPrinter.h"

#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/DOTGraphTraitsPass.h"
#include "llvm/Analysis/PostDominators.h"

using namespace llvm;

namespace llvm {
template<>
struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {

  DOTGraphTraits (bool isSimple=false)
    : DefaultDOTGraphTraits(isSimple) {}

  std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {

    BasicBlock *BB = Node->getBlock();

    if (!BB)
      return "Post dominance root node";

    if (isSimple())
      return DOTGraphTraits<const Function*>
	       ::getSimpleNodeLabel(BB, BB->getParent());
    else
      return DOTGraphTraits<const Function*>
	       ::getCompleteNodeLabel(BB, BB->getParent());
  }
};

template<>
struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {

  DOTGraphTraits (bool isSimple=false)
    : DOTGraphTraits<DomTreeNode*>(isSimple) {}

  static std::string getGraphName(DominatorTree *DT) {
    return "Dominator tree";
  }

  std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
  }
};

template<>
struct DOTGraphTraits<PostDominatorTree*>
  : public DOTGraphTraits<DomTreeNode*> {

  DOTGraphTraits (bool isSimple=false)
    : DOTGraphTraits<DomTreeNode*>(isSimple) {}

  static std::string getGraphName(PostDominatorTree *DT) {
    return "Post dominator tree";
  }

  std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
  }
};
}

namespace {
template <class Analysis, bool OnlyBBS>
struct GenericGraphViewer : public FunctionPass {
  std::string Name;

  GenericGraphViewer(std::string GraphName, const void *ID) : FunctionPass(ID) {
    Name = GraphName;
  }

  virtual bool runOnFunction(Function &F) {
    Analysis *Graph;
    std::string Title, GraphName;
    Graph = &getAnalysis<Analysis>();
    GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
    Title = GraphName + " for '" + F.getNameStr() + "' function";
    ViewGraph(Graph, Name, OnlyBBS, Title);

    return false;
  }

  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    AU.setPreservesAll();
    AU.addRequired<Analysis>();
  }
};

struct DomViewer
  : public DOTGraphTraitsViewer<DominatorTree, false> {
  static char ID;
  DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", &ID){}
};

struct DomOnlyViewer
  : public DOTGraphTraitsViewer<DominatorTree, true> {
  static char ID;
  DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", &ID){}
};

struct PostDomViewer
  : public DOTGraphTraitsViewer<PostDominatorTree, false> {
  static char ID;
  PostDomViewer() :
    DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", &ID){}
};

struct PostDomOnlyViewer
  : public DOTGraphTraitsViewer<PostDominatorTree, true> {
  static char ID;
  PostDomOnlyViewer() :
    DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", &ID){}
};
} // end anonymous namespace

char DomViewer::ID = 0;
RegisterPass<DomViewer> A("view-dom",
                          "View dominance tree of function");

char DomOnlyViewer::ID = 0;
RegisterPass<DomOnlyViewer> B("view-dom-only",
                              "View dominance tree of function "
                              "(with no function bodies)");

char PostDomViewer::ID = 0;
RegisterPass<PostDomViewer> C("view-postdom",
                              "View postdominance tree of function");

char PostDomOnlyViewer::ID = 0;
RegisterPass<PostDomOnlyViewer> D("view-postdom-only",
                                  "View postdominance tree of function "
                                  "(with no function bodies)");

namespace {
struct DomPrinter
  : public DOTGraphTraitsPrinter<DominatorTree, false> {
  static char ID;
  DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", &ID) {}
};

struct DomOnlyPrinter
  : public DOTGraphTraitsPrinter<DominatorTree, true> {
  static char ID;
  DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", &ID) {}
};

struct PostDomPrinter
  : public DOTGraphTraitsPrinter<PostDominatorTree, false> {
  static char ID;
  PostDomPrinter() :
    DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", &ID) {}
};

struct PostDomOnlyPrinter
  : public DOTGraphTraitsPrinter<PostDominatorTree, true> {
  static char ID;
  PostDomOnlyPrinter() :
    DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", &ID) {}
};
} // end anonymous namespace

char DomPrinter::ID = 0;
RegisterPass<DomPrinter> E("dot-dom",
                           "Print dominance tree of function "
                           "to 'dot' file");

char DomOnlyPrinter::ID = 0;
RegisterPass<DomOnlyPrinter> F("dot-dom-only",
                               "Print dominance tree of function "
                               "to 'dot' file "
                               "(with no function bodies)");

char PostDomPrinter::ID = 0;
RegisterPass<PostDomPrinter> G("dot-postdom",
                               "Print postdominance tree of function "
                               "to 'dot' file");

char PostDomOnlyPrinter::ID = 0;
RegisterPass<PostDomOnlyPrinter> H("dot-postdom-only",
                                   "Print postdominance tree of function "
                                   "to 'dot' file "
                                   "(with no function bodies)");

// Create methods available outside of this file, to use them
// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
// the link time optimization.

FunctionPass *llvm::createDomPrinterPass() {
  return new DomPrinter();
}

FunctionPass *llvm::createDomOnlyPrinterPass() {
  return new DomOnlyPrinter();
}

FunctionPass *llvm::createDomViewerPass() {
  return new DomViewer();
}

FunctionPass *llvm::createDomOnlyViewerPass() {
  return new DomOnlyViewer();
}

FunctionPass *llvm::createPostDomPrinterPass() {
  return new PostDomPrinter();
}

FunctionPass *llvm::createPostDomOnlyPrinterPass() {
  return new PostDomOnlyPrinter();
}

FunctionPass *llvm::createPostDomViewerPass() {
  return new PostDomViewer();
}

FunctionPass *llvm::createPostDomOnlyViewerPass() {
  return new PostDomOnlyViewer();
}
<commit_msg>Remove dead code in the dotty dominance tree printer.<commit_after>//===- DomPrinter.cpp - DOT printer for the dominance trees    ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
// program, with a graph of the dominance/postdominance tree of that
// function.
//
// There are also passes available to directly call dotty ('-view-dom' or
// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
// names of the bbs are printed, but the content is hidden.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DomPrinter.h"

#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/DOTGraphTraitsPass.h"
#include "llvm/Analysis/PostDominators.h"

using namespace llvm;

namespace llvm {
template<>
struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {

  DOTGraphTraits (bool isSimple=false)
    : DefaultDOTGraphTraits(isSimple) {}

  std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {

    BasicBlock *BB = Node->getBlock();

    if (!BB)
      return "Post dominance root node";

    if (isSimple())
      return DOTGraphTraits<const Function*>
	       ::getSimpleNodeLabel(BB, BB->getParent());
    else
      return DOTGraphTraits<const Function*>
	       ::getCompleteNodeLabel(BB, BB->getParent());
  }
};

template<>
struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {

  DOTGraphTraits (bool isSimple=false)
    : DOTGraphTraits<DomTreeNode*>(isSimple) {}

  static std::string getGraphName(DominatorTree *DT) {
    return "Dominator tree";
  }

  std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
  }
};

template<>
struct DOTGraphTraits<PostDominatorTree*>
  : public DOTGraphTraits<DomTreeNode*> {

  DOTGraphTraits (bool isSimple=false)
    : DOTGraphTraits<DomTreeNode*>(isSimple) {}

  static std::string getGraphName(PostDominatorTree *DT) {
    return "Post dominator tree";
  }

  std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
  }
};
}

namespace {
struct DomViewer
  : public DOTGraphTraitsViewer<DominatorTree, false> {
  static char ID;
  DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", &ID){}
};

struct DomOnlyViewer
  : public DOTGraphTraitsViewer<DominatorTree, true> {
  static char ID;
  DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", &ID){}
};

struct PostDomViewer
  : public DOTGraphTraitsViewer<PostDominatorTree, false> {
  static char ID;
  PostDomViewer() :
    DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", &ID){}
};

struct PostDomOnlyViewer
  : public DOTGraphTraitsViewer<PostDominatorTree, true> {
  static char ID;
  PostDomOnlyViewer() :
    DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", &ID){}
};
} // end anonymous namespace

char DomViewer::ID = 0;
RegisterPass<DomViewer> A("view-dom",
                          "View dominance tree of function");

char DomOnlyViewer::ID = 0;
RegisterPass<DomOnlyViewer> B("view-dom-only",
                              "View dominance tree of function "
                              "(with no function bodies)");

char PostDomViewer::ID = 0;
RegisterPass<PostDomViewer> C("view-postdom",
                              "View postdominance tree of function");

char PostDomOnlyViewer::ID = 0;
RegisterPass<PostDomOnlyViewer> D("view-postdom-only",
                                  "View postdominance tree of function "
                                  "(with no function bodies)");

namespace {
struct DomPrinter
  : public DOTGraphTraitsPrinter<DominatorTree, false> {
  static char ID;
  DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", &ID) {}
};

struct DomOnlyPrinter
  : public DOTGraphTraitsPrinter<DominatorTree, true> {
  static char ID;
  DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", &ID) {}
};

struct PostDomPrinter
  : public DOTGraphTraitsPrinter<PostDominatorTree, false> {
  static char ID;
  PostDomPrinter() :
    DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", &ID) {}
};

struct PostDomOnlyPrinter
  : public DOTGraphTraitsPrinter<PostDominatorTree, true> {
  static char ID;
  PostDomOnlyPrinter() :
    DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", &ID) {}
};
} // end anonymous namespace

char DomPrinter::ID = 0;
RegisterPass<DomPrinter> E("dot-dom",
                           "Print dominance tree of function "
                           "to 'dot' file");

char DomOnlyPrinter::ID = 0;
RegisterPass<DomOnlyPrinter> F("dot-dom-only",
                               "Print dominance tree of function "
                               "to 'dot' file "
                               "(with no function bodies)");

char PostDomPrinter::ID = 0;
RegisterPass<PostDomPrinter> G("dot-postdom",
                               "Print postdominance tree of function "
                               "to 'dot' file");

char PostDomOnlyPrinter::ID = 0;
RegisterPass<PostDomOnlyPrinter> H("dot-postdom-only",
                                   "Print postdominance tree of function "
                                   "to 'dot' file "
                                   "(with no function bodies)");

// Create methods available outside of this file, to use them
// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
// the link time optimization.

FunctionPass *llvm::createDomPrinterPass() {
  return new DomPrinter();
}

FunctionPass *llvm::createDomOnlyPrinterPass() {
  return new DomOnlyPrinter();
}

FunctionPass *llvm::createDomViewerPass() {
  return new DomViewer();
}

FunctionPass *llvm::createDomOnlyViewerPass() {
  return new DomOnlyViewer();
}

FunctionPass *llvm::createPostDomPrinterPass() {
  return new PostDomPrinter();
}

FunctionPass *llvm::createPostDomOnlyPrinterPass() {
  return new PostDomOnlyPrinter();
}

FunctionPass *llvm::createPostDomViewerPass() {
  return new PostDomViewer();
}

FunctionPass *llvm::createPostDomOnlyViewerPass() {
  return new PostDomOnlyViewer();
}
<|endoftext|>