<commit_before>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>

#include "Command.h"
#include "DynamicKomi.h"
#include "GoBoard.h"
#include "Gtp.h"
#include "Message.h"
#include "UctSearch.h"
#include "ZobristHash.h"

using namespace std;

const string command[COMMAND_MAX] = {
  "--playout",
  "--time",
  "--size",
  "--const-time",
  "--thread",
  "--komi",
  "--handicap",
  "--reuse-subtree",
  "--pondering",
  "--tree-size",
  "--no-debug",
  "--sim-move",
  "--no-early-pass",
  "--no-nn",
  "--no-gpu",
};

const string errmessage[COMMAND_MAX] = {
  "Set playouts",
  "Set all thinking time",
  "Set board size",
  "Set mode const time, and set thinking time per move",
  "Set threads",
  "Set komi",
  "Set the number of handicap stones (for testing)",
  "Reuse subtree",
  "Set pondering mode",
  "Set tree size (tree size must be 2 ^ n)",
  "Prohibit any debug message",
  "Play simulation move",
  "No early pass",
  "Don't use NN",
  "Don't use GPU",
};

//////////////////////
//  R}h̏  //
//////////////////////
void
AnalyzeCommand( int argc, char **argv )
{
  int i, j, n, size;

  for (i = 1; i < argc; i++){
    n = COMMAND_MAX + 1;
    for (j = 0; j < COMMAND_MAX; j++){
      if (!strcmp(argv[i], command[j].c_str())){
	n = j;
      }
    }

    switch (n) {
      case COMMAND_PLAYOUT:
	SetPlayout(atoi(argv[++i]));
	SetMode(CONST_PLAYOUT_MODE);
	break;
      case COMMAND_TIME:
	SetTime(atof(argv[++i]));
	SetMode(TIME_SETTING_MODE);
	break;
      case COMMAND_SIZE:
	i++;
	size = atoi(argv[i]);
	if (pure_board_size != size &&
	    size > 0 && size <= PURE_BOARD_SIZE) {
	  SetBoardSize(size);
	  SetParameter();
	}
	break;
      case COMMAND_CONST_TIME:
	SetMode(CONST_TIME_MODE);
	SetConstTime(atof(argv[++i]));
	break;
      case COMMAND_THREAD:
	SetThread(atoi(argv[++i]));
	break;
      case COMMAND_KOMI:
	SetKomi(atof(argv[++i]));
	break;
      case COMMAND_HANDICAP:
	SetConstHandicapNum(atoi(argv[++i]));
	SetHandicapNum(0);
	break;
      case COMMAND_REUSE_SUBTREE:
        SetReuseSubtree(true);
        break;
      case COMMAND_PONDERING :
	SetReuseSubtree(true);
	SetPonderingMode(true);
	break;
      case COMMAND_TREE_SIZE:
	SetHashSize((unsigned int)atoi(argv[++i]));
	break;
      case COMMAND_NO_DEBUG:
        SetDebugMessageMode(false);
        break;
      case COMMAND_SIM_MOVE:
	SetSimMove(true);
      case COMMAND_NO_EARLY_PASS:
	SetEarlyPass(false);
	break;
      case COMMAND_NO_NN:
	SetUseNN(false);
	break;
      case COMMAND_NO_GPU:
	SetUseGPU(false);
	break;
      default:
	for (j = 0; j < COMMAND_MAX; j++){
	  fprintf(stderr, "%-22s : %s\n", command[j].c_str(), errmessage[j].c_str());
	}
	exit(1);
    }
  }

}
<commit_msg>Fix --sim-move enables --no-ealry-pass<commit_after>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>

#include "Command.h"
#include "DynamicKomi.h"
#include "GoBoard.h"
#include "Gtp.h"
#include "Message.h"
#include "UctSearch.h"
#include "ZobristHash.h"

using namespace std;

const string command[COMMAND_MAX] = {
  "--playout",
  "--time",
  "--size",
  "--const-time",
  "--thread",
  "--komi",
  "--handicap",
  "--reuse-subtree",
  "--pondering",
  "--tree-size",
  "--no-debug",
  "--sim-move",
  "--no-early-pass",
  "--no-nn",
  "--no-gpu",
};

const string errmessage[COMMAND_MAX] = {
  "Set playouts",
  "Set all thinking time",
  "Set board size",
  "Set mode const time, and set thinking time per move",
  "Set threads",
  "Set komi",
  "Set the number of handicap stones (for testing)",
  "Reuse subtree",
  "Set pondering mode",
  "Set tree size (tree size must be 2 ^ n)",
  "Prohibit any debug message",
  "Play simulation move",
  "No early pass",
  "Don't use NN",
  "Don't use GPU",
};

//////////////////////
//  R}h̏  //
//////////////////////
void
AnalyzeCommand( int argc, char **argv )
{
  int i, j, n, size;

  for (i = 1; i < argc; i++){
    n = COMMAND_MAX + 1;
    for (j = 0; j < COMMAND_MAX; j++){
      if (!strcmp(argv[i], command[j].c_str())){
	n = j;
      }
    }

    switch (n) {
      case COMMAND_PLAYOUT:
	SetPlayout(atoi(argv[++i]));
	SetMode(CONST_PLAYOUT_MODE);
	break;
      case COMMAND_TIME:
	SetTime(atof(argv[++i]));
	SetMode(TIME_SETTING_MODE);
	break;
      case COMMAND_SIZE:
	i++;
	size = atoi(argv[i]);
	if (pure_board_size != size &&
	    size > 0 && size <= PURE_BOARD_SIZE) {
	  SetBoardSize(size);
	  SetParameter();
	}
	break;
      case COMMAND_CONST_TIME:
	SetMode(CONST_TIME_MODE);
	SetConstTime(atof(argv[++i]));
	break;
      case COMMAND_THREAD:
	SetThread(atoi(argv[++i]));
	break;
      case COMMAND_KOMI:
	SetKomi(atof(argv[++i]));
	break;
      case COMMAND_HANDICAP:
	SetConstHandicapNum(atoi(argv[++i]));
	SetHandicapNum(0);
	break;
      case COMMAND_REUSE_SUBTREE:
        SetReuseSubtree(true);
        break;
      case COMMAND_PONDERING :
	SetReuseSubtree(true);
	SetPonderingMode(true);
	break;
      case COMMAND_TREE_SIZE:
	SetHashSize((unsigned int)atoi(argv[++i]));
	break;
      case COMMAND_NO_DEBUG:
        SetDebugMessageMode(false);
        break;
      case COMMAND_SIM_MOVE:
	SetSimMove(true);
        break;
      case COMMAND_NO_EARLY_PASS:
	SetEarlyPass(false);
	break;
      case COMMAND_NO_NN:
	SetUseNN(false);
	break;
      case COMMAND_NO_GPU:
	SetUseGPU(false);
	break;
      default:
	for (j = 0; j < COMMAND_MAX; j++){
	  fprintf(stderr, "%-22s : %s\n", command[j].c_str(), errmessage[j].c_str());
	}
	exit(1);
    }
  }

}
<|endoftext|>


<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include "default_tensor_engine.h"
#include <vespa/vespalib/eval/value.h>
#include <vespa/vespalib/eval/tensor_spec.h>
#include <vespa/vespalib/eval/operation_visitor.h>
#include "tensor.h"
#include "dense/dense_tensor_builder.h"
#include "dense/dense_tensor_function_compiler.h"
#include "default_tensor.h"

namespace vespalib {
namespace tensor {

using ErrorValue = eval::ErrorValue;
using DoubleValue = eval::DoubleValue;
using TensorValue = eval::TensorValue;

const DefaultTensorEngine DefaultTensorEngine::_engine;

eval::ValueType
DefaultTensorEngine::type_of(const Tensor &tensor) const
{
    assert(&tensor.engine() == this);
    const tensor::Tensor &my_tensor = static_cast<const tensor::Tensor &>(tensor);
    return my_tensor.getType();
}

bool
DefaultTensorEngine::equal(const Tensor &a, const Tensor &b) const
{
    assert(&a.engine() == this);
    assert(&b.engine() == this);
    const tensor::Tensor &my_a = static_cast<const tensor::Tensor &>(a);
    const tensor::Tensor &my_b = static_cast<const tensor::Tensor &>(b);
    if (my_a.getType().type() != my_b.getType().type()) {
        return false;
    }
    return my_a.equals(my_b);
}

vespalib::string
DefaultTensorEngine::to_string(const Tensor &tensor) const
{
    assert(&tensor.engine() == this);
    const tensor::Tensor &my_tensor = static_cast<const tensor::Tensor &>(tensor);
    return my_tensor.toString();
}

eval::TensorSpec
DefaultTensorEngine::to_spec(const Tensor &tensor) const
{
    assert(&tensor.engine() == this);
    const tensor::Tensor &my_tensor = static_cast<const tensor::Tensor &>(tensor);
    return my_tensor.toSpec();
}

eval::TensorFunction::UP
DefaultTensorEngine::compile(eval::tensor_function::Node_UP expr)
{
    return DenseTensorFunctionCompiler::compile(std::move(expr));
}

struct IsAddOperation : public eval::DefaultOperationVisitor {
    bool result = false;
    void visitDefault(const eval::Operation &) override {}
    void visit(const eval::operation::Add &) override { result = true; }
};

std::unique_ptr<eval::Tensor>
DefaultTensorEngine::create(const TensorSpec &spec) const
{
    ValueType type = ValueType::from_spec(spec.type());
    bool is_dense = false;
    bool is_sparse = false;
    for (const auto &dimension: type.dimensions()) {
        if (dimension.is_mapped()) {
            is_sparse = true;
        }
        if (dimension.is_indexed()) {
            is_dense = true;
        }
    }
    if (is_dense && is_sparse) {
        return DefaultTensor::builder().build();
    } else if (is_dense) {
        DenseTensorBuilder builder;
        std::map<vespalib::string,DenseTensorBuilder::Dimension> dimension_map;
        for (const auto &dimension: type.dimensions()) {
            dimension_map[dimension.name] = builder.defineDimension(dimension.name, dimension.size);
        }
        for (const auto &cell: spec.cells()) {
            const auto &address = cell.first;
            for (const auto &binding: address) {
                builder.addLabel(dimension_map[binding.first], binding.second.index);
            }
            builder.addCell(cell.second);
        }
        return builder.build();
    } else { // sparse
        DefaultTensor::builder builder;
        std::map<vespalib::string,DefaultTensor::builder::Dimension> dimension_map;
        for (const auto &dimension: type.dimensions()) {
            dimension_map[dimension.name] = builder.define_dimension(dimension.name);
        }
        for (const auto &cell: spec.cells()) {
            const auto &address = cell.first;
            for (const auto &binding: address) {
                builder.add_label(dimension_map[binding.first], binding.second.name);
            }
            builder.add_cell(cell.second);
        }
        return builder.build();
    }
}

const eval::Value &
DefaultTensorEngine::reduce(const Tensor &tensor, const BinaryOperation &op, const std::vector<vespalib::string> &dimensions, Stash &stash) const
{
    assert(&tensor.engine() == this);
    const tensor::Tensor &my_tensor = static_cast<const tensor::Tensor &>(tensor);
    IsAddOperation check;
    op.accept(check);
    tensor::Tensor::UP result;
    if (check.result) {
        if (dimensions.empty()) { // sum
            return stash.create<eval::DoubleValue>(my_tensor.sum());
        } else { // dimension sum
            for (const auto &dimension: dimensions) {
                if (result) {
                    result = result->sum(dimension);
                } else {
                    result = my_tensor.sum(dimension);
                }
            }
        }
    } else {
        result = my_tensor.reduce(op, dimensions);
    }
    if (result) {
        eval::ValueType result_type(result->getType());
        if (result_type.is_tensor()) {
            return stash.create<TensorValue>(std::move(result));
        }
        if (result_type.is_double()) {
            return stash.create<eval::DoubleValue>(result->sum());
        }
    }
    return stash.create<ErrorValue>();
}

struct CellFunctionAdapter : tensor::CellFunction {
    const eval::UnaryOperation &op;
    CellFunctionAdapter(const eval::UnaryOperation &op_in) : op(op_in) {}
    virtual double apply(double value) const override { return op.eval(value); }
};

const eval::Value &
DefaultTensorEngine::map(const UnaryOperation &op, const Tensor &a, Stash &stash) const
{
    assert(&a.engine() == this);
    const tensor::Tensor &my_a = static_cast<const tensor::Tensor &>(a);
    CellFunctionAdapter cell_function(op);
    return stash.create<TensorValue>(my_a.apply(cell_function));
}

struct TensorOperationOverride : eval::DefaultOperationVisitor {
    const tensor::Tensor &lhs;
    const tensor::Tensor &rhs;
    tensor::Tensor::UP result;
    TensorOperationOverride(const tensor::Tensor &lhs_in,
                            const tensor::Tensor &rhs_in)
        : lhs(lhs_in), rhs(rhs_in), result() {}
    virtual void visitDefault(const eval::Operation &op) override {
        // empty result indicates error
        const eval::BinaryOperation *binaryOp =
            dynamic_cast<const eval::BinaryOperation *>(&op);
        if (binaryOp) {
            result = lhs.apply(*binaryOp, rhs);
        }
    }
    virtual void visit(const eval::operation::Add &) override {
        result = lhs.add(rhs);
    }
    virtual void visit(const eval::operation::Sub &) override {
        result = lhs.subtract(rhs);
    }
    virtual void visit(const eval::operation::Mul &) override {
        if (lhs.getType() == rhs.getType()) {
            result = lhs.match(rhs);
        } else {
            result = lhs.multiply(rhs);
        }
    }
    virtual void visit(const eval::operation::Min &) override {
        result = lhs.min(rhs);
    }
    virtual void visit(const eval::operation::Max &) override {
        result = lhs.max(rhs);
    }
};

const eval::Value &
DefaultTensorEngine::apply(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const
{
    assert(&a.engine() == this);
    assert(&b.engine() == this);
    const tensor::Tensor &my_a = static_cast<const tensor::Tensor &>(a);
    const tensor::Tensor &my_b = static_cast<const tensor::Tensor &>(b);
    if (my_a.getType().type() != my_b.getType().type()) {
        return stash.create<ErrorValue>();
    }
    TensorOperationOverride tensor_override(my_a, my_b);
    op.accept(tensor_override);
    if (tensor_override.result) {
        return stash.create<TensorValue>(std::move(tensor_override.result));
    } else {
        return stash.create<ErrorValue>();
    }
}

} // namespace vespalib::tensor
} // namespace vespalib
<commit_msg>De-activate function compiler until optimization and unit tests are in place.<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include "default_tensor_engine.h"
#include <vespa/vespalib/eval/value.h>
#include <vespa/vespalib/eval/tensor_spec.h>
#include <vespa/vespalib/eval/operation_visitor.h>
#include "tensor.h"
#include "dense/dense_tensor_builder.h"
#include "dense/dense_tensor_function_compiler.h"
#include "default_tensor.h"

namespace vespalib {
namespace tensor {

using ErrorValue = eval::ErrorValue;
using DoubleValue = eval::DoubleValue;
using TensorValue = eval::TensorValue;

const DefaultTensorEngine DefaultTensorEngine::_engine;

eval::ValueType
DefaultTensorEngine::type_of(const Tensor &tensor) const
{
    assert(&tensor.engine() == this);
    const tensor::Tensor &my_tensor = static_cast<const tensor::Tensor &>(tensor);
    return my_tensor.getType();
}

bool
DefaultTensorEngine::equal(const Tensor &a, const Tensor &b) const
{
    assert(&a.engine() == this);
    assert(&b.engine() == this);
    const tensor::Tensor &my_a = static_cast<const tensor::Tensor &>(a);
    const tensor::Tensor &my_b = static_cast<const tensor::Tensor &>(b);
    if (my_a.getType().type() != my_b.getType().type()) {
        return false;
    }
    return my_a.equals(my_b);
}

vespalib::string
DefaultTensorEngine::to_string(const Tensor &tensor) const
{
    assert(&tensor.engine() == this);
    const tensor::Tensor &my_tensor = static_cast<const tensor::Tensor &>(tensor);
    return my_tensor.toString();
}

eval::TensorSpec
DefaultTensorEngine::to_spec(const Tensor &tensor) const
{
    assert(&tensor.engine() == this);
    const tensor::Tensor &my_tensor = static_cast<const tensor::Tensor &>(tensor);
    return my_tensor.toSpec();
}

eval::TensorFunction::UP
DefaultTensorEngine::compile(eval::tensor_function::Node_UP expr)
{
    return std::move(expr);
}

struct IsAddOperation : public eval::DefaultOperationVisitor {
    bool result = false;
    void visitDefault(const eval::Operation &) override {}
    void visit(const eval::operation::Add &) override { result = true; }
};

std::unique_ptr<eval::Tensor>
DefaultTensorEngine::create(const TensorSpec &spec) const
{
    ValueType type = ValueType::from_spec(spec.type());
    bool is_dense = false;
    bool is_sparse = false;
    for (const auto &dimension: type.dimensions()) {
        if (dimension.is_mapped()) {
            is_sparse = true;
        }
        if (dimension.is_indexed()) {
            is_dense = true;
        }
    }
    if (is_dense && is_sparse) {
        return DefaultTensor::builder().build();
    } else if (is_dense) {
        DenseTensorBuilder builder;
        std::map<vespalib::string,DenseTensorBuilder::Dimension> dimension_map;
        for (const auto &dimension: type.dimensions()) {
            dimension_map[dimension.name] = builder.defineDimension(dimension.name, dimension.size);
        }
        for (const auto &cell: spec.cells()) {
            const auto &address = cell.first;
            for (const auto &binding: address) {
                builder.addLabel(dimension_map[binding.first], binding.second.index);
            }
            builder.addCell(cell.second);
        }
        return builder.build();
    } else { // sparse
        DefaultTensor::builder builder;
        std::map<vespalib::string,DefaultTensor::builder::Dimension> dimension_map;
        for (const auto &dimension: type.dimensions()) {
            dimension_map[dimension.name] = builder.define_dimension(dimension.name);
        }
        for (const auto &cell: spec.cells()) {
            const auto &address = cell.first;
            for (const auto &binding: address) {
                builder.add_label(dimension_map[binding.first], binding.second.name);
            }
            builder.add_cell(cell.second);
        }
        return builder.build();
    }
}

const eval::Value &
DefaultTensorEngine::reduce(const Tensor &tensor, const BinaryOperation &op, const std::vector<vespalib::string> &dimensions, Stash &stash) const
{
    assert(&tensor.engine() == this);
    const tensor::Tensor &my_tensor = static_cast<const tensor::Tensor &>(tensor);
    IsAddOperation check;
    op.accept(check);
    tensor::Tensor::UP result;
    if (check.result) {
        if (dimensions.empty()) { // sum
            return stash.create<eval::DoubleValue>(my_tensor.sum());
        } else { // dimension sum
            for (const auto &dimension: dimensions) {
                if (result) {
                    result = result->sum(dimension);
                } else {
                    result = my_tensor.sum(dimension);
                }
            }
        }
    } else {
        result = my_tensor.reduce(op, dimensions);
    }
    if (result) {
        eval::ValueType result_type(result->getType());
        if (result_type.is_tensor()) {
            return stash.create<TensorValue>(std::move(result));
        }
        if (result_type.is_double()) {
            return stash.create<eval::DoubleValue>(result->sum());
        }
    }
    return stash.create<ErrorValue>();
}

struct CellFunctionAdapter : tensor::CellFunction {
    const eval::UnaryOperation &op;
    CellFunctionAdapter(const eval::UnaryOperation &op_in) : op(op_in) {}
    virtual double apply(double value) const override { return op.eval(value); }
};

const eval::Value &
DefaultTensorEngine::map(const UnaryOperation &op, const Tensor &a, Stash &stash) const
{
    assert(&a.engine() == this);
    const tensor::Tensor &my_a = static_cast<const tensor::Tensor &>(a);
    CellFunctionAdapter cell_function(op);
    return stash.create<TensorValue>(my_a.apply(cell_function));
}

struct TensorOperationOverride : eval::DefaultOperationVisitor {
    const tensor::Tensor &lhs;
    const tensor::Tensor &rhs;
    tensor::Tensor::UP result;
    TensorOperationOverride(const tensor::Tensor &lhs_in,
                            const tensor::Tensor &rhs_in)
        : lhs(lhs_in), rhs(rhs_in), result() {}
    virtual void visitDefault(const eval::Operation &op) override {
        // empty result indicates error
        const eval::BinaryOperation *binaryOp =
            dynamic_cast<const eval::BinaryOperation *>(&op);
        if (binaryOp) {
            result = lhs.apply(*binaryOp, rhs);
        }
    }
    virtual void visit(const eval::operation::Add &) override {
        result = lhs.add(rhs);
    }
    virtual void visit(const eval::operation::Sub &) override {
        result = lhs.subtract(rhs);
    }
    virtual void visit(const eval::operation::Mul &) override {
        if (lhs.getType() == rhs.getType()) {
            result = lhs.match(rhs);
        } else {
            result = lhs.multiply(rhs);
        }
    }
    virtual void visit(const eval::operation::Min &) override {
        result = lhs.min(rhs);
    }
    virtual void visit(const eval::operation::Max &) override {
        result = lhs.max(rhs);
    }
};

const eval::Value &
DefaultTensorEngine::apply(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const
{
    assert(&a.engine() == this);
    assert(&b.engine() == this);
    const tensor::Tensor &my_a = static_cast<const tensor::Tensor &>(a);
    const tensor::Tensor &my_b = static_cast<const tensor::Tensor &>(b);
    if (my_a.getType().type() != my_b.getType().type()) {
        return stash.create<ErrorValue>();
    }
    TensorOperationOverride tensor_override(my_a, my_b);
    op.accept(tensor_override);
    if (tensor_override.result) {
        return stash.create<TensorValue>(std::move(tensor_override.result));
    } else {
        return stash.create<ErrorValue>();
    }
}

} // namespace vespalib::tensor
} // namespace vespalib
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2013 libwallet developers (see AUTHORS)
 *
 * This file is part of libwallet.
 *
 * libwallet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <wallet/uri.hpp>

#include <boost/algorithm/string.hpp>
#include <bitcoin/constants.hpp>
#include <bitcoin/utility/base58.hpp>

namespace libwallet {

static bool is_digit(char c)
{
    return '0' <= c && c <= '9';
}
static bool is_hex(char c)
{
    return is_digit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
}
static bool is_qchar(char c)
{
    return
        ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || is_digit(c) ||
        '-' == c || '.' == c || '_' == c || '~' == c || // unreserved
        '!' == c || '$' == c || '\'' == c || '(' == c || ')' == c ||
        '*' == c || '+' == c || ',' == c || ';' == c || // sub-delims
        ':' == c || '@' == c || // pchar
        '/' == c || '?' == c;   // query
}
static bool isnt_amp(char c)
{
    return '&' != c;
}

static unsigned from_hex(char c)
{
    return
        'A' <= c && c <= 'F' ? 10 + c - 'A' :
        'a' <= c && c <= 'f' ? 10 + c - 'a' :
        c - '0';
}

/**
 * Unescapes a percent-encoded string while advancing the iterator.
 * @param i set to one-past the last-read character on return.
 */
typedef std::string::const_iterator sci;
static std::string unescape(sci& i, sci end, bool (*is_valid)(char))
{
    auto j = i;
    size_t count = 0;
    while (end != i && (is_valid(*i) ||
        ('%' == *i && 2 < end - i && is_hex(i[1]) && is_hex(i[2]))))
    {
        ++count;
        i += ('%' == *i ? 3 : 1);
    }
    std::string out;
    out.reserve(count);
    while (j != i)
    {
        out.push_back('%' == *j ? from_hex(j[1]) << 4 | from_hex(j[2]) : *j);
        j += ('%' == *j ? 3 : 1);
    }
    return out;
}

/**
 * Parses a URI string into its individual components.
 * @param strict Only accept properly-escaped parameters. Some bitcoin
 * software does not properly escape URI parameters, and setting strict to
 * false allows these malformed URI's to parse anyhow.
 * @return false if the URI is malformed.
 */
bool uri_parse(const std::string& uri, uri_visitor& result, bool strict)
{
    auto i = uri.begin();

    // URI scheme (this approach does not depend on the current locale):
    const char* lower = "bitcoin:";
    const char* upper = "BITCOIN:";
    while (*lower != '\0')
    {
        if (uri.end() == i || (*lower != *i && *upper != *i))
            return false;
        ++lower; ++upper; ++i;
    }

    // Payment address:
    std::string address = unescape(i, uri.end(), libbitcoin::is_base58);
    if (uri.end() != i && '?' != *i)
        return false;
    if (!address.empty() && !result.got_address(address))
        return false;

    // Parameters:
    while (uri.end() != i)
    {
        ++i; // Consume '?' or '&'
        std::string key = unescape(i, uri.end(), is_qchar);
        std::string value;
        if (uri.end() != i && '=' == *i)
        {
            ++i; // Consume '='
            if (key.empty())
                return false;
            value = unescape(i, uri.end(), strict ? is_qchar : isnt_amp);
        }
        if (uri.end() != i && '&' != *i)
            return false;
        if (!key.empty() && !result.got_param(key, value))
            return false;
    }
    return true;
}

bool uri_parse_result::got_address(std::string& address)
{
    libbitcoin::payment_address payaddr;
    if (!payaddr.set_encoded(address))
        return false;
    this->address.reset(payaddr);
    return true;
}

bool uri_parse_result::got_param(std::string& key, std::string& value)
{
    if (key == "amount")
    {
        uint64_t amount = parse_amount(value);
        if (invalid_amount == amount)
            return false;
        this->amount.reset(amount);
    }
    else if (key == "label")
        label.reset(value);
    else if (key == "message")
        message.reset(value);
    else if (key == "r")
        r.reset(value);
    else if (!key.compare(0, 4, "req-"))
        return false;
    return true;
}

uint64_t parse_amount(const std::string& amount, unsigned decmial_place)
{
    auto i = amount.begin();
    uint64_t value = 0;
    unsigned places = 0;

    while (amount.end() != i && is_digit(*i))
    {
        value = 10*value + (*i - '0');
        ++i;
    }
    if (amount.end() != i && '.' == *i)
    {
        ++i;
        while (amount.end() != i && is_digit(*i))
        {
            if (places < decmial_place)
                value = 10*value + (*i - '0');
            else if (places == decmial_place && '5' <= *i)
                value += 1;
            ++places;
            ++i;
        }
    }
    while (places < decmial_place)
    {
        value *= 10;
        ++places;
    }
    return amount.end() == i ? value : invalid_amount;
}

/**
 * Percent-encodes a string.
 * @param is_valid a function returning true for acceptable characters.
 */
static std::string escape(const std::string& in, bool (*is_valid)(char))
{
    std::ostringstream stream;
    stream << std::hex << std::uppercase << std::setfill('0');
    for (auto c: in)
    {
        if (is_valid(c))
            stream << c;
        else
            stream << '%' << std::setw(2) << +c;
    }
    return stream.str();
}

uri_writer::uri_writer()
  : first_param_{true}
{
    stream_ << "bitcoin:";
}

void uri_writer::write_address(const libbitcoin::payment_address& address)
{
    write_address(address.encoded());
}

void uri_writer::write_amount(uint64_t satoshis)
{
    // Format as a fixed-point number:
    uint64_t bitcoin = satoshis / libbitcoin::coin_price();
    satoshis = satoshis % libbitcoin::coin_price();
    std::ostringstream stream;
    stream << bitcoin << '.' << std::setw(8) << std::setfill('0') << satoshis;
    // Trim trailing zeros:
    auto string = stream.str();
    boost::algorithm::trim_right_if(string, [](char c){ return '0' == c; });
    boost::algorithm::trim_right_if(string, [](char c){ return '.' == c; });
    write_param("amount", string);
}

void uri_writer::write_label(const std::string& label)
{
    write_param("label", label);
}

void uri_writer::write_message(const std::string& message)
{
    write_param("message", message);
}

void uri_writer::write_r(const std::string& r)
{
    write_param("r", r);
}

void uri_writer::write_address(const std::string& address)
{
    stream_ << address;
}

void uri_writer::write_param(const std::string& key, const std::string& value)
{
    stream_ << (first_param_ ? '?' : '&') <<
        escape(key, is_qchar) << '=' << escape(value, is_qchar);
    first_param_ = false;
}

std::string uri_writer::string() const
{
    return stream_.str();
}

} // namespace libwallet
<commit_msg>Fix ubuntu compiler break in uri parse.<commit_after>/*
 * Copyright (c) 2011-2013 libwallet developers (see AUTHORS)
 *
 * This file is part of libwallet.
 *
 * libwallet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <wallet/uri.hpp>

#include <boost/algorithm/string.hpp>
#include <bitcoin/constants.hpp>
#include <bitcoin/utility/base58.hpp>

namespace libwallet {

static bool is_base58(char c)
{
    // This wrapper is necessary to prevent compiler from
    // choosing the wrong override of libbitcoin::is_base58.
    return libbitcoin::is_base58(c);
}
static bool is_digit(char c)
{
    return '0' <= c && c <= '9';
}
static bool is_hex(char c)
{
    return is_digit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
}
static bool is_qchar(char c)
{
    return
        ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || is_digit(c) ||
        '-' == c || '.' == c || '_' == c || '~' == c || // unreserved
        '!' == c || '$' == c || '\'' == c || '(' == c || ')' == c ||
        '*' == c || '+' == c || ',' == c || ';' == c || // sub-delims
        ':' == c || '@' == c || // pchar
        '/' == c || '?' == c;   // query
}
static bool isnt_amp(char c)
{
    return '&' != c;
}

static unsigned from_hex(char c)
{
    return
        'A' <= c && c <= 'F' ? 10 + c - 'A' :
        'a' <= c && c <= 'f' ? 10 + c - 'a' :
        c - '0';
}

/**
 * Unescapes a percent-encoded string while advancing the iterator.
 * @param i set to one-past the last-read character on return.
 */
typedef std::string::const_iterator sci;
static std::string unescape(sci& i, sci end, bool (*is_valid)(char))
{
    auto j = i;
    size_t count = 0;
    while (end != i && (is_valid(i[0]) ||
        ('%' == *i && 2 < end - i && is_hex(i[1]) && is_hex(i[2]))))
    {
        ++count;
        i += ('%' == *i ? 3 : 1);
    }
    std::string out;
    out.reserve(count);
    while (j != i)
    {
        out.push_back('%' == *j ? from_hex(j[1]) << 4 | from_hex(j[2]) : *j);
        j += ('%' == *j ? 3 : 1);
    }
    return out;
}

/**
 * Parses a URI string into its individual components.
 * @param strict Only accept properly-escaped parameters. Some bitcoin
 * software does not properly escape URI parameters, and setting strict to
 * false allows these malformed URI's to parse anyhow.
 * @return false if the URI is malformed.
 */
bool uri_parse(const std::string& uri, uri_visitor& result, bool strict)
{
    auto i = uri.begin();

    // URI scheme (this approach does not depend on the current locale):
    const char* lower = "bitcoin:";
    const char* upper = "BITCOIN:";
    while (*lower != '\0')
    {
        if (uri.end() == i || (*lower != *i && *upper != *i))
            return false;
        ++lower; ++upper; ++i;
    }

    // Payment address:
    std::string address = unescape(i, uri.end(), (bool(*)(char))libbitcoin::is_base58);
    if (uri.end() != i && '?' != *i)
        return false;
    if (!address.empty() && !result.got_address(address))
        return false;

    // Parameters:
    while (uri.end() != i)
    {
        ++i; // Consume '?' or '&'
        std::string key = unescape(i, uri.end(), is_qchar);
        std::string value;
        if (uri.end() != i && '=' == *i)
        {
            ++i; // Consume '='
            if (key.empty())
                return false;
            value = unescape(i, uri.end(), strict ? is_qchar : isnt_amp);
        }
        if (uri.end() != i && '&' != *i)
            return false;
        if (!key.empty() && !result.got_param(key, value))
            return false;
    }
    return true;
}

bool uri_parse_result::got_address(std::string& address)
{
    libbitcoin::payment_address payaddr;
    if (!payaddr.set_encoded(address))
        return false;
    this->address.reset(payaddr);
    return true;
}

bool uri_parse_result::got_param(std::string& key, std::string& value)
{
    if (key == "amount")
    {
        uint64_t amount = parse_amount(value);
        if (invalid_amount == amount)
            return false;
        this->amount.reset(amount);
    }
    else if (key == "label")
        label.reset(value);
    else if (key == "message")
        message.reset(value);
    else if (key == "r")
        r.reset(value);
    else if (!key.compare(0, 4, "req-"))
        return false;
    return true;
}

uint64_t parse_amount(const std::string& amount, unsigned decmial_place)
{
    auto i = amount.begin();
    uint64_t value = 0;
    unsigned places = 0;

    while (amount.end() != i && is_digit(*i))
    {
        value = 10*value + (*i - '0');
        ++i;
    }
    if (amount.end() != i && '.' == *i)
    {
        ++i;
        while (amount.end() != i && is_digit(*i))
        {
            if (places < decmial_place)
                value = 10*value + (*i - '0');
            else if (places == decmial_place && '5' <= *i)
                value += 1;
            ++places;
            ++i;
        }
    }
    while (places < decmial_place)
    {
        value *= 10;
        ++places;
    }
    return amount.end() == i ? value : invalid_amount;
}

/**
 * Percent-encodes a string.
 * @param is_valid a function returning true for acceptable characters.
 */
static std::string escape(const std::string& in, bool (*is_valid)(char))
{
    std::ostringstream stream;
    stream << std::hex << std::uppercase << std::setfill('0');
    for (auto c: in)
    {
        if (is_valid(c))
            stream << c;
        else
            stream << '%' << std::setw(2) << +c;
    }
    return stream.str();
}

uri_writer::uri_writer()
  : first_param_{true}
{
    stream_ << "bitcoin:";
}

void uri_writer::write_address(const libbitcoin::payment_address& address)
{
    write_address(address.encoded());
}

void uri_writer::write_amount(uint64_t satoshis)
{
    // Format as a fixed-point number:
    uint64_t bitcoin = satoshis / libbitcoin::coin_price();
    satoshis = satoshis % libbitcoin::coin_price();
    std::ostringstream stream;
    stream << bitcoin << '.' << std::setw(8) << std::setfill('0') << satoshis;
    // Trim trailing zeros:
    auto string = stream.str();
    boost::algorithm::trim_right_if(string, [](char c){ return '0' == c; });
    boost::algorithm::trim_right_if(string, [](char c){ return '.' == c; });
    write_param("amount", string);
}

void uri_writer::write_label(const std::string& label)
{
    write_param("label", label);
}

void uri_writer::write_message(const std::string& message)
{
    write_param("message", message);
}

void uri_writer::write_r(const std::string& r)
{
    write_param("r", r);
}

void uri_writer::write_address(const std::string& address)
{
    stream_ << address;
}

void uri_writer::write_param(const std::string& key, const std::string& value)
{
    stream_ << (first_param_ ? '?' : '&') <<
        escape(key, is_qchar) << '=' << escape(value, is_qchar);
    first_param_ = false;
}

std::string uri_writer::string() const
{
    return stream_.str();
}

} // namespace libwallet
<|endoftext|>


<commit_before>// Copyright (c) 2018 The Globaltoken Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <globaltoken/hardfork.h>
#include <uint256.h>
#include <arith_uint256.h>
#include <chainparams.h>
#include <primitives/block.h>

arith_uint256 GetAlgoPowLimit(int algo, const Consensus::Params& consensusParams)
{
	if (algo == ALGO_SHA256D)
		return UintToArith256(consensusParams.powLimit_SHA256);
	else if (algo == ALGO_SCRYPT)
		return UintToArith256(consensusParams.powLimit_SCRYPT);
	else if (algo == ALGO_X11)
		return UintToArith256(consensusParams.powLimit_X11);
	else if (algo == ALGO_NEOSCRYPT)
		return UintToArith256(consensusParams.powLimit_NEOSCRYPT);
	else if (algo == ALGO_EQUIHASH)
		return UintToArith256(consensusParams.powLimit_EQUIHASH);
	else if (algo == ALGO_YESCRYPT)
		return UintToArith256(consensusParams.powLimit_YESCRYPT);
	else if (algo == ALGO_HMQ1725)
		return UintToArith256(consensusParams.powLimit_HMQ1725);
	else
		return UintToArith256(consensusParams.powLimit_SHA256);
}

arith_uint256 GetAlgoPowLimit(int algo)
{
	const Consensus::Params& consensusParams = Params().GetConsensus();
	GetAlgoPowLimit(algo, consensusParams);
}

bool IsHardForkActivated(uint32_t blocktime, const Consensus::Params& consensusParams)
{
	if(blocktime >= consensusParams.HardforkTime)
	{
		return true;
	}
	return false;
}

bool IsHardForkActivated(uint32_t blocktime)
{
	const Consensus::Params& consensusParams = Params().GetConsensus();
	IsHardForkActivated(blocktime, consensusParams);
}

int64_t GetPoWTargetTimeSpan(uint32_t blocktime, const Consensus::Params& consensusParams)
{
	if(IsHardForkActivated(blocktime))
	{
		return consensusParams.nPowTargetTimespanV2;
	}
	else
	{
		return consensusParams.nPowTargetTimespan;
	}
}

int64_t GetPoWTargetTimeSpan(uint32_t blocktime)
{
	const Consensus::Params& consensusParams = Params().GetConsensus();
	GetPoWTargetTimeSpan(blocktime, consensusParams);
}

int64_t GetPoWTargetSpacing(uint32_t blocktime, const Consensus::Params& consensusParams)
{
	if(IsHardForkActivated(blocktime))
	{
		return consensusParams.nPowTargetSpacingV2;
	}
	else
	{
		return consensusParams.nPowTargetSpacing;
	}
}

int64_t GetPoWTargetSpacing(uint32_t blocktime)
{
	const Consensus::Params& consensusParams = Params().GetConsensus();
	GetPoWTargetSpacing(blocktime, consensusParams);
}<commit_msg>Hardfork had no return value<commit_after>// Copyright (c) 2018 The Globaltoken Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <globaltoken/hardfork.h>
#include <uint256.h>
#include <arith_uint256.h>
#include <chainparams.h>
#include <primitives/block.h>

arith_uint256 GetAlgoPowLimit(int algo, const Consensus::Params& consensusParams)
{
	if (algo == ALGO_SHA256D)
		return UintToArith256(consensusParams.powLimit_SHA256);
	else if (algo == ALGO_SCRYPT)
		return UintToArith256(consensusParams.powLimit_SCRYPT);
	else if (algo == ALGO_X11)
		return UintToArith256(consensusParams.powLimit_X11);
	else if (algo == ALGO_NEOSCRYPT)
		return UintToArith256(consensusParams.powLimit_NEOSCRYPT);
	else if (algo == ALGO_EQUIHASH)
		return UintToArith256(consensusParams.powLimit_EQUIHASH);
	else if (algo == ALGO_YESCRYPT)
		return UintToArith256(consensusParams.powLimit_YESCRYPT);
	else if (algo == ALGO_HMQ1725)
		return UintToArith256(consensusParams.powLimit_HMQ1725);
	else
		return UintToArith256(consensusParams.powLimit_SHA256);
}

arith_uint256 GetAlgoPowLimit(int algo)
{
	const Consensus::Params& consensusParams = Params().GetConsensus();
	return GetAlgoPowLimit(algo, consensusParams);
}

bool IsHardForkActivated(uint32_t blocktime, const Consensus::Params& consensusParams)
{
	if(blocktime >= consensusParams.HardforkTime)
	{
		return true;
	}
	return false;
}

bool IsHardForkActivated(uint32_t blocktime)
{
	const Consensus::Params& consensusParams = Params().GetConsensus();
	return IsHardForkActivated(blocktime, consensusParams);
}

int64_t GetPoWTargetTimeSpan(uint32_t blocktime, const Consensus::Params& consensusParams)
{
	if(IsHardForkActivated(blocktime))
	{
		return consensusParams.nPowTargetTimespanV2;
	}
	else
	{
		return consensusParams.nPowTargetTimespan;
	}
}

int64_t GetPoWTargetTimeSpan(uint32_t blocktime)
{
	const Consensus::Params& consensusParams = Params().GetConsensus();
	return GetPoWTargetTimeSpan(blocktime, consensusParams);
}

int64_t GetPoWTargetSpacing(uint32_t blocktime, const Consensus::Params& consensusParams)
{
	if(IsHardForkActivated(blocktime))
	{
		return consensusParams.nPowTargetSpacingV2;
	}
	else
	{
		return consensusParams.nPowTargetSpacing;
	}
}

int64_t GetPoWTargetSpacing(uint32_t blocktime)
{
	const Consensus::Params& consensusParams = Params().GetConsensus();
	return GetPoWTargetSpacing(blocktime, consensusParams);
}<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 *  Created on: Jan 2018
 *      Author: Norbert Podhorszki
 */

#include <chrono>
#include <ios>      //std::ios_base::failure
#include <iostream> //std::cout
#include <numeric>
#include <stdexcept> //std::invalid_argument std::exception
#include <string>
#include <thread>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include <adios2.h>

static int numprocs, wrank;
std::string engineName; // comes from command line

struct RunParams
{
    /* 2D decomposition of processes
     * npx_w x npy_w Writers
     * npx_r x npy_r Readers
     */
    size_t npx_w;
    size_t npy_w;
    size_t npx_r;
    size_t npy_r;
    RunParams(size_t xw, size_t yw, size_t xr, size_t yr)
    : npx_w{xw}, npy_w{yw}, npx_r{xr}, npy_r{yr} {};
};

/* This function is executed by INSTANTIATE_TEST_CASE_P
   before main() and MPI_Init()!!! */
std::vector<RunParams> CreateRunParams()
{
    std::vector<RunParams> params;
    // 2 process test
    params.push_back(RunParams(1, 1, 1, 1));
    // 3 process tests
    params.push_back(RunParams(2, 1, 1, 1));
    params.push_back(RunParams(1, 2, 1, 1));
    params.push_back(RunParams(1, 1, 2, 1));
    params.push_back(RunParams(1, 1, 1, 2));
    // 4 process tests
    params.push_back(RunParams(2, 1, 2, 1));
    params.push_back(RunParams(2, 1, 1, 2));
    // 8 process tests
    params.push_back(RunParams(1, 1, 1, 7));
    params.push_back(RunParams(1, 7, 1, 1));
    params.push_back(RunParams(2, 2, 2, 2));
    // 16 process tests
    params.push_back(RunParams(3, 5, 1, 1));
    params.push_back(RunParams(1, 1, 5, 3));
    return params;
}

class TestStagingMPMD : public ::testing::TestWithParam<RunParams>
{
public:
    TestStagingMPMD() = default;
    const std::string streamName = "TestStream";

    void MainWriters(MPI_Comm comm, size_t npx, size_t npy, int steps,
                     unsigned int sleeptime)
    {
        int rank, nproc;
        MPI_Comm_rank(comm, &rank);
        MPI_Comm_size(comm, &nproc);
        if (!rank)
        {
            std::cout << "There are " << nproc << " Writers" << std::endl;
        }
        size_t ndx = 50;
        size_t ndy = 60;
        size_t gndx = npx * ndx;
        size_t gndy = npy * ndy;
        size_t posx = rank % npx;
        size_t posy = rank / npx;
        size_t offsx = posx * ndx;
        size_t offsy = posy * ndy;

        std::vector<float> myArray(ndx * ndy);

        adios2::ADIOS adios(comm);
        adios2::IO &io = adios.DeclareIO("writer");
        io.SetEngine(engineName);

        adios2::Variable<float> &varArray =
            io.DefineVariable<float>("myArray", {gndx, gndy}, {offsx, offsy},
                                     {ndx, ndy}, adios2::ConstantDims);

        adios2::Engine &writer = io.Open(streamName, adios2::Mode::Write, comm);

        for (size_t step = 0; step < steps; ++step)
        {
            size_t idx = 0;
            for (size_t x = 0; x < ndx; ++x)
            {
                for (size_t y = 0; y < ndy; ++y)
                {
                    myArray[idx] = GetValue(offsx + x, offsy + y, step);
                    ++idx;
                }
            }
            writer.BeginStep(adios2::StepMode::Append);
            writer.PutDeferred<float>(varArray, myArray.data());
            writer.EndStep();
            std::this_thread::sleep_for(std::chrono::milliseconds(sleeptime));
        }
        writer.Close();
    }

    /* encode position x,y as y.x floating point value in each array cell
     * add 1000*step to each value
     *
     * A 2 by 2 example with 3x3 local arrays
     *   0.0    0.001  0.002 |  0.003  0.004  0.005
     *   1.0    1.001  1.002 |  1.003  1.004  1.005
     *   2.0    2.001  2.002 |  2.003  2.004  2.005
     *   --------------------+---------------------
     *   3.0    3.001  3.002 |  3.003  3.004  3.005
     *   4.0    4.001  4.002 |  4.003  4.004  4.005
     *   5.0    5.001  5.002 |  5.003  5.004  5.005
     *
     * Next step each value is bigger by 1000
     */
    float GetValue(size_t offsx, size_t offsy, size_t step)
    {
        return 1000.0f * step + offsy + offsx / 1000.0f;
    }

    void CheckData(const std::vector<float> &array, size_t gndx, size_t gndy,
                   size_t offsx, size_t offsy, size_t ndx, size_t ndy,
                   size_t step, int rank)
    {
        size_t idx = 0;
        for (size_t x = 0; x < ndx; ++x)
        {
            for (size_t y = 0; y < ndy; ++x)
            {
                float expectedValue = GetValue(offsx + x, offsy + y, step);
                EXPECT_EQ(array[idx], expectedValue) <<
                    "Error in read, did not receive the expected value:"
                    << " rank " << rank << ", step " << step
                    << ", gdim {" << gndx << ',' << gndy << '}'
                    << ", offs {" << offsx << ',' << offsy << '}'
                    << ", ldim {" << ndx << ',' << ndy << '}'
                    << ", lpos {" << x << ',' << y << '}';
                ++idx;
            }
        }
    }

    void MainReaders(MPI_Comm comm, size_t npx, size_t npy,
                     unsigned int sleeptime)
    {
        int rank, nproc;
        MPI_Comm_rank(comm, &rank);
        MPI_Comm_size(comm, &nproc);
        if (!rank)
        {
            std::cout << "There are " << nproc << " Readers" << std::endl;
        }

        adios2::ADIOS adios(comm);
        adios2::IO &io = adios.DeclareIO("reader");
        io.SetEngine(engineName);
        adios2::Engine &reader = io.Open(streamName, adios2::Mode::Read, comm);

        size_t posx = rank % npx;
        size_t posy = rank / npx;
        size_t step = 0;
        adios2::Variable<float> *vMyArray = nullptr;
        std::vector<float> myArray;

        while (true)
        {
            adios2::StepStatus status =
                reader.BeginStep(adios2::StepMode::NextAvailable, 60.0f);
            if (status != adios2::StepStatus::OK)
            {
                break;
            }

            vMyArray = io.InquireVariable<float>("myArray");
            if (vMyArray == nullptr)
            {
                throw std::ios_base::failure("Missing 'myArray' variable.");
            }

            // 2D decomposition of global array reading
            size_t gndx = vMyArray->m_Shape[0];
            size_t gndy = vMyArray->m_Shape[1];
            size_t ndx = gndx / npx;
            size_t ndy = gndy / npy;
            size_t offsx = ndx * posx;
            size_t offsy = ndy * posy;
            if (posx == npx - 1)
            {
                // right-most processes need to read all the rest of rows
                ndx = gndx - ndx * (npx - 1);
            }

            if (posy == npy - 1)
            {
                // bottom processes need to read all the rest of columns
                ndy = gndy - ndy * (npy - 1);
            }

            adios2::Dims count({ndx, ndy});
            adios2::Dims start({offsx, offsy});

            vMyArray->SetSelection({start, count});
            size_t elementsSize = count[0] * count[1];
            myArray.resize(elementsSize);

            reader.GetDeferred(*vMyArray, myArray.data());
            reader.EndStep();
            CheckData(myArray, gndx, gndy, offsx, offsy, ndx, ndy, step, rank);
            std::this_thread::sleep_for(std::chrono::milliseconds(sleeptime));
            ++step;
        }
        reader.Close();
    }

    void TestCommon(RunParams p, int steps, unsigned int writer_sleeptime,
                    unsigned int reader_sleeptime)
    {
        std::cout << "test " << p.npx_w << "x" << p.npy_w << " writers "
                  << p.npx_r << "x" << p.npy_r << " readers " << std::endl;

        int nwriters = p.npx_w * p.npy_w;
        int nreaders = p.npx_r * p.npy_r;
        if (nwriters + nreaders > numprocs)
        {
            if (!wrank)
            {
                std::cout
                    << "skip test: writers+readers > available processors "
                    << std::endl;
            }
            return;
        }

        int rank;
        MPI_Comm comm;

        unsigned int color;
        if (wrank < nwriters)
        {
            color = 0; // writers
        }
        else if (wrank < nwriters + nreaders)
        {
            color = 1; // readers
        }
        else
        {
            color = 2; // not participating in test
        }
        MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &comm);
        MPI_Comm_rank(comm, &rank);

        if (color == 0)
        {
            std::cout << "Process wrank " << wrank << " rank " << rank
                      << " calls MainWriters " << std::endl;
            MainWriters(comm, p.npx_w, p.npy_w, steps, writer_sleeptime);
        }
        else if (color == 1)
        {
            std::cout << "Process wrank " << wrank << " rank " << rank
                      << " calls MainReaders " << std::endl;
            MainReaders(comm, p.npx_r, p.npy_r, reader_sleeptime);
        }
        std::cout << "Process wrank " << wrank << " rank " << rank
                  << " enters MPI barrier..." << std::endl;
        MPI_Barrier(MPI_COMM_WORLD);

        // Separate each individual test with a big gap in time
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
};

TEST_P(TestStagingMPMD, SingleStep)
{
    RunParams p = GetParam();
    TestCommon(p, 1, 0, 0);
}

TEST_P(TestStagingMPMD, MultipleSteps)
{
    RunParams p = GetParam();
    TestCommon(p, 10, 0, 0);
}

TEST_P(TestStagingMPMD, SlowWriter)
{
    RunParams p = GetParam();
    TestCommon(p, 5, 500, 0);
}

TEST_P(TestStagingMPMD, SlowReader)
{
    RunParams p = GetParam();
    TestCommon(p, 5, 0, 500);
}

INSTANTIATE_TEST_CASE_P(NxM, TestStagingMPMD,
                        ::testing::ValuesIn(CreateRunParams()));

//******************************************************************************
// main
//******************************************************************************

int main(int argc, char **argv)
{
    MPI_Init(&argc, &argv);
    ::testing::InitGoogleTest(&argc, argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

    engineName = std::string(argv[1]);

    if (!wrank)
    {
        std::cout << "Test " << engineName << " engine with " << numprocs
                  << " processes " << std::endl;
    }

    int result;
    result = RUN_ALL_TESTS();

    MPI_Finalize();
    return result;
}
<commit_msg>Fix bug introduced in staging tests<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 *  Created on: Jan 2018
 *      Author: Norbert Podhorszki
 */

#include <chrono>
#include <ios>      //std::ios_base::failure
#include <iostream> //std::cout
#include <numeric>
#include <stdexcept> //std::invalid_argument std::exception
#include <string>
#include <thread>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include <adios2.h>

static int numprocs, wrank;
std::string engineName; // comes from command line

struct RunParams
{
    /* 2D decomposition of processes
     * npx_w x npy_w Writers
     * npx_r x npy_r Readers
     */
    size_t npx_w;
    size_t npy_w;
    size_t npx_r;
    size_t npy_r;
    RunParams(size_t xw, size_t yw, size_t xr, size_t yr)
    : npx_w{xw}, npy_w{yw}, npx_r{xr}, npy_r{yr} {};
};

/* This function is executed by INSTANTIATE_TEST_CASE_P
   before main() and MPI_Init()!!! */
std::vector<RunParams> CreateRunParams()
{
    std::vector<RunParams> params;
    // 2 process test
    params.push_back(RunParams(1, 1, 1, 1));
    // 3 process tests
    params.push_back(RunParams(2, 1, 1, 1));
    params.push_back(RunParams(1, 2, 1, 1));
    params.push_back(RunParams(1, 1, 2, 1));
    params.push_back(RunParams(1, 1, 1, 2));
    // 4 process tests
    params.push_back(RunParams(2, 1, 2, 1));
    params.push_back(RunParams(2, 1, 1, 2));
    // 8 process tests
    params.push_back(RunParams(1, 1, 1, 7));
    params.push_back(RunParams(1, 7, 1, 1));
    params.push_back(RunParams(2, 2, 2, 2));
    // 16 process tests
    params.push_back(RunParams(3, 5, 1, 1));
    params.push_back(RunParams(1, 1, 5, 3));
    return params;
}

class TestStagingMPMD : public ::testing::TestWithParam<RunParams>
{
public:
    TestStagingMPMD() = default;
    const std::string streamName = "TestStream";

    void MainWriters(MPI_Comm comm, size_t npx, size_t npy, int steps,
                     unsigned int sleeptime)
    {
        int rank, nproc;
        MPI_Comm_rank(comm, &rank);
        MPI_Comm_size(comm, &nproc);
        if (!rank)
        {
            std::cout << "There are " << nproc << " Writers" << std::endl;
        }
        size_t ndx = 50;
        size_t ndy = 60;
        size_t gndx = npx * ndx;
        size_t gndy = npy * ndy;
        size_t posx = rank % npx;
        size_t posy = rank / npx;
        size_t offsx = posx * ndx;
        size_t offsy = posy * ndy;

        std::vector<float> myArray(ndx * ndy);

        adios2::ADIOS adios(comm);
        adios2::IO &io = adios.DeclareIO("writer");
        io.SetEngine(engineName);

        adios2::Variable<float> &varArray =
            io.DefineVariable<float>("myArray", {gndx, gndy}, {offsx, offsy},
                                     {ndx, ndy}, adios2::ConstantDims);

        adios2::Engine &writer = io.Open(streamName, adios2::Mode::Write, comm);

        for (size_t step = 0; step < steps; ++step)
        {
            size_t idx = 0;
            for (size_t x = 0; x < ndx; ++x)
            {
                for (size_t y = 0; y < ndy; ++y)
                {
                    myArray[idx] = GetValue(offsx + x, offsy + y, step);
                    ++idx;
                }
            }
            writer.BeginStep(adios2::StepMode::Append);
            writer.PutDeferred<float>(varArray, myArray.data());
            writer.EndStep();
            std::this_thread::sleep_for(std::chrono::milliseconds(sleeptime));
        }
        writer.Close();
    }

    /* encode position x,y as y.x floating point value in each array cell
     * add 1000*step to each value
     *
     * A 2 by 2 example with 3x3 local arrays
     *   0.0    0.001  0.002 |  0.003  0.004  0.005
     *   1.0    1.001  1.002 |  1.003  1.004  1.005
     *   2.0    2.001  2.002 |  2.003  2.004  2.005
     *   --------------------+---------------------
     *   3.0    3.001  3.002 |  3.003  3.004  3.005
     *   4.0    4.001  4.002 |  4.003  4.004  4.005
     *   5.0    5.001  5.002 |  5.003  5.004  5.005
     *
     * Next step each value is bigger by 1000
     */
    float GetValue(size_t offsx, size_t offsy, size_t step)
    {
        return 1000.0f * step + offsy + offsx / 1000.0f;
    }

    void CheckData(const std::vector<float> &array, size_t gndx, size_t gndy,
                   size_t offsx, size_t offsy, size_t ndx, size_t ndy,
                   size_t step, int rank)
    {
        size_t idx = 0;
        for (size_t x = 0; x < ndx; ++x)
        {
            for (size_t y = 0; y < ndy; ++y)
            {
                float expectedValue = GetValue(offsx + x, offsy + y, step);
                EXPECT_EQ(array[idx], expectedValue) <<
                    "Error in read, did not receive the expected value:"
                    << " rank " << rank << ", step " << step
                    << ", gdim {" << gndx << ',' << gndy << '}'
                    << ", offs {" << offsx << ',' << offsy << '}'
                    << ", ldim {" << ndx << ',' << ndy << '}'
                    << ", lpos {" << x << ',' << y << '}';
                ++idx;
            }
        }
    }

    void MainReaders(MPI_Comm comm, size_t npx, size_t npy,
                     unsigned int sleeptime)
    {
        int rank, nproc;
        MPI_Comm_rank(comm, &rank);
        MPI_Comm_size(comm, &nproc);
        if (!rank)
        {
            std::cout << "There are " << nproc << " Readers" << std::endl;
        }

        adios2::ADIOS adios(comm);
        adios2::IO &io = adios.DeclareIO("reader");
        io.SetEngine(engineName);
        adios2::Engine &reader = io.Open(streamName, adios2::Mode::Read, comm);

        size_t posx = rank % npx;
        size_t posy = rank / npx;
        size_t step = 0;
        adios2::Variable<float> *vMyArray = nullptr;
        std::vector<float> myArray;

        while (true)
        {
            adios2::StepStatus status =
                reader.BeginStep(adios2::StepMode::NextAvailable, 60.0f);
            if (status != adios2::StepStatus::OK)
            {
                break;
            }

            vMyArray = io.InquireVariable<float>("myArray");
            if (vMyArray == nullptr)
            {
                throw std::ios_base::failure("Missing 'myArray' variable.");
            }

            // 2D decomposition of global array reading
            size_t gndx = vMyArray->m_Shape[0];
            size_t gndy = vMyArray->m_Shape[1];
            size_t ndx = gndx / npx;
            size_t ndy = gndy / npy;
            size_t offsx = ndx * posx;
            size_t offsy = ndy * posy;
            if (posx == npx - 1)
            {
                // right-most processes need to read all the rest of rows
                ndx = gndx - ndx * (npx - 1);
            }

            if (posy == npy - 1)
            {
                // bottom processes need to read all the rest of columns
                ndy = gndy - ndy * (npy - 1);
            }

            adios2::Dims count({ndx, ndy});
            adios2::Dims start({offsx, offsy});

            vMyArray->SetSelection({start, count});
            size_t elementsSize = count[0] * count[1];
            myArray.resize(elementsSize);

            reader.GetDeferred(*vMyArray, myArray.data());
            reader.EndStep();
            CheckData(myArray, gndx, gndy, offsx, offsy, ndx, ndy, step, rank);
            std::this_thread::sleep_for(std::chrono::milliseconds(sleeptime));
            ++step;
        }
        reader.Close();
    }

    void TestCommon(RunParams p, int steps, unsigned int writer_sleeptime,
                    unsigned int reader_sleeptime)
    {
        std::cout << "test " << p.npx_w << "x" << p.npy_w << " writers "
                  << p.npx_r << "x" << p.npy_r << " readers " << std::endl;

        int nwriters = p.npx_w * p.npy_w;
        int nreaders = p.npx_r * p.npy_r;
        if (nwriters + nreaders > numprocs)
        {
            if (!wrank)
            {
                std::cout
                    << "skip test: writers+readers > available processors "
                    << std::endl;
            }
            return;
        }

        int rank;
        MPI_Comm comm;

        unsigned int color;
        if (wrank < nwriters)
        {
            color = 0; // writers
        }
        else if (wrank < nwriters + nreaders)
        {
            color = 1; // readers
        }
        else
        {
            color = 2; // not participating in test
        }
        MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &comm);
        MPI_Comm_rank(comm, &rank);

        if (color == 0)
        {
            std::cout << "Process wrank " << wrank << " rank " << rank
                      << " calls MainWriters " << std::endl;
            MainWriters(comm, p.npx_w, p.npy_w, steps, writer_sleeptime);
        }
        else if (color == 1)
        {
            std::cout << "Process wrank " << wrank << " rank " << rank
                      << " calls MainReaders " << std::endl;
            MainReaders(comm, p.npx_r, p.npy_r, reader_sleeptime);
        }
        std::cout << "Process wrank " << wrank << " rank " << rank
                  << " enters MPI barrier..." << std::endl;
        MPI_Barrier(MPI_COMM_WORLD);

        // Separate each individual test with a big gap in time
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
};

TEST_P(TestStagingMPMD, SingleStep)
{
    RunParams p = GetParam();
    TestCommon(p, 1, 0, 0);
}

TEST_P(TestStagingMPMD, MultipleSteps)
{
    RunParams p = GetParam();
    TestCommon(p, 10, 0, 0);
}

TEST_P(TestStagingMPMD, SlowWriter)
{
    RunParams p = GetParam();
    TestCommon(p, 5, 500, 0);
}

TEST_P(TestStagingMPMD, SlowReader)
{
    RunParams p = GetParam();
    TestCommon(p, 5, 0, 500);
}

INSTANTIATE_TEST_CASE_P(NxM, TestStagingMPMD,
                        ::testing::ValuesIn(CreateRunParams()));

//******************************************************************************
// main
//******************************************************************************

int main(int argc, char **argv)
{
    MPI_Init(&argc, &argv);
    ::testing::InitGoogleTest(&argc, argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

    engineName = std::string(argv[1]);

    if (!wrank)
    {
        std::cout << "Test " << engineName << " engine with " << numprocs
                  << " processes " << std::endl;
    }

    int result;
    result = RUN_ALL_TESTS();

    MPI_Finalize();
    return result;
}
<|endoftext|>


<commit_before>#include "Console.h"
#include <cstdio>
#include <cstdlib>
#ifdef LINUX_OR_APPLE
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#elif _WIN32
#include <conio.h>
#endif

ConsoleColor::ConsoleColor(const ConsoleColorType foreColor_, const ConsoleColorType backColor_,
                           const bool &foreIntensified_, const bool &backIntensified_)
: foreColor(foreColor_), backColor(backColor_),
foreIntensified(foreIntensified_), backIntensified(backIntensified_) {
}

#ifdef WIN32

WORD Console::setColor(const ConsoleColor &consoleColor) {
    WORD color = 0;
    switch (consoleColor.foreColor) {
        case WHITE:
            color |= FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE; break;
        case RED:
            color |= FOREGROUND_RED; break;
        case GREEN:
            color |= FOREGROUND_GREEN; break;
        case BLUE:
            color |= FOREGROUND_BLUE; break;
        case YELLOW:
            color |= FOREGROUND_RED | FOREGROUND_GREEN; break;
        case MAGENTA:
            color |= FOREGROUND_BLUE | FOREGROUND_RED; break;
        case CYAN:
            color |= FOREGROUND_BLUE | FOREGROUND_GREEN; break;
        case BLACK:
        default:
            break;
    }
    if (consoleColor.foreIntensified) {
        color |= FOREGROUND_INTENSITY;
    }
    switch (consoleColor.backColor) {
        case WHITE:
            color |= BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE; break;
        case RED:
            color |= BACKGROUND_RED; break;
        case GREEN:
            color |= BACKGROUND_GREEN; break;
        case BLUE:
            color |= BACKGROUND_BLUE; break;
        case YELLOW:
            color |= BACKGROUND_RED | BACKGROUND_GREEN; break;
        case MAGENTA:
            color |= BACKGROUND_BLUE | BACKGROUND_RED; break;
        case CYAN:
            color |= BACKGROUND_BLUE | BACKGROUND_GREEN; break;
        case BLACK:
        default:
            break;
    }
    if (consoleColor.backIntensified) {
        color |= BACKGROUND_INTENSITY;
    }

    // Get origin attribute
    CONSOLE_SCREEN_BUFFER_INFO info;
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hStdout, &info);
    WORD originAttr = info.wAttributes;

    // Set new attribute
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hout, color);

    // Return the origin attribute
    return originAttr;
}

void Console::resetColor(const WORD &attr) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr);
}

#endif

void Console::setCursor(const int &x, const int &y) {
#ifdef LINUX_OR_APPLE
    printf("\033[%d;%dH", y + 1, x);  // Param: row and col
#elif _WIN32
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD coord;
    coord.X = x;
    coord.Y = y;
    SetConsoleCursorPosition(hout, coord);
#else
    // Other platforms
#endif
}

void Console::clear() {
#ifdef LINUX_OR_APPLE
    system("clear");
#elif _WIN32
    system("cls");
#else
    // Other platforms
#endif
}

void Console::write(const std::string &str) {
    printf("%s", str.c_str());
}

void Console::writeWithColor(const std::string &str, const ConsoleColor &consoleColor) {
#ifdef LINUX_OR_APPLE
    int fore = -1, back = -1;
    switch (consoleColor.backColor) {
        case WHITE:
            back = 47; break;
        case RED:
            back = 41; break;
        case GREEN:
            back = 42; break;
        case BLUE:
            back = 44; break;
        case YELLOW:
            back = 43; break;
        case MAGENTA:
            back = 45; break;
        case CYAN:
            back = 46; break;
        case BLACK:
            back = 40; break;
        default:
            break;
    }
    switch (consoleColor.foreColor) {
        case WHITE:
            fore = 37; break;
        case RED:
            fore = 31; break;
        case GREEN:
            fore = 32; break;
        case BLUE:
            fore = 34; break;
        case YELLOW:
            fore = 33; break;
        case MAGENTA:
            fore = 35; break;
        case CYAN:
            fore = 36; break;
        case BLACK:
            fore = 30; break;
        default:
            break;
    }
    if (fore != -1 && back != -1) {
        printf("\033[%d;%dm%s\033[0m", fore, back, str.c_str());
    }
#elif _WIN32
    WORD originAttr = setColor(consoleColor);
    printf("%s", str.c_str());
    resetColor(originAttr);  // Reset to origin output color
#else
    // Other platforms
#endif
}

char Console::getch() {
#ifdef LINUX_OR_APPLE
    struct termios oldattr, newattr;
    int ch;
    tcgetattr(STDIN_FILENO, &oldattr);
    newattr = oldattr;
    newattr.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
    return ch;
#elif _WIN32
    return _getch();
#else
    // Other platforms
#endif
}

int Console::kbhit() {
#ifdef LINUX_OR_APPLE
    struct termios oldt, newt;
    int ch;
    int oldf;

    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

    ch = getchar();

    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    fcntl(STDIN_FILENO, F_SETFL, oldf);

    if (ch != EOF) {
        ungetc(ch, stdin);
        return 1;
    }

    return 0;
#elif _WIN32
    return _kbhit();
#else
    // Other platforms
#endif
}
<commit_msg>Fix system() warnings<commit_after>#include "Console.h"
#include <cstdio>
#include <cstdlib>
#ifdef LINUX_OR_APPLE
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#elif _WIN32
#include <conio.h>
#endif

ConsoleColor::ConsoleColor(const ConsoleColorType foreColor_, const ConsoleColorType backColor_,
                           const bool &foreIntensified_, const bool &backIntensified_)
: foreColor(foreColor_), backColor(backColor_),
foreIntensified(foreIntensified_), backIntensified(backIntensified_) {
}

#ifdef WIN32

WORD Console::setColor(const ConsoleColor &consoleColor) {
    WORD color = 0;
    switch (consoleColor.foreColor) {
        case WHITE:
            color |= FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE; break;
        case RED:
            color |= FOREGROUND_RED; break;
        case GREEN:
            color |= FOREGROUND_GREEN; break;
        case BLUE:
            color |= FOREGROUND_BLUE; break;
        case YELLOW:
            color |= FOREGROUND_RED | FOREGROUND_GREEN; break;
        case MAGENTA:
            color |= FOREGROUND_BLUE | FOREGROUND_RED; break;
        case CYAN:
            color |= FOREGROUND_BLUE | FOREGROUND_GREEN; break;
        case BLACK:
        default:
            break;
    }
    if (consoleColor.foreIntensified) {
        color |= FOREGROUND_INTENSITY;
    }
    switch (consoleColor.backColor) {
        case WHITE:
            color |= BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE; break;
        case RED:
            color |= BACKGROUND_RED; break;
        case GREEN:
            color |= BACKGROUND_GREEN; break;
        case BLUE:
            color |= BACKGROUND_BLUE; break;
        case YELLOW:
            color |= BACKGROUND_RED | BACKGROUND_GREEN; break;
        case MAGENTA:
            color |= BACKGROUND_BLUE | BACKGROUND_RED; break;
        case CYAN:
            color |= BACKGROUND_BLUE | BACKGROUND_GREEN; break;
        case BLACK:
        default:
            break;
    }
    if (consoleColor.backIntensified) {
        color |= BACKGROUND_INTENSITY;
    }

    // Get origin attribute
    CONSOLE_SCREEN_BUFFER_INFO info;
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hStdout, &info);
    WORD originAttr = info.wAttributes;

    // Set new attribute
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hout, color);

    // Return the origin attribute
    return originAttr;
}

void Console::resetColor(const WORD &attr) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr);
}

#endif

void Console::setCursor(const int &x, const int &y) {
#ifdef LINUX_OR_APPLE
    printf("\033[%d;%dH", y + 1, x);  // Param: row and col
#elif _WIN32
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD coord;
    coord.X = x;
    coord.Y = y;
    SetConsoleCursorPosition(hout, coord);
#else
    // Other platforms
#endif
}

void Console::clear() {
#ifdef LINUX_OR_APPLE
    if (system("clear")) {}
#elif _WIN32
    if (system("cls")) {}
#else
    // Other platforms
#endif
}

void Console::write(const std::string &str) {
    printf("%s", str.c_str());
}

void Console::writeWithColor(const std::string &str, const ConsoleColor &consoleColor) {
#ifdef LINUX_OR_APPLE
    int fore = -1, back = -1;
    switch (consoleColor.backColor) {
        case WHITE:
            back = 47; break;
        case RED:
            back = 41; break;
        case GREEN:
            back = 42; break;
        case BLUE:
            back = 44; break;
        case YELLOW:
            back = 43; break;
        case MAGENTA:
            back = 45; break;
        case CYAN:
            back = 46; break;
        case BLACK:
            back = 40; break;
        default:
            break;
    }
    switch (consoleColor.foreColor) {
        case WHITE:
            fore = 37; break;
        case RED:
            fore = 31; break;
        case GREEN:
            fore = 32; break;
        case BLUE:
            fore = 34; break;
        case YELLOW:
            fore = 33; break;
        case MAGENTA:
            fore = 35; break;
        case CYAN:
            fore = 36; break;
        case BLACK:
            fore = 30; break;
        default:
            break;
    }
    if (fore != -1 && back != -1) {
        printf("\033[%d;%dm%s\033[0m", fore, back, str.c_str());
    }
#elif _WIN32
    WORD originAttr = setColor(consoleColor);
    printf("%s", str.c_str());
    resetColor(originAttr);  // Reset to origin output color
#else
    // Other platforms
#endif
}

char Console::getch() {
#ifdef LINUX_OR_APPLE
    struct termios oldattr, newattr;
    int ch;
    tcgetattr(STDIN_FILENO, &oldattr);
    newattr = oldattr;
    newattr.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
    return ch;
#elif _WIN32
    return _getch();
#else
    // Other platforms
#endif
}

int Console::kbhit() {
#ifdef LINUX_OR_APPLE
    struct termios oldt, newt;
    int ch;
    int oldf;

    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

    ch = getchar();

    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    fcntl(STDIN_FILENO, F_SETFL, oldf);

    if (ch != EOF) {
        ungetc(ch, stdin);
        return 1;
    }

    return 0;
#elif _WIN32
    return _kbhit();
#else
    // Other platforms
#endif
}
<|endoftext|>


<commit_before>/*  cbr
 *  Context.hpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of cbr nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * 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.
 */

#ifndef _CBR_CONTEXT_HPP_
#define _CBR_CONTEXT_HPP_

#include "Utility.hpp"
#include "Timer.hpp"
#include "TimeProfiler.hpp"
#include "PollingService.hpp"

namespace CBR {

class Trace;

/** Base class for Contexts, provides basic infrastructure such as IOServices,
 *  IOStrands, Trace, and timing information.
 */
class Context {
public:
    Context(const String& name, IOService* ios, IOStrand* strand, Trace* _trace, const Time& epoch, const Duration& simlen)
     : ioService(ios),
       mainStrand(strand),
       profiler( new TimeProfiler(name) ),
       mTrace(_trace),
       mEpoch(epoch),
       mLastSimTime(Time::null()),
       mSimDuration(simlen)
    {
    }

    ~Context() {
    }

    Time epoch() const {
        return mEpoch.read();
    }
    Duration sinceEpoch(const Time& rawtime) const {
        return rawtime - mEpoch.read();
    }
    Time simTime(const Duration& sinceStart) const {
        return Time::null() + sinceStart;
    }
    Time simTime(const Time& rawTime) const {
        return simTime( sinceEpoch(rawTime) );
    }
    // WARNING: The evaluates Timer::now, which shouldn't be done too often
    Time simTime() const {
        Time curt = simTime( Timer::now() );

        if (curt < mLastSimTime)
            curt = mLastSimTime;

        // FIXME this is to avoid const fallout since this didn't used to
        // need to modify data
        const_cast<Time&>(this->mLastSimTime) = curt;

        return curt;
    }

    void add(Service* ps) {
        mServices.push_back(ps);
        ps->start();
    }

    void run(uint32 nthreads = 1) {
        std::vector<Thread*> workerThreads;

        // Start workers
        for(uint32 i = 1; i < nthreads; i++) {
            workerThreads.push_back(
                new Thread( std::tr1::bind(&IOService::run, ioService) )
            );
        }

        // Run
        ioService->run();

        // Wait for workers to finish
        for(uint32 i = 0; i < workerThreads.size(); i++) {
            workerThreads[i]->join();
            delete workerThreads[i];
        }
        workerThreads.clear();
    }

    Trace* trace() const {
        return mTrace;
    }

    IOService* ioService;
    IOStrand* mainStrand;
    TimeProfiler* profiler;
protected:
    Trace* mTrace;

    Sirikata::AtomicValue<Time> mEpoch;
    Time mLastSimTime;
    Duration mSimDuration;
    std::vector<Service*> mServices;
}; // class ObjectHostContext

} // namespace CBR

#endif //_CBR_CONTEXT_HPP_
<commit_msg>Reverting monotonic timer fix since it seems to introduce a mysterious bug that I can't track down.<commit_after>/*  cbr
 *  Context.hpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of cbr nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * 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.
 */

#ifndef _CBR_CONTEXT_HPP_
#define _CBR_CONTEXT_HPP_

#include "Utility.hpp"
#include "Timer.hpp"
#include "TimeProfiler.hpp"
#include "PollingService.hpp"

namespace CBR {

class Trace;

/** Base class for Contexts, provides basic infrastructure such as IOServices,
 *  IOStrands, Trace, and timing information.
 */
class Context {
public:
    Context(const String& name, IOService* ios, IOStrand* strand, Trace* _trace, const Time& epoch, const Duration& simlen)
     : ioService(ios),
       mainStrand(strand),
       profiler( new TimeProfiler(name) ),
       mTrace(_trace),
       mEpoch(epoch),
       mLastSimTime(Time::null()),
       mSimDuration(simlen)
    {
    }

    ~Context() {
    }

    Time epoch() const {
        return mEpoch.read();
    }
    Duration sinceEpoch(const Time& rawtime) const {
        return rawtime - mEpoch.read();
    }
    Time simTime(const Duration& sinceStart) const {
        return Time::null() + sinceStart;
    }
    Time simTime(const Time& rawTime) const {
        return simTime( sinceEpoch(rawTime) );
    }
    // WARNING: The evaluates Timer::now, which shouldn't be done too often
    Time simTime() const {
        Time curt = simTime( Timer::now() );

#if 0
        Time last = mLastSimTime.read();
        if (curt < last)
            curt = last;

        // FIXME this is to avoid const fallout since this didn't used to
        // need to modify data
        const_cast< Sirikata::AtomicValue<Time>& >(this->mLastSimTime) = curt;
#endif
        return curt;
    }

    void add(Service* ps) {
        mServices.push_back(ps);
        ps->start();
    }

    void run(uint32 nthreads = 1) {
        std::vector<Thread*> workerThreads;

        // Start workers
        for(uint32 i = 1; i < nthreads; i++) {
            workerThreads.push_back(
                new Thread( std::tr1::bind(&IOService::run, ioService) )
            );
        }

        // Run
        ioService->run();

        // Wait for workers to finish
        for(uint32 i = 0; i < workerThreads.size(); i++) {
            workerThreads[i]->join();
            delete workerThreads[i];
        }
        workerThreads.clear();
    }

    Trace* trace() const {
        return mTrace;
    }

    IOService* ioService;
    IOStrand* mainStrand;
    TimeProfiler* profiler;
protected:
    Trace* mTrace;

    Sirikata::AtomicValue<Time> mEpoch;
    Sirikata::AtomicValue<Time> mLastSimTime;
    Duration mSimDuration;
    std::vector<Service*> mServices;
}; // class ObjectHostContext

} // namespace CBR

#endif //_CBR_CONTEXT_HPP_
<|endoftext|>