<commit_before>//===- Reassociate.cpp - Reassociate binary expressions -------------------===//
//
// This pass reassociates commutative expressions in an order that is designed
// to promote better constant propogation, GCSE, LICM, PRE...
//
// For example: 4 + (x + 5) -> x + (4 + 5)
//
// Note that this pass works best if left shifts have been promoted to explicit
// multiplies before this pass executes.
//
// In the implementation of this algorithm, constants are assigned rank = 0,
// function arguments are rank = 1, and other values are assigned ranks
// corresponding to the reverse post order traversal of current function
// (starting at 2), which effectively gives values in deep loops higher rank
// than values not in loops.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/iOperators.h"
#include "llvm/Type.h"
#include "llvm/Pass.h"
#include "llvm/Constant.h"
#include "llvm/Support/CFG.h"
#include "Support/PostOrderIterator.h"

namespace {
  class Reassociate : public FunctionPass {
    map<BasicBlock*, unsigned> RankMap;
  public:
    const char *getPassName() const {
      return "Expression Reassociation";
    }

    bool runOnFunction(Function *F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.preservesCFG();
    }
  private:
    void BuildRankMap(Function *F);
    unsigned getRank(Value *V);
    bool ReassociateExpr(BinaryOperator *I);
    bool ReassociateBB(BasicBlock *BB);
  };
}

Pass *createReassociatePass() { return new Reassociate(); }

void Reassociate::BuildRankMap(Function *F) {
  unsigned i = 1;
  ReversePostOrderTraversal<Function*> RPOT(F);
  for (ReversePostOrderTraversal<Function*>::rpo_iterator I = RPOT.begin(),
         E = RPOT.end(); I != E; ++I)
    RankMap[*I] = ++i;
}

unsigned Reassociate::getRank(Value *V) {
  if (isa<Argument>(V)) return 1;   // Function argument...
  if (Instruction *I = dyn_cast<Instruction>(V)) {
    // If this is an expression, return the MAX(rank(LHS), rank(RHS)) so that we
    // can reassociate expressions for code motion!  Since we do not recurse for
    // PHI nodes, we cannot have infinite recursion here, because there cannot
    // be loops in the value graph (except for PHI nodes).
    //
    if (I->getOpcode() == Instruction::PHINode ||
        I->getOpcode() == Instruction::Alloca ||
        I->getOpcode() == Instruction::Malloc || isa<TerminatorInst>(I) ||
        I->hasSideEffects())
      return RankMap[I->getParent()];

    unsigned Rank = 0;
    for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
      Rank = std::max(Rank, getRank(I->getOperand(i)));

    return Rank;
  }

  // Otherwise it's a global or constant, rank 0.
  return 0;
}

// isCommutativeOperator - Return true if the specified instruction is
// commutative and associative.  If the instruction is not commutative and
// associative, we can not reorder its operands!
//
static inline BinaryOperator *isCommutativeOperator(Instruction *I) {
  // Floating point operations do not commute!
  if (I->getType()->isFloatingPoint()) return 0;

  if (I->getOpcode() == Instruction::Add ||
      I->getOpcode() == Instruction::Mul ||
      I->getOpcode() == Instruction::And ||
      I->getOpcode() == Instruction::Or  ||
      I->getOpcode() == Instruction::Xor)
    return cast<BinaryOperator>(I);
  return 0;
}

bool Reassociate::ReassociateExpr(BinaryOperator *I) {
  Value *LHS = I->getOperand(0);
  Value *RHS = I->getOperand(1);
  unsigned LHSRank = getRank(LHS);
  unsigned RHSRank = getRank(RHS);

  bool Changed = false;

  // Make sure the LHS of the operand always has the greater rank...
  if (LHSRank < RHSRank) {
    I->swapOperands();
    std::swap(LHS, RHS);
    std::swap(LHSRank, RHSRank);
    Changed = true;
    //cerr << "Transposed: " << I << " Result BB: " << I->getParent();
  }

  // If the LHS is the same operator as the current one is, and if we are the
  // only expression using it...
  //
  if (BinaryOperator *LHSI = dyn_cast<BinaryOperator>(LHS))
    if (LHSI->getOpcode() == I->getOpcode() && LHSI->use_size() == 1) {
      // If the rank of our current RHS is less than the rank of the LHS's LHS,
      // then we reassociate the two instructions...
      if (RHSRank < getRank(LHSI->getOperand(0))) {
        unsigned TakeOp = 0;
        if (BinaryOperator *IOp = dyn_cast<BinaryOperator>(LHSI->getOperand(0)))
          if (IOp->getOpcode() == LHSI->getOpcode())
            TakeOp = 1;   // Hoist out non-tree portion

        // Convert ((a + 12) + 10) into (a + (12 + 10))
        I->setOperand(0, LHSI->getOperand(TakeOp));
        LHSI->setOperand(TakeOp, RHS);
        I->setOperand(1, LHSI);

        //cerr << "Reassociated: " << I << " Result BB: " << I->getParent();

        // Since we modified the RHS instruction, make sure that we recheck it.
        ReassociateExpr(LHSI);
        return true;
      }
    }

  return Changed;
}

bool Reassociate::ReassociateBB(BasicBlock *BB) {
  bool Changed = false;
  for (BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI) {
    Instruction *Inst = *BI;

    // If this instruction is a commutative binary operator, and the ranks of
    // the two operands are sorted incorrectly, fix it now.
    //
    if (BinaryOperator *I = isCommutativeOperator(Inst)) {
      // Make sure that this expression is correctly reassociated with respect
      // to it's used values...
      //
      Changed |= ReassociateExpr(I);

    } else if (Inst->getOpcode() == Instruction::Sub &&
               Inst->getOperand(0) != Constant::getNullValue(Inst->getType())) {
      // Convert a subtract into an add and a neg instruction... so that sub
      // instructions can be commuted with other add instructions...
      //
      Instruction *New = BinaryOperator::create(Instruction::Add,
                                                Inst->getOperand(0), Inst,
                                                Inst->getName()+".add");
      // Everyone now refers to the add instruction...
      Inst->replaceAllUsesWith(New);
      New->setOperand(1, Inst);        // Except for the add inst itself!

      BI = BB->getInstList().insert(BI+1, New)-1;  // Add to the basic block...
      Inst->setOperand(0, Constant::getNullValue(Inst->getType()));
      Changed = true;
    }
  }

  return Changed;
}

bool Reassociate::runOnFunction(Function *F) {
  // Recalculate the rank map for F
  BuildRankMap(F);

  bool Changed = false;
  for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
    Changed |= ReassociateBB(*FI);

  // We are done with the rank map...
  RankMap.clear();
  return Changed;
}
<commit_msg>Give the longer name to the instruction that will probably be eliminated later<commit_after>//===- Reassociate.cpp - Reassociate binary expressions -------------------===//
//
// This pass reassociates commutative expressions in an order that is designed
// to promote better constant propogation, GCSE, LICM, PRE...
//
// For example: 4 + (x + 5) -> x + (4 + 5)
//
// Note that this pass works best if left shifts have been promoted to explicit
// multiplies before this pass executes.
//
// In the implementation of this algorithm, constants are assigned rank = 0,
// function arguments are rank = 1, and other values are assigned ranks
// corresponding to the reverse post order traversal of current function
// (starting at 2), which effectively gives values in deep loops higher rank
// than values not in loops.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/iOperators.h"
#include "llvm/Type.h"
#include "llvm/Pass.h"
#include "llvm/Constant.h"
#include "llvm/Support/CFG.h"
#include "Support/PostOrderIterator.h"

namespace {
  class Reassociate : public FunctionPass {
    map<BasicBlock*, unsigned> RankMap;
  public:
    const char *getPassName() const {
      return "Expression Reassociation";
    }

    bool runOnFunction(Function *F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.preservesCFG();
    }
  private:
    void BuildRankMap(Function *F);
    unsigned getRank(Value *V);
    bool ReassociateExpr(BinaryOperator *I);
    bool ReassociateBB(BasicBlock *BB);
  };
}

Pass *createReassociatePass() { return new Reassociate(); }

void Reassociate::BuildRankMap(Function *F) {
  unsigned i = 1;
  ReversePostOrderTraversal<Function*> RPOT(F);
  for (ReversePostOrderTraversal<Function*>::rpo_iterator I = RPOT.begin(),
         E = RPOT.end(); I != E; ++I)
    RankMap[*I] = ++i;
}

unsigned Reassociate::getRank(Value *V) {
  if (isa<Argument>(V)) return 1;   // Function argument...
  if (Instruction *I = dyn_cast<Instruction>(V)) {
    // If this is an expression, return the MAX(rank(LHS), rank(RHS)) so that we
    // can reassociate expressions for code motion!  Since we do not recurse for
    // PHI nodes, we cannot have infinite recursion here, because there cannot
    // be loops in the value graph (except for PHI nodes).
    //
    if (I->getOpcode() == Instruction::PHINode ||
        I->getOpcode() == Instruction::Alloca ||
        I->getOpcode() == Instruction::Malloc || isa<TerminatorInst>(I) ||
        I->hasSideEffects())
      return RankMap[I->getParent()];

    unsigned Rank = 0;
    for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
      Rank = std::max(Rank, getRank(I->getOperand(i)));

    return Rank;
  }

  // Otherwise it's a global or constant, rank 0.
  return 0;
}

// isCommutativeOperator - Return true if the specified instruction is
// commutative and associative.  If the instruction is not commutative and
// associative, we can not reorder its operands!
//
static inline BinaryOperator *isCommutativeOperator(Instruction *I) {
  // Floating point operations do not commute!
  if (I->getType()->isFloatingPoint()) return 0;

  if (I->getOpcode() == Instruction::Add ||
      I->getOpcode() == Instruction::Mul ||
      I->getOpcode() == Instruction::And ||
      I->getOpcode() == Instruction::Or  ||
      I->getOpcode() == Instruction::Xor)
    return cast<BinaryOperator>(I);
  return 0;
}

bool Reassociate::ReassociateExpr(BinaryOperator *I) {
  Value *LHS = I->getOperand(0);
  Value *RHS = I->getOperand(1);
  unsigned LHSRank = getRank(LHS);
  unsigned RHSRank = getRank(RHS);

  bool Changed = false;

  // Make sure the LHS of the operand always has the greater rank...
  if (LHSRank < RHSRank) {
    I->swapOperands();
    std::swap(LHS, RHS);
    std::swap(LHSRank, RHSRank);
    Changed = true;
    //cerr << "Transposed: " << I << " Result BB: " << I->getParent();
  }

  // If the LHS is the same operator as the current one is, and if we are the
  // only expression using it...
  //
  if (BinaryOperator *LHSI = dyn_cast<BinaryOperator>(LHS))
    if (LHSI->getOpcode() == I->getOpcode() && LHSI->use_size() == 1) {
      // If the rank of our current RHS is less than the rank of the LHS's LHS,
      // then we reassociate the two instructions...
      if (RHSRank < getRank(LHSI->getOperand(0))) {
        unsigned TakeOp = 0;
        if (BinaryOperator *IOp = dyn_cast<BinaryOperator>(LHSI->getOperand(0)))
          if (IOp->getOpcode() == LHSI->getOpcode())
            TakeOp = 1;   // Hoist out non-tree portion

        // Convert ((a + 12) + 10) into (a + (12 + 10))
        I->setOperand(0, LHSI->getOperand(TakeOp));
        LHSI->setOperand(TakeOp, RHS);
        I->setOperand(1, LHSI);

        //cerr << "Reassociated: " << I << " Result BB: " << I->getParent();

        // Since we modified the RHS instruction, make sure that we recheck it.
        ReassociateExpr(LHSI);
        return true;
      }
    }

  return Changed;
}

bool Reassociate::ReassociateBB(BasicBlock *BB) {
  bool Changed = false;
  for (BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI) {
    Instruction *Inst = *BI;

    // If this instruction is a commutative binary operator, and the ranks of
    // the two operands are sorted incorrectly, fix it now.
    //
    if (BinaryOperator *I = isCommutativeOperator(Inst)) {
      // Make sure that this expression is correctly reassociated with respect
      // to it's used values...
      //
      Changed |= ReassociateExpr(I);

    } else if (Inst->getOpcode() == Instruction::Sub &&
               Inst->getOperand(0) != Constant::getNullValue(Inst->getType())) {
      // Convert a subtract into an add and a neg instruction... so that sub
      // instructions can be commuted with other add instructions...
      //
      Instruction *New = BinaryOperator::create(Instruction::Add,
                                                Inst->getOperand(0), Inst,
                                                Inst->getName());
      // Everyone now refers to the add instruction...
      Inst->replaceAllUsesWith(New);
      Inst->setName(Inst->getOperand(1)->getName()+".neg");
      New->setOperand(1, Inst);        // Except for the add inst itself!

      BI = BB->getInstList().insert(BI+1, New)-1;  // Add to the basic block...
      Inst->setOperand(0, Constant::getNullValue(Inst->getType()));
      Changed = true;
    }
  }

  return Changed;
}

bool Reassociate::runOnFunction(Function *F) {
  // Recalculate the rank map for F
  BuildRankMap(F);

  bool Changed = false;
  for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
    Changed |= ReassociateBB(*FI);

  // We are done with the rank map...
  RankMap.clear();
  return Changed;
}
<|endoftext|>


<commit_before>/*
    This file is part of cpp-ethereum.

    cpp-ethereum is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    cpp-ethereum is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Christian <c@ethdev.com>
 * @date 2014
 * Unit tests for the name and type resolution of the solidity parser.
 */

#include <string>

#include <libdevcore/Log.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Parser.h>
#include <libsolidity/NameAndTypeResolver.h>
#include <libsolidity/Exceptions.h>
#include <boost/test/unit_test.hpp>

namespace dev
{
namespace solidity
{
namespace test
{

namespace
{
void parseTextAndResolveNames(std::string const& _source)
{
	Parser parser;
	ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
	NameAndTypeResolver resolver({});
	resolver.registerDeclarations(*sourceUnit);
	for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
		if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
			resolver.resolveNamesAndTypes(*contract);
}
}

BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution)

BOOST_AUTO_TEST_CASE(smoke_test)
{
	char const* text = "contract test {\n"
					   "  uint256 stateVariable1;\n"
					   "  function fun(uint256 arg1) { var x; uint256 y; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(double_stateVariable_declaration)
{
	char const* text = "contract test {\n"
					   "  uint256 variable;\n"
					   "  uint128 variable;\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
}

BOOST_AUTO_TEST_CASE(double_function_declaration)
{
	char const* text = "contract test {\n"
					   "  function fun() { var x; }\n"
					   "  function fun() { var x; }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
}

BOOST_AUTO_TEST_CASE(double_variable_declaration)
{
	char const* text = "contract test {\n"
					   "  function f() { uint256 x; if (true)  { uint256 x; } }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
}

BOOST_AUTO_TEST_CASE(name_shadowing)
{
	char const* text = "contract test {\n"
					   "  uint256 variable;\n"
					   "  function f() { uint32 variable ; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(name_references)
{
	char const* text = "contract test {\n"
					   "  uint256 variable;\n"
					   "  function f(uint256 arg) returns (uint out) { f(variable); test; out; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(undeclared_name)
{
	char const* text = "contract test {\n"
					   "  uint256 variable;\n"
					   "  function f(uint256 arg) { f(notfound); }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
}

BOOST_AUTO_TEST_CASE(reference_to_later_declaration)
{
	char const* text = "contract test {\n"
					   "  function g() { f(); }"
					   "  function f() {  }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive)
{
	char const* text = "contract test {\n"
					   "  struct MyStructName {\n"
					   "    address addr;\n"
					   "    MyStructName x;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError);
}

BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
{
	char const* text = "contract test {\n"
					   "  struct MyStructName1 {\n"
					   "    address addr;\n"
					   "    uint256 count;\n"
					   "    MyStructName2 x;\n"
					   "  }\n"
					   "  struct MyStructName2 {\n"
					   "    MyStructName1 x;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError);
}

BOOST_AUTO_TEST_CASE(struct_definition_recursion_via_mapping)
{
	char const* text = "contract test {\n"
					   "  struct MyStructName1 {\n"
					   "    address addr;\n"
					   "    uint256 count;\n"
					   "    mapping(uint => MyStructName1) x;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_inference_smoke_test)
{
	char const* text = "contract test {\n"
					   "  function f(uint256 arg1, uint32 arg2) returns (bool ret) { var x = arg1 + arg2 == 8; ret = x; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_checking_return)
{
	char const* text = "contract test {\n"
					   "  function f() returns (bool r) { return 1 >= 2; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number)
{
	char const* text = "contract test {\n"
					   "  function f() returns (bool r1, bool r2) { return 1 >= 2; }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type)
{
	char const* text = "contract test {\n"
					   "  function f() returns (uint256 r) { return 1 >= 2; }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(type_checking_function_call)
{
	char const* text = "contract test {\n"
					   "  function f() returns (bool r) { return g(12, true) == 3; }\n"
					   "  function g(uint256 a, bool b) returns (uint256 r) { }\n"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_conversion_for_comparison)
{
	char const* text = "contract test {\n"
					   "  function f() { uint32(2) == int64(2); }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid)
{
	char const* text = "contract test {\n"
					   "  function f() { int32(2) == uint64(2); }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion)
{
	char const* text = "contract test {\n"
					   "  function f() returns (int256 r) { var x = int256(uint32(2)); return x; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(balance)
{
	char const* text = "contract test {\n"
					   "  function fun() {\n"
					   "    uint256 x = address(0).balance;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(balance_invalid)
{
	char const* text = "contract test {\n"
					   "  function fun() {\n"
					   "    address(0).balance = 7;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(assignment_to_mapping)
{
	char const* text = "contract test {\n"
					   "  struct str {\n"
					   "    mapping(uint=>uint) map;\n"
					   "  }\n"
					   "  str data;"
					   "  function fun() {\n"
					   "    var a = data.map;\n"
					   "    data.map = a;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(assignment_to_struct)
{
	char const* text = "contract test {\n"
					   "  struct str {\n"
					   "    mapping(uint=>uint) map;\n"
					   "  }\n"
					   "  str data;"
					   "  function fun() {\n"
					   "    var a = data;\n"
					   "    data = a;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_SUITE_END()

}
}
} // end namespaces

<commit_msg>Tests for empty and too long strings.<commit_after>/*
    This file is part of cpp-ethereum.

    cpp-ethereum is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    cpp-ethereum is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Christian <c@ethdev.com>
 * @date 2014
 * Unit tests for the name and type resolution of the solidity parser.
 */

#include <string>

#include <libdevcore/Log.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Parser.h>
#include <libsolidity/NameAndTypeResolver.h>
#include <libsolidity/Exceptions.h>
#include <boost/test/unit_test.hpp>

namespace dev
{
namespace solidity
{
namespace test
{

namespace
{
void parseTextAndResolveNames(std::string const& _source)
{
	Parser parser;
	ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
	NameAndTypeResolver resolver({});
	resolver.registerDeclarations(*sourceUnit);
	for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
		if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
			resolver.resolveNamesAndTypes(*contract);
}
}

BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution)

BOOST_AUTO_TEST_CASE(smoke_test)
{
	char const* text = "contract test {\n"
					   "  uint256 stateVariable1;\n"
					   "  function fun(uint256 arg1) { var x; uint256 y; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(double_stateVariable_declaration)
{
	char const* text = "contract test {\n"
					   "  uint256 variable;\n"
					   "  uint128 variable;\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
}

BOOST_AUTO_TEST_CASE(double_function_declaration)
{
	char const* text = "contract test {\n"
					   "  function fun() { var x; }\n"
					   "  function fun() { var x; }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
}

BOOST_AUTO_TEST_CASE(double_variable_declaration)
{
	char const* text = "contract test {\n"
					   "  function f() { uint256 x; if (true)  { uint256 x; } }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
}

BOOST_AUTO_TEST_CASE(name_shadowing)
{
	char const* text = "contract test {\n"
					   "  uint256 variable;\n"
					   "  function f() { uint32 variable ; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(name_references)
{
	char const* text = "contract test {\n"
					   "  uint256 variable;\n"
					   "  function f(uint256 arg) returns (uint out) { f(variable); test; out; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(undeclared_name)
{
	char const* text = "contract test {\n"
					   "  uint256 variable;\n"
					   "  function f(uint256 arg) { f(notfound); }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
}

BOOST_AUTO_TEST_CASE(reference_to_later_declaration)
{
	char const* text = "contract test {\n"
					   "  function g() { f(); }"
					   "  function f() {  }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive)
{
	char const* text = "contract test {\n"
					   "  struct MyStructName {\n"
					   "    address addr;\n"
					   "    MyStructName x;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError);
}

BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
{
	char const* text = "contract test {\n"
					   "  struct MyStructName1 {\n"
					   "    address addr;\n"
					   "    uint256 count;\n"
					   "    MyStructName2 x;\n"
					   "  }\n"
					   "  struct MyStructName2 {\n"
					   "    MyStructName1 x;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError);
}

BOOST_AUTO_TEST_CASE(struct_definition_recursion_via_mapping)
{
	char const* text = "contract test {\n"
					   "  struct MyStructName1 {\n"
					   "    address addr;\n"
					   "    uint256 count;\n"
					   "    mapping(uint => MyStructName1) x;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_inference_smoke_test)
{
	char const* text = "contract test {\n"
					   "  function f(uint256 arg1, uint32 arg2) returns (bool ret) { var x = arg1 + arg2 == 8; ret = x; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_checking_return)
{
	char const* text = "contract test {\n"
					   "  function f() returns (bool r) { return 1 >= 2; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number)
{
	char const* text = "contract test {\n"
					   "  function f() returns (bool r1, bool r2) { return 1 >= 2; }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type)
{
	char const* text = "contract test {\n"
					   "  function f() returns (uint256 r) { return 1 >= 2; }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(type_checking_function_call)
{
	char const* text = "contract test {\n"
					   "  function f() returns (bool r) { return g(12, true) == 3; }\n"
					   "  function g(uint256 a, bool b) returns (uint256 r) { }\n"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_conversion_for_comparison)
{
	char const* text = "contract test {\n"
					   "  function f() { uint32(2) == int64(2); }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid)
{
	char const* text = "contract test {\n"
					   "  function f() { int32(2) == uint64(2); }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion)
{
	char const* text = "contract test {\n"
					   "  function f() returns (int256 r) { var x = int256(uint32(2)); return x; }"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(empty_string_literal)
{
	char const* text = "contract test {\n"
					   "  function f() { var x = \"\"; }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(large_string_literal)
{
	char const* text = "contract test {\n"
					   "  function f() { var x = \"123456789012345678901234567890123\"; }"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(balance)
{
	char const* text = "contract test {\n"
					   "  function fun() {\n"
					   "    uint256 x = address(0).balance;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}

BOOST_AUTO_TEST_CASE(balance_invalid)
{
	char const* text = "contract test {\n"
					   "  function fun() {\n"
					   "    address(0).balance = 7;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(assignment_to_mapping)
{
	char const* text = "contract test {\n"
					   "  struct str {\n"
					   "    mapping(uint=>uint) map;\n"
					   "  }\n"
					   "  str data;"
					   "  function fun() {\n"
					   "    var a = data.map;\n"
					   "    data.map = a;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_CASE(assignment_to_struct)
{
	char const* text = "contract test {\n"
					   "  struct str {\n"
					   "    mapping(uint=>uint) map;\n"
					   "  }\n"
					   "  str data;"
					   "  function fun() {\n"
					   "    var a = data;\n"
					   "    data = a;\n"
					   "  }\n"
					   "}\n";
	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}

BOOST_AUTO_TEST_SUITE_END()

}
}
} // end namespaces

<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License

#include <string>

#include "process/delay.hpp"
#include "process/future.hpp"
#include "process/help.hpp"
#include "process/http.hpp"
#include "process/logging.hpp"

#include "stout/numify.hpp"
#include "stout/option.hpp"
#include "stout/stringify.hpp"
#include "stout/try.hpp"

namespace process {

Future<http::Response> Logging::toggle(const http::Request& request)
{
  Option<std::string> level = request.url.query.get("level");
  Option<std::string> duration = request.url.query.get("duration");

  if (level.isNone() && duration.isNone()) {
    return http::OK(stringify(FLAGS_v) + "\n");
  }

  if (level.isSome() && duration.isNone()) {
    return http::BadRequest("Expecting 'duration=value' in query.\n");
  } else if (level.isNone() && duration.isSome()) {
    return http::BadRequest("Expecting 'level=value' in query.\n");
  }

  Try<int> v = numify<int>(level.get());

  if (v.isError()) {
    return http::BadRequest(v.error() + ".\n");
  }

  if (v.get() < 0) {
    return http::BadRequest(
        "Invalid level '" + stringify(v.get()) + "'.\n");
  } else if (v.get() < original) {
    return http::BadRequest(
        "'" + stringify(v.get()) + "' < original level.\n");
  }

  Try<Duration> d = Duration::parse(duration.get());

  if (d.isError()) {
    return http::BadRequest(d.error() + ".\n");
  }

  // Set the logging level.
  set(v.get());

  // Start a revert timer (if necessary).
  if (v.get() != original) {
    timeout = d.get();
    delay(timeout.remaining(), this, &This::revert);
  }

  return http::OK();
}

const std::string Logging::TOGGLE_HELP()
{
  return HELP(
    TLDR(
        "Sets the logging verbosity level for a specified duration."),
    DESCRIPTION(
        "The libprocess library uses [glog][glog] for logging. The library",
        "only uses verbose logging which means nothing will be output unless",
        "the verbosity level is set (by default it's 0, libprocess uses"
        "levels 1, 2, and 3).",
        "",
        "**NOTE:** If your application uses glog this will also affect",
        "your verbose logging.",
        "",
        "Query parameters:",
        "",
        ">        level=VALUE          Verbosity level (e.g., 1, 2, 3)",
        ">        duration=VALUE       Duration to keep verbosity level",
        ">                             toggled (e.g., 10secs, 15mins, etc.)"),
    REFERENCES(
        "[glog]: https://code.google.com/p/google-glog"));
}

} // namespace process {
<commit_msg>Fixed white space in libprocess/src/logging.cpp.<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License

#include <string>

#include "process/delay.hpp"
#include "process/future.hpp"
#include "process/help.hpp"
#include "process/http.hpp"
#include "process/logging.hpp"

#include "stout/numify.hpp"
#include "stout/option.hpp"
#include "stout/stringify.hpp"
#include "stout/try.hpp"

namespace process {

Future<http::Response> Logging::toggle(const http::Request& request)
{
  Option<std::string> level = request.url.query.get("level");
  Option<std::string> duration = request.url.query.get("duration");

  if (level.isNone() && duration.isNone()) {
    return http::OK(stringify(FLAGS_v) + "\n");
  }

  if (level.isSome() && duration.isNone()) {
    return http::BadRequest("Expecting 'duration=value' in query.\n");
  } else if (level.isNone() && duration.isSome()) {
    return http::BadRequest("Expecting 'level=value' in query.\n");
  }

  Try<int> v = numify<int>(level.get());

  if (v.isError()) {
    return http::BadRequest(v.error() + ".\n");
  }

  if (v.get() < 0) {
    return http::BadRequest(
        "Invalid level '" + stringify(v.get()) + "'.\n");
  } else if (v.get() < original) {
    return http::BadRequest(
        "'" + stringify(v.get()) + "' < original level.\n");
  }

  Try<Duration> d = Duration::parse(duration.get());

  if (d.isError()) {
    return http::BadRequest(d.error() + ".\n");
  }

  // Set the logging level.
  set(v.get());

  // Start a revert timer (if necessary).
  if (v.get() != original) {
    timeout = d.get();
    delay(timeout.remaining(), this, &This::revert);
  }

  return http::OK();
}

const std::string Logging::TOGGLE_HELP()
{
  return HELP(
    TLDR(
        "Sets the logging verbosity level for a specified duration."),
    DESCRIPTION(
        "The libprocess library uses [glog][glog] for logging. The library",
        "only uses verbose logging which means nothing will be output unless",
        "the verbosity level is set (by default it's 0, libprocess uses levels"
        " 1, 2, and 3).",
        "",
        "**NOTE:** If your application uses glog this will also affect",
        "your verbose logging.",
        "",
        "Query parameters:",
        "",
        ">        level=VALUE          Verbosity level (e.g., 1, 2, 3)",
        ">        duration=VALUE       Duration to keep verbosity level",
        ">                             toggled (e.g., 10secs, 15mins, etc.)"),
    REFERENCES(
        "[glog]: https://code.google.com/p/google-glog"));
}

} // namespace process {
<|endoftext|>


<commit_before>// $Id: forceField.C,v 1.22 2001/06/05 15:55:26 anker Exp $

#include <BALL/MOLMEC/COMMON/forceField.h>

#include <BALL/MOLMEC/COMMON/forceFieldComponent.h>
#include <BALL/MOLMEC/COMMON/periodicBoundary.h>
#include <BALL/KERNEL/bond.h>
#include <BALL/KERNEL/forEach.h>

using namespace std;

namespace BALL
{

	// default constructor
	ForceField::ForceField()
		:	periodic_boundary(*this),
			system_( 0 ),
			valid_(true),
			name_("Force Field"),
			number_of_movable_atoms_(0),
			use_selection_(false),
			update_time_stamp_(),
			setup_time_stamp_()
	{
	}

	void ForceField::clear()
		throw()
	{
		options.clear();
		periodic_boundary.clear();

		name_ = "Force Field";
		energy_ = 0.0;
		system_ = 0;
		atoms_.clear();
		number_of_movable_atoms_ = 0;
		parameters_.clear();
		use_selection_ = false;
		valid_ = true;

		update_time_stamp_.clear();
		setup_time_stamp_.clear();

		// remove all force field components from the list after
		// calling their destructors
		vector<ForceFieldComponent*>::iterator  it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			delete (*it);
		}
		components_.clear();
	}

	// copy constructor
	ForceField::ForceField(const ForceField& force_field)
	{
		// Copy the attributes
		name_   = force_field.name_;
		energy_ = force_field.energy_;
		options = force_field.options;
		system_ = force_field.system_;
		atoms_  = force_field.atoms_;
		number_of_movable_atoms_ = force_field.number_of_movable_atoms_;
		parameters_ = force_field.parameters_;
		periodic_boundary = force_field.periodic_boundary;
		use_selection_ = force_field.use_selection_;
		valid_ = force_field.valid_;
		update_time_stamp_ = force_field.update_time_stamp_;
		setup_time_stamp_ = force_field.setup_time_stamp_;

		// Copy the component vector
		for (Size i = 0; i < force_field.components_.size(); i++)
		{
			components_.push_back((ForceFieldComponent*)force_field.components_[i]->create());
		}
	}

	// assignment operator
	ForceField& ForceField::operator = (const ForceField& force_field)
	{

		// guard against self assignment
		if (&force_field != this)
		{
			atoms_.clear();
			atoms_  = force_field.atoms_;
			number_of_movable_atoms_ = force_field.number_of_movable_atoms_;

			name_   = force_field.name_;
			energy_ = force_field.energy_;
			options = force_field.options;
			system_ = force_field.system_;
			parameters_ = force_field.parameters_;
			periodic_boundary = force_field.periodic_boundary;
			use_selection_ = force_field.use_selection_;
			valid_ = force_field.valid_;

			Size i;
			for (i = 0; i < components_.size(); i++)
			{
				delete components_[i];
			}
			components_.clear();

			for (i = 0; i < force_field.components_.size(); i++)
			{
				components_.push_back((ForceFieldComponent*)force_field.components_[i]->create());
			}

		}
		return (*this);
	}

	// Constructor initialized with a system
	ForceField::ForceField(System& system)
		:	periodic_boundary(*this)
	{
		bool result = setup(system);

		if (!result)
		{
			Log.level(LogStream::ERROR) << "Force Field setup failed! " << endl;
			valid_ = false;
		}
	}

	// Constructor intialized with a system and a set of options
	ForceField::ForceField(System& system, const Options& new_options)
		:	periodic_boundary(*this)
	{
		bool result = setup(system, new_options);

		if (!result)
		{
			Log.level(LogStream::ERROR) << "Force Field setup failed! " << endl;
			valid_ = false;
		}
	}

	// destructor
	ForceField::~ForceField()
	{
		clear();
		valid_ = false;
	}

	// Is the force field valid
	bool ForceField::isValid() const
		throw()
	{
		return valid_;
	}

	// setup methods
	bool  ForceField::setup(System& system)
	{
		bool  success = true;

		// store the specified system
		system_ = &system;

		// Setup periodic boundary
		if(!periodic_boundary.setup())
		{
			Log.error() << "setup of periodic boundary failed" << endl;
			return false;
		}

		// collect the atoms of the system in the atoms_ vector
		collectAtoms_(system);
		Size old_size = (Size)atoms_.size();

		// generate the vector of molecules if periodic boundary is enabled
		if (periodic_boundary.isEnabled())
		{
			periodic_boundary.generateMoleculesVector();
		}

		// force field specific parts
		success = specificSetup();
		if (!success)
		{
			Log.error() << "Force Field specificSetup failed!" << endl;
			return false;
		}

		// if specificSetup cleared this array, it wants to tell us
		// that it had to change the system a bit (e.g. CHARMM replacing
	  // hydrogens by united atoms). So, we have to recalculated the vector.
		if (atoms_.size() != old_size)
		{
			collectAtoms_(system);
		}
		// call the setup method for each force field component
		vector<ForceFieldComponent*>::iterator  it;
		for (it = components_.begin(); (it != components_.end()) && success; ++it)
		{
			success = (*(*it)).setup();
			if (!success)
			{
				Log.error() << "Force Field Component setup of "
										<< (*it)->name_ <<  " failed!" << endl;
			}
		}

		// remember the setup time
		setup_time_stamp_.stamp();

		// if the setup failed, our force field becomes invalid!
		valid_ = success;
		return success;
	}

	// collect all atoms
	void ForceField::collectAtoms_(const System& system)
	{
		// clear existing atoms entries
		atoms_.clear();

		// check for selected atoms
		// if any of the atoms is selected, the atoms_ array holds
		// the selected atoms first (0 < i < number_of_movable_atoms_)
		use_selection_ = system.containsSelection();
		number_of_movable_atoms_ = 0;
		AtomConstIterator atom_it = system.beginAtom();
		if (use_selection_ == true)
		{
			for (; +atom_it; ++atom_it)
			{
				if (atom_it->isSelected() == true)
				{
					atoms_.push_back(const_cast<Atom*>(&(*atom_it)));
				}
			}
		} else {
			for (; +atom_it; ++atom_it)
			{
				atoms_.push_back(const_cast<Atom*>(&(*atom_it)));
			}
		}

		number_of_movable_atoms_ = (Size)atoms_.size();
	}

	// Setup with a system and a set of options
	bool ForceField::setup(System& system, const Options& new_options)
	{
		options = new_options;
		return setup(system);
	}

	// Returns the name of the force field
	String ForceField::getName() const
	{
		return name_;
	}

	// Sets the name of force field to name
	void ForceField::setName(const String& name)
	{
		name_ = name;
	}

	const TimeStamp& ForceField::getUpdateTime() const
		throw()
	{
		return update_time_stamp_;
	}

	const TimeStamp& ForceField::getSetupTime() const
		throw()
	{
		return setup_time_stamp_;
	}

	// Returns the number of atoms stored in the vector atoms_
	Size ForceField::getNumberOfAtoms() const
	{
		return (Size)atoms_.size();
	}

	// Returns the number of movable (non-fixed) atoms stored in the vector atoms_
	Size ForceField::getNumberOfMovableAtoms() const
	{
		return number_of_movable_atoms_;
	}

	// Returns the reference of the atom vector atoms_
	const AtomVector& ForceField::getAtoms() const
	{
		return atoms_;
	}

	// Return a pointer to the system
	System* ForceField::getSystem()
	{
		return system_;
	}

  // Return a pointer to the system
  const System* ForceField::getSystem() const
  {
    return system_;
  }

	// Return the parameter use_selection_
	bool ForceField::getUseSelection()
	{
		return use_selection_;
	}

	// Return the parameter use_selection_
	void ForceField::setUseSelection(bool use_selection)
	{
		use_selection_ = use_selection;
	}

	// Return a pointer to the parameter file
	ForceFieldParameters& ForceField::getParameters()
	{
		return parameters_;
	}

	void ForceField::updateForces()
	{
		// check for validity of the force field
		if (!isValid())
		{
			return;
		}

		// Set forces to zero
		for (AtomVector::Iterator it = atoms_.begin(); it != atoms_.end(); ++it)
		{
			(*it)->setForce(RTTI::getDefault<Vector3>());
		}

		// update use_selection_
		use_selection_ = system_->containsSelection();

		// call each component - they will add their forces...
		vector<ForceFieldComponent*>::iterator		component_it = components_.begin();
		for (; component_it != components_.end(); ++component_it)
		{
			(*component_it)->updateForces();
		}
	}

	// Calculate the RMS of the gradient
	double	ForceField::getRMSGradient() const
	{
		double sum = 0;
		AtomConstVector::ConstIterator it = atoms_.begin();
		for (; it != atoms_.end(); ++it)
		{
			sum += (*it)->getForce().getSquareLength();
		}
		sum = sqrt(sum/(3 * (double)atoms_.size()));
		sum *= Constants::AVOGADRO / 1e13;
		return(sum);
	}

	double ForceField::getEnergy() const
	{
	 return energy_;
	}

	double ForceField::updateEnergy()
	{
		// check for validity of the force field
		if (!isValid())
		{
			return 0.0;
		}

		// clear the total energy
		energy_ = 0;

		// update use_selection_
		use_selection_ = system_->containsSelection();

		// check whether the selection changed since the last call
		// to update and call update oterwise
		// if (update_time_stamp_ )
		// BAUSTELLE

		// call each component and add their energies
		vector<ForceFieldComponent*>::iterator		it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			energy_ += (*it)->updateEnergy();
		}

		// return the resulting energy
		return energy_;

	}

	Size ForceField::getUpdateFrequency() const
	{
		return 1;
	}

	void ForceField::update()
	{
		// check for validity of the force field
		if (!valid_)
		{
			return;
		}

		// iterate over all components and
		// call their update methods
		vector<ForceFieldComponent*>::iterator it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			(*it)->update();
		}

		// remember the time of the last update
		update_time_stamp_.stamp();
	}

	bool ForceField::specificSetup()
	{
		return true;
	}

	// Insert a component in the component vector
	void ForceField::insertComponent(ForceFieldComponent* force_field_component)
	{
		components_.push_back(force_field_component);
	}

	// Remove the component
	void ForceField::removeComponent(const ForceFieldComponent* force_field_component)
	{
		// call each component - test if equal - remove
		vector<ForceFieldComponent*>::iterator		it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			if ((*it) == force_field_component)
			{
				components_.erase(it);
				break ;
			}
		}
	}

	// Remove the component
	void ForceField::removeComponent(const String& name)
	{
		// call each component - test if equal - remove
		vector<ForceFieldComponent*>::iterator		it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			if ((*it)->getName() == name)
			{
				components_.erase(it);
				break ;
			}
		}
	}

	// Returns the number of components
	Size ForceField::countComponents() const
	{
		return (Size)components_.size();
	}

	// Returns the component with index "index"
	ForceFieldComponent* ForceField::getComponent(const Size index) const
	{
		if (index >= components_.size())
			return 0;

		return components_[index];
	}

	ForceFieldComponent* ForceField::getComponent(const String& name) const
	{
		for (Size i = 0; i < components_.size(); ++i)
		{
			if (components_[i]->getName() == name)
			{
				return components_[i];
			}
		}

		return 0;
	}

} // namespace BALL
<commit_msg>fixed: removed reference to non-existing type AtomConstVector<commit_after>// $Id: forceField.C,v 1.23 2001/06/21 02:41:54 oliver Exp $

#include <BALL/MOLMEC/COMMON/forceField.h>

#include <BALL/MOLMEC/COMMON/forceFieldComponent.h>
#include <BALL/MOLMEC/COMMON/periodicBoundary.h>
#include <BALL/KERNEL/bond.h>
#include <BALL/KERNEL/forEach.h>

using namespace std;

namespace BALL
{

	// default constructor
	ForceField::ForceField()
		:	periodic_boundary(*this),
			system_( 0 ),
			valid_(true),
			name_("Force Field"),
			number_of_movable_atoms_(0),
			use_selection_(false),
			update_time_stamp_(),
			setup_time_stamp_()
	{
	}

	void ForceField::clear()
		throw()
	{
		options.clear();
		periodic_boundary.clear();

		name_ = "Force Field";
		energy_ = 0.0;
		system_ = 0;
		atoms_.clear();
		number_of_movable_atoms_ = 0;
		parameters_.clear();
		use_selection_ = false;
		valid_ = true;

		update_time_stamp_.clear();
		setup_time_stamp_.clear();

		// remove all force field components from the list after
		// calling their destructors
		vector<ForceFieldComponent*>::iterator  it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			delete (*it);
		}
		components_.clear();
	}

	// copy constructor
	ForceField::ForceField(const ForceField& force_field)
	{
		// Copy the attributes
		name_   = force_field.name_;
		energy_ = force_field.energy_;
		options = force_field.options;
		system_ = force_field.system_;
		atoms_  = force_field.atoms_;
		number_of_movable_atoms_ = force_field.number_of_movable_atoms_;
		parameters_ = force_field.parameters_;
		periodic_boundary = force_field.periodic_boundary;
		use_selection_ = force_field.use_selection_;
		valid_ = force_field.valid_;
		update_time_stamp_ = force_field.update_time_stamp_;
		setup_time_stamp_ = force_field.setup_time_stamp_;

		// Copy the component vector
		for (Size i = 0; i < force_field.components_.size(); i++)
		{
			components_.push_back((ForceFieldComponent*)force_field.components_[i]->create());
		}
	}

	// assignment operator
	ForceField& ForceField::operator = (const ForceField& force_field)
	{

		// guard against self assignment
		if (&force_field != this)
		{
			atoms_.clear();
			atoms_  = force_field.atoms_;
			number_of_movable_atoms_ = force_field.number_of_movable_atoms_;

			name_   = force_field.name_;
			energy_ = force_field.energy_;
			options = force_field.options;
			system_ = force_field.system_;
			parameters_ = force_field.parameters_;
			periodic_boundary = force_field.periodic_boundary;
			use_selection_ = force_field.use_selection_;
			valid_ = force_field.valid_;

			Size i;
			for (i = 0; i < components_.size(); i++)
			{
				delete components_[i];
			}
			components_.clear();

			for (i = 0; i < force_field.components_.size(); i++)
			{
				components_.push_back((ForceFieldComponent*)force_field.components_[i]->create());
			}

		}
		return (*this);
	}

	// Constructor initialized with a system
	ForceField::ForceField(System& system)
		:	periodic_boundary(*this)
	{
		bool result = setup(system);

		if (!result)
		{
			Log.level(LogStream::ERROR) << "Force Field setup failed! " << endl;
			valid_ = false;
		}
	}

	// Constructor intialized with a system and a set of options
	ForceField::ForceField(System& system, const Options& new_options)
		:	periodic_boundary(*this)
	{
		bool result = setup(system, new_options);

		if (!result)
		{
			Log.level(LogStream::ERROR) << "Force Field setup failed! " << endl;
			valid_ = false;
		}
	}

	// destructor
	ForceField::~ForceField()
	{
		clear();
		valid_ = false;
	}

	// Is the force field valid
	bool ForceField::isValid() const
		throw()
	{
		return valid_;
	}

	// setup methods
	bool  ForceField::setup(System& system)
	{
		bool  success = true;

		// store the specified system
		system_ = &system;

		// Setup periodic boundary
		if(!periodic_boundary.setup())
		{
			Log.error() << "setup of periodic boundary failed" << endl;
			return false;
		}

		// collect the atoms of the system in the atoms_ vector
		collectAtoms_(system);
		Size old_size = (Size)atoms_.size();

		// generate the vector of molecules if periodic boundary is enabled
		if (periodic_boundary.isEnabled())
		{
			periodic_boundary.generateMoleculesVector();
		}

		// force field specific parts
		success = specificSetup();
		if (!success)
		{
			Log.error() << "Force Field specificSetup failed!" << endl;
			return false;
		}

		// if specificSetup cleared this array, it wants to tell us
		// that it had to change the system a bit (e.g. CHARMM replacing
	  // hydrogens by united atoms). So, we have to recalculated the vector.
		if (atoms_.size() != old_size)
		{
			collectAtoms_(system);
		}
		// call the setup method for each force field component
		vector<ForceFieldComponent*>::iterator  it;
		for (it = components_.begin(); (it != components_.end()) && success; ++it)
		{
			success = (*(*it)).setup();
			if (!success)
			{
				Log.error() << "Force Field Component setup of "
										<< (*it)->name_ <<  " failed!" << endl;
			}
		}

		// remember the setup time
		setup_time_stamp_.stamp();

		// if the setup failed, our force field becomes invalid!
		valid_ = success;
		return success;
	}

	// collect all atoms
	void ForceField::collectAtoms_(const System& system)
	{
		// clear existing atoms entries
		atoms_.clear();

		// check for selected atoms
		// if any of the atoms is selected, the atoms_ array holds
		// the selected atoms first (0 < i < number_of_movable_atoms_)
		use_selection_ = system.containsSelection();
		number_of_movable_atoms_ = 0;
		AtomConstIterator atom_it = system.beginAtom();
		if (use_selection_ == true)
		{
			for (; +atom_it; ++atom_it)
			{
				if (atom_it->isSelected() == true)
				{
					atoms_.push_back(const_cast<Atom*>(&(*atom_it)));
				}
			}
		} else {
			for (; +atom_it; ++atom_it)
			{
				atoms_.push_back(const_cast<Atom*>(&(*atom_it)));
			}
		}

		number_of_movable_atoms_ = (Size)atoms_.size();
	}

	// Setup with a system and a set of options
	bool ForceField::setup(System& system, const Options& new_options)
	{
		options = new_options;
		return setup(system);
	}

	// Returns the name of the force field
	String ForceField::getName() const
	{
		return name_;
	}

	// Sets the name of force field to name
	void ForceField::setName(const String& name)
	{
		name_ = name;
	}

	const TimeStamp& ForceField::getUpdateTime() const
		throw()
	{
		return update_time_stamp_;
	}

	const TimeStamp& ForceField::getSetupTime() const
		throw()
	{
		return setup_time_stamp_;
	}

	// Returns the number of atoms stored in the vector atoms_
	Size ForceField::getNumberOfAtoms() const
	{
		return (Size)atoms_.size();
	}

	// Returns the number of movable (non-fixed) atoms stored in the vector atoms_
	Size ForceField::getNumberOfMovableAtoms() const
	{
		return number_of_movable_atoms_;
	}

	// Returns the reference of the atom vector atoms_
	const AtomVector& ForceField::getAtoms() const
	{
		return atoms_;
	}

	// Return a pointer to the system
	System* ForceField::getSystem()
	{
		return system_;
	}

  // Return a pointer to the system
  const System* ForceField::getSystem() const
  {
    return system_;
  }

	// Return the parameter use_selection_
	bool ForceField::getUseSelection()
	{
		return use_selection_;
	}

	// Return the parameter use_selection_
	void ForceField::setUseSelection(bool use_selection)
	{
		use_selection_ = use_selection;
	}

	// Return a pointer to the parameter file
	ForceFieldParameters& ForceField::getParameters()
	{
		return parameters_;
	}

	void ForceField::updateForces()
	{
		// check for validity of the force field
		if (!isValid())
		{
			return;
		}

		// Set forces to zero
		for (AtomVector::Iterator it = atoms_.begin(); it != atoms_.end(); ++it)
		{
			(*it)->setForce(RTTI::getDefault<Vector3>());
		}

		// update use_selection_
		use_selection_ = system_->containsSelection();

		// call each component - they will add their forces...
		vector<ForceFieldComponent*>::iterator		component_it = components_.begin();
		for (; component_it != components_.end(); ++component_it)
		{
			(*component_it)->updateForces();
		}
	}

	// Calculate the RMS of the gradient
	double	ForceField::getRMSGradient() const
	{
		double sum = 0;
		AtomVector::ConstIterator it(atoms_.begin());
		for (; it != atoms_.end(); ++it)
		{
			sum += (*it)->getForce().getSquareLength();
		}
		sum = sqrt(sum/(3 * (double)atoms_.size()));
		sum *= Constants::AVOGADRO / 1e13;
		return(sum);
	}

	double ForceField::getEnergy() const
	{
	 return energy_;
	}

	double ForceField::updateEnergy()
	{
		// check for validity of the force field
		if (!isValid())
		{
			return 0.0;
		}

		// clear the total energy
		energy_ = 0;

		// update use_selection_
		use_selection_ = system_->containsSelection();

		// check whether the selection changed since the last call
		// to update and call update oterwise
		// if (update_time_stamp_ )
		// BAUSTELLE

		// call each component and add their energies
		vector<ForceFieldComponent*>::iterator		it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			energy_ += (*it)->updateEnergy();
		}

		// return the resulting energy
		return energy_;

	}

	Size ForceField::getUpdateFrequency() const
	{
		return 1;
	}

	void ForceField::update()
	{
		// check for validity of the force field
		if (!valid_)
		{
			return;
		}

		// iterate over all components and
		// call their update methods
		vector<ForceFieldComponent*>::iterator it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			(*it)->update();
		}

		// remember the time of the last update
		update_time_stamp_.stamp();
	}

	bool ForceField::specificSetup()
	{
		return true;
	}

	// Insert a component in the component vector
	void ForceField::insertComponent(ForceFieldComponent* force_field_component)
	{
		components_.push_back(force_field_component);
	}

	// Remove the component
	void ForceField::removeComponent(const ForceFieldComponent* force_field_component)
	{
		// call each component - test if equal - remove
		vector<ForceFieldComponent*>::iterator		it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			if ((*it) == force_field_component)
			{
				components_.erase(it);
				break ;
			}
		}
	}

	// Remove the component
	void ForceField::removeComponent(const String& name)
	{
		// call each component - test if equal - remove
		vector<ForceFieldComponent*>::iterator		it;
		for (it = components_.begin(); it != components_.end(); ++it)
		{
			if ((*it)->getName() == name)
			{
				components_.erase(it);
				break ;
			}
		}
	}

	// Returns the number of components
	Size ForceField::countComponents() const
	{
		return (Size)components_.size();
	}

	// Returns the component with index "index"
	ForceFieldComponent* ForceField::getComponent(const Size index) const
	{
		if (index >= components_.size())
			return 0;

		return components_[index];
	}

	ForceFieldComponent* ForceField::getComponent(const String& name) const
	{
		for (Size i = 0; i < components_.size(); ++i)
		{
			if (components_[i]->getName() == name)
			{
				return components_[i];
			}
		}

		return 0;
	}

} // namespace BALL
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: HBondProcessor.C,v 1.12 2005/03/02 15:18:55 amoll Exp $
//

#include <BALL/STRUCTURE/HBondProcessor.h>
#include <BALL/DATATYPE/hashGrid.h>
#include <BALL/KERNEL/bond.h>
#include <BALL/KERNEL/system.h>
#include <BALL/STRUCTURE/geometricProperties.h>

namespace BALL
{

	HBondProcessor::HBondProcessor()
		:	MAX_LENGTH(5.2 + 4.2),
			BOND_LENGTH_N_H(1.020),
			BOND_LENGTH_C_O(1.240),
			residue_data_()
	{
	}

	HBondProcessor::~HBondProcessor()
	{
	}

	void HBondProcessor::preComputeBonds_(ResidueIterator& resit)
	{
		// index to serially the residues
		Position j = 0;

		// iteration over all residues of the protein
		// to find the C,N,O atoms

		for (; +resit ; ++resit)
		{
			if (!resit->isAminoAcid()) continue;

			bool haveO = false;
			bool haveN = false;
			bool haveC = false;

			ResidueData pos;

			Size found = 0;
			for (AtomIterator ai = resit->beginAtom(); +ai; ++ai)
			{
				if (ai->getName() ==  "C")
				{
					pos.pos_C = ai->getPosition();
					haveC = true;
				}
				else if (ai->getName() ==  "O")
				{
					pos.pos_O = ai->getPosition();
					haveO = true;
				}
				else if (ai->getName() ==  "N")
				{
					pos.pos_N = ai->getPosition();
          haveN = true;
				}
				else
				{
					continue;
				}

				found++;
				if (found == 3) break;
			}

			// we have to overread incomplete residues
			pos.is_complete = (haveN && haveO && haveC);

			pos.number = j;
			pos.res = &(*resit);

			// the N-terminus is special
			if (pos.is_complete && j != 0)
			{
				// evaluate the position of H
				const Vector3 OC(residue_data_[j-1].pos_O - residue_data_[j-1].pos_C);
				const float length = OC.getLength();

				if (!Maths::isZero(length))
				{
					pos.pos_H = pos.pos_N - (OC * BOND_LENGTH_N_H) / length;
				}
				else
				{
					pos.is_complete = false;
				}
			}

			residue_data_.push_back(pos);
			j++;
		}
	}

	bool HBondProcessor::finish()
	{
		if (residue_data_.size() == 0) return true;

		// matrix to save the existence of a HBond
		h_bond_pairs_.resize(residue_data_.size());

		//create a grid inside the bounding box
		HashGrid3<ResidueData*> atom_grid(lower_, upper_ - lower_, MAX_LENGTH);

		// insert all protein-residues in respect of N-atom
		// the last residue does not _have_ an O.  = > don't use it
		for (Size i = 0; i < residue_data_.size(); i++)
		{
			if (residue_data_[i].is_complete)
			{
				atom_grid.insert(residue_data_[i].pos_N, &residue_data_[i]);
			}
		}

		const Index size_x = atom_grid.getSizeX();
		const Index size_y = atom_grid.getSizeY();
		const Index size_z = atom_grid.getSizeZ();

 		// now compute the energies and see whether we have a hydrogen bond
		for (Size i = 0; i < residue_data_.size(); i++)
		{
			const ResidueData& current_res = residue_data_[i];
			if (!current_res.is_complete) continue;

			HashGridBox3<ResidueData*>* const box = atom_grid.getBox(current_res.pos_N);

			// We iterate over the grid ourselves, since the beginBox()... didn't work... :-(
			Position x, y, z;                            // indices of the actual box
			atom_grid.getIndices(*box, x, y, z);         // compute the indices of the actual box

			// Iterate over all the neighbouring boxes
			// for (box_it = box->beginBox(); +box_it; ++box_it) //as mentioned beginBox doesn't work
			for (int nx = x-1; (nx < size_x) && (nx < (int)x+2); nx++)
			{
				if (nx < 0) continue;

				for (int ny = y-1; (ny < size_y) && (ny < (int)y+2); ny++)
				{
					if (ny < 0) continue;

					for (int nz = z-1; (nz < size_z) && (nz < (int)z+2); nz++)
					{
						if (nz < 0) continue;

						// compute the neighbour box
						HashGridBox3<ResidueData*>* const nb = atom_grid.getBox(nx, ny, nz);

						//iterate over all residues of the neighbouring box
						HashGridBox3<ResidueData*>::DataIterator data_it;
						for (data_it = nb->beginData(); +data_it; ++data_it)
						{
							// TODO: We don't want H-bonds between neighboring residues!
							//       Does this criterion always work? We should check for
							//       an existing bond between data_it and vec[i] instead!

							// data from neighbouring residue
							const ResidueData& ndata = **data_it;

							if (abs((Index)ndata.number - (Index)(current_res.number)) <= 1 ||
									ndata.number == 0)
							{
								continue;
							}

							// compute the distances between the relevant atoms
							const float dist_ON = (current_res.pos_O - ndata.pos_N).getLength();
							const float dist_CH = (current_res.pos_C - ndata.pos_H).getLength();
							const float dist_OH = (current_res.pos_O - ndata.pos_H).getLength();
							const float dist_CN = (current_res.pos_C - ndata.pos_N).getLength();

							// compute the electrostatic energy of the bond-building groups
							float energy  = 0.42 * 0.20 * 332.;
							energy *=  (1./dist_ON + 1./dist_CH - 1./dist_OH - 1./dist_CN);

							if (energy >= -0.5) continue;

							Atom *acceptor = 0;
							for (AtomIterator ai = current_res.res->beginAtom(); +ai; ++ai)
							{
								if (ai->getName() == "O")
								{
									acceptor = &(*ai);
									break;
								}
							}

							Atom* donor = 0;
							for (AtomIterator ai = ndata.res->beginAtom(); +ai; ++ai)
							{
								if (ai->getName() == "N")
								{
									donor = &*ai;
									break;
								}
							}

							if (!donor || !acceptor) continue;

							h_bond_pairs_[current_res.number].push_back(ndata.number);

							Bond* bond = donor->createBond(*acceptor);
							bond->setType(Bond::TYPE__HYDROGEN);
							bond->setOrder(1);
							bond->setName("calculated H-Bond");

							donor->setProperty("HBOND_DONOR", *acceptor);
						}
					}
				}
			}
		}

		return true;
	}

	Processor::Result HBondProcessor::operator() (Composite &composite)
	{
		ResidueIterator ri;

	  // create a mantel box (bounding box)  which should include the composite
		BoundingBoxProcessor bp;

		// do we have a system?
		if (RTTI::isKindOf<System>(composite))
		{
			System *s = RTTI::castTo<System>(composite);
			s->apply(bp);
      ri = s->beginResidue();
		}else
		if (RTTI::isKindOf<Protein>(composite))
		{
			Protein *s = RTTI::castTo<Protein>(composite);
			s->apply(bp);
      ri = s->beginResidue();
		}else
		if (RTTI::isKindOf<Chain>(composite))
		{
			Chain *s = RTTI::castTo<Chain>(composite);
			s->apply(bp);
			ri = s->beginResidue();
		}

		if (!(+ri)) return Processor::CONTINUE;

		upper_ = bp.getUpper();
		lower_ = bp.getLower();

		// compute the H-Bonds
		preComputeBonds_(ri);

		return Processor::BREAK;

	}

	std::ostream& operator << (std::ostream& s, const BALL::HBondProcessor::ResidueData& p)
	{
		return s << p.pos_C << " " << p.pos_N << " " << p.pos_H << " " << p.pos_O << " " << p.number << std::endl;
	}

	const std::vector< std::vector<Position> >& HBondProcessor::getHBondPairs() const
	{
		return h_bond_pairs_;
	}

	const std::vector<HBondProcessor::ResidueData>& HBondProcessor::getResidueData() const
	{
		return residue_data_;
	}

} //Namespace BALL

<commit_msg>Cleaning up<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: HBondProcessor.C,v 1.13 2005/04/14 12:40:17 anhi Exp $
//

#include <BALL/STRUCTURE/HBondProcessor.h>
#include <BALL/DATATYPE/hashGrid.h>
#include <BALL/KERNEL/bond.h>
#include <BALL/KERNEL/system.h>
#include <BALL/STRUCTURE/geometricProperties.h>

namespace BALL
{

	HBondProcessor::HBondProcessor()
		:	MAX_LENGTH(5.2 + 4.2),
			BOND_LENGTH_N_H(1.020),
			BOND_LENGTH_C_O(1.240),
			residue_data_()
	{
	}

	HBondProcessor::~HBondProcessor()
	{
	}

	/*********************************************************
  *  preComputeBonds identifies characteristic amino acid
	*  atoms (C, N, O), and stores them in residue_data_
  *********************************************************/
	void HBondProcessor::preComputeBonds_(ResidueIterator& resit)
	{
		// index to enumerate the residues. Unfortunately, we cannot use
		// the residueID, which is not monotonous
		Position j = 0;

		// iteration over all residues of the protein
		// to find the C,N,O atoms
		//
		// since the N-terminus is special, we treat it differently
		// we also have to take care of residues with missing atoms
		// we find the first complete residue and use it instead
		for (; +resit ; ++resit)
		{
			if (!resit->isAminoAcid()) continue;

			bool haveO = false;
			bool haveN = false;
			bool haveC = false;

			ResidueData pos;

			Size found = 0;
			for (AtomIterator ai = resit->beginAtom(); +ai; ++ai)
			{
				if (ai->getName() ==  "C")
				{
					pos.pos_C = ai->getPosition();
					haveC = true;
				}
				else if (ai->getName() ==  "O")
				{
					pos.pos_O = ai->getPosition();
					haveO = true;
				}
				else if (ai->getName() ==  "N")
				{
					pos.pos_N = ai->getPosition();
          haveN = true;
				}
				else
				{
					continue;
				}

				found++;
				if (found == 3) break;
			}

			// we have to overread incomplete residues
			pos.is_complete = (haveN && haveO && haveC);

			pos.number = j;
			pos.res = &(*resit);

			// the N-terminus is special
			if (pos.is_complete && !(pos.res->isNTerminal()))
			{
				// evaluate the position of H
				const Vector3 OC(residue_data_[j-1].pos_O - residue_data_[j-1].pos_C);
				const float length = OC.getLength();

				if (!Maths::isZero(length))
				{
					pos.pos_H = pos.pos_N - (OC * BOND_LENGTH_N_H) / length;
				}
				else
				{
					pos.is_complete = false;
				}
			}

			residue_data_.push_back(pos);
			j++;
		}
	}

  /***************************************************
	 * Finish computes all hbonds of the composite
	 * and stores them in h_bond_pairs_.
   ***************************************************/
	bool HBondProcessor::finish()
	{
		if (residue_data_.size() == 0) return true;

		// matrix to save the existence of a HBond
		h_bond_pairs_.resize(residue_data_.size());

		//create a grid inside the bounding box
		HashGrid3<ResidueData*> atom_grid(lower_, upper_ - lower_, MAX_LENGTH);

		// insert all protein-residues at the position of their N-atom
		for (Size i = 0; i < residue_data_.size(); i++)
		{
			if (residue_data_[i].is_complete)
			{
				atom_grid.insert(residue_data_[i].pos_N, &residue_data_[i]);
			}
		}

		const Index size_x = atom_grid.getSizeX();
		const Index size_y = atom_grid.getSizeY();
		const Index size_z = atom_grid.getSizeZ();

 		// now compute the energies and see whether we have a hydrogen bond
		for (Size i = 0; i < residue_data_.size(); i++)
		{
			const ResidueData& current_res = residue_data_[i];
			if (!current_res.is_complete) continue;

			HashGridBox3<ResidueData*>* const box = atom_grid.getBox(current_res.pos_N);

			// We iterate over the grid ourselves, since the beginBox()... didn't work... :-(
			Position x, y, z;                            // indices of the actual box
			atom_grid.getIndices(*box, x, y, z);         // compute the indices of the actual box

			// Iterate over all the neighbouring boxes
			// for (box_it = box->beginBox(); +box_it; ++box_it) //as mentioned beginBox doesn't work
			for (int nx = x-1; (nx < size_x) && (nx < (int)x+2); nx++)
			{
				if (nx < 0) continue;

				for (int ny = y-1; (ny < size_y) && (ny < (int)y+2); ny++)
				{
					if (ny < 0) continue;

					for (int nz = z-1; (nz < size_z) && (nz < (int)z+2); nz++)
					{
						if (nz < 0) continue;

						// compute the neighbour box
						HashGridBox3<ResidueData*>* const nb = atom_grid.getBox(nx, ny, nz);

						//iterate over all residues of the neighbouring box
						HashGridBox3<ResidueData*>::DataIterator data_it;
						for (data_it = nb->beginData(); +data_it; ++data_it)
						{
							// TODO: We don't want H-bonds between neighboring residues!
							//       Does this criterion always work? We should check for
							//       an existing bond between data_it and residue_data_[i] instead!

							// data from neighbouring residue
							const ResidueData& ndata = **data_it;

							if (abs((Index)ndata.number - (Index)(current_res.number)) <= 1 ||
									ndata.number == 0)
							{
								continue;
							}

							// compute the distances between the relevant atoms
							const float dist_ON = (current_res.pos_O - ndata.pos_N).getLength();
							const float dist_CH = (current_res.pos_C - ndata.pos_H).getLength();
							const float dist_OH = (current_res.pos_O - ndata.pos_H).getLength();
							const float dist_CN = (current_res.pos_C - ndata.pos_N).getLength();

							// compute the electrostatic energy of the bond-building groups
							float energy  = 0.42 * 0.20 * 332.;
							energy *=  (1./dist_ON + 1./dist_CH - 1./dist_OH - 1./dist_CN);

							if (energy >= -0.5) continue;

							Atom *acceptor = 0;
							for (AtomIterator ai = current_res.res->beginAtom(); +ai; ++ai)
							{
								if (ai->getName() == "O")
								{
									acceptor = &(*ai);
									break;
								}
							}

							Atom* donor = 0;
							for (AtomIterator ai = ndata.res->beginAtom(); +ai; ++ai)
							{
								if (ai->getName() == "N")
								{
									donor = &*ai;
									break;
								}
							}

							if (!donor || !acceptor) continue;

							h_bond_pairs_[current_res.number].push_back(ndata.number);

							Bond* bond = donor->createBond(*acceptor);
							bond->setType(Bond::TYPE__HYDROGEN);
							bond->setOrder(1);
							bond->setName("calculated H-Bond");

							donor->setProperty("HBOND_DONOR", *acceptor);
						}
					}
				}
			}
		}

		return true;
	}

	/*********************************************************
	 *  Compute all HBonds for a given composite
	 *********************************************************/
	Processor::Result HBondProcessor::operator() (Composite &composite)
	{
		ResidueIterator ri;

	  // create a bounding box which should include the composite
		BoundingBoxProcessor bp;

		// do we have a system?
		if (RTTI::isKindOf<System>(composite))
		{
			System *s = RTTI::castTo<System>(composite);
			s->apply(bp);
      ri = s->beginResidue();
		}
		else if (RTTI::isKindOf<Protein>(composite))
		{
			Protein *s = RTTI::castTo<Protein>(composite);
			s->apply(bp);
      ri = s->beginResidue();
		}
		else if (RTTI::isKindOf<Chain>(composite))
		{
			Chain *s = RTTI::castTo<Chain>(composite);
			s->apply(bp);
			ri = s->beginResidue();
		}

		// ri doesn't seem to exist
		if (!(+ri))
		{
			return Processor::CONTINUE;
		}

		upper_ = bp.getUpper();
		lower_ = bp.getLower();

		// compute the H-Bonds
		preComputeBonds_(ri);

		return Processor::BREAK;

	}

	std::ostream& operator << (std::ostream& s, const BALL::HBondProcessor::ResidueData& p)
	{
		return s << p.pos_C << " " << p.pos_N << " " << p.pos_H << " " << p.pos_O << " " << p.number << std::endl;
	}

	const std::vector< std::vector<Position> >& HBondProcessor::getHBondPairs() const
	{
		return h_bond_pairs_;
	}

	const std::vector<HBondProcessor::ResidueData>& HBondProcessor::getResidueData() const
	{
		return residue_data_;
	}

} //Namespace BALL

<|endoftext|>


<commit_before>// Copyright (c) 2014 Marcin Polaczyk http://mpolaczyk.pl

#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <set>
#include <string.h>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <sysexits.h>
#include <exception>

using namespace std;

inline void coutBegin(const string& text) { cout << "=== " << text << " ===" << endl; }
inline void coutEnd() { cout << endl; }
inline void coutE(const string& text) { cout << ' ' << text; }
inline void coutH() { cout << "Format: --voice <voice> --text \"<text>\"" << endl << "Where <voice> is directory name with wav files and <text> is a text to process." << endl; }

string get_selfpath() {
    char buff[1024];
    ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
    if (len != -1) {
      buff[len] = '\0';
	  string ans(buff);
      return ans.substr(0, ans.length() - 5);
    } else {
     /* handle error condition */
    }
}

void getUTF8Char(const int& i, const string& word, string& outChar, int& outLen)
{
	int num = 0;
	int position = 7;
	while ((word[i] & (1 << position)) == (1 << position))
	{
		num++;
		position--;
	}

	outLen = (num == 0 ? 1 : num);
	outChar = word.substr(i, outLen);
}

bool mergeSounds(string& word, const string& voice, set<string>& sounds)
{
    string cmd = get_selfpath() + "wavmerge ";
    cout << endl;

	// Current combination
	string current = "";
	// Next combination
	string next = "";

	int di;

    for ( int i = 0 ; i <= word.length(); i+=di)
    {
		di = 0;

		// If current combination is empty, get first not processed character
		if (current == "")
		{
			getUTF8Char(i, word, current, di);
		}

		// Check if current combination exists
		if(current != "" && sounds.find(current) != sounds.end())
		{
			// If we have more characters
			int din = 0;
			if(i+di < word.length())
			{
				// Build next combination
				string x;
				getUTF8Char(i+di, word, x, din);
				next = current + x;
			}
			else
			{
				next = "";
			}

			// Check if next combination exists
			if(din > 0 && sounds.find(next) != sounds.end())
			{
				// Save next combination to current and continue
				current = next;
				di += din;
			}
			else
			{
				// Send combination to merge and continue
				cmd = cmd + " " + voice + "/" + current + ".wav";
				current = "";
				next = "";
			}
		}

    }
	cout << endl << cmd << endl;
    system(cmd.c_str()); // UNSECURE: Directory traversal / Command Injection
    cmd = "mv " + get_selfpath() + "merge.wav " + get_selfpath() + voice + "/" + word + ".wav";
    system(cmd.c_str()); // UNSECURE: Directory traversal / Command Injection
    return true;
}

bool tryParseParams(string& voice, string& text, int& argc, char *argv[])
{
	// Check params
	if(argc != 5 || strcmp(argv[1], "--voice") != 0 || strcmp(argv[3], "--text") != 0) { return false; }

	// Configure
	voice = argv[2];
	text = argv[4];
	return true;
}

bool loadVoice(string& voice, set<string>& sounds)
{
    // Get all waves from directory and save to file
    coutBegin("Looking for sounds of: '" + voice + "'");

	string cmd = get_selfpath() + "find " + voice + " -type f -name \"*.wav\" -exec basename {} .wav \\; > " + voice + "/sounds";
	system(cmd.c_str()); // UNSECURE: Directory traversal / Command Injection

	ifstream soundsFile(get_selfpath() + voice + "/sounds", ifstream::in);
	if (soundsFile.is_open())
	{
		// Each line has sound name, store it
		string line;
		while (getline(soundsFile, line))
		{
			coutE(line);
			sounds.insert(line);
		}
		soundsFile.close();
	}

	bool isEmpty = sounds.empty();
	if(isEmpty) { coutE("No sounds available..."); }

    coutEnd();

	return !isEmpty;
}

void splitTextIntoWords(string& text, vector<string>& words)
{
	// Split text into words
	coutBegin("Parsing text into words");

	istringstream iss(text);
	string word;
	while (iss >> word)
	{
		coutE(word);
		words.push_back(word);
	}

	coutEnd();
}

bool createWords(string& voice, vector<string>& words, set<string>& sounds)
{
	// Create wave files for words
	coutBegin("Creating word sounds");
	for(auto word : words)
	{
		if (sounds.find(word) == sounds.end())
		{
			coutE(word);
			if (!mergeSounds(word, voice, sounds)) { return false; }
			sounds.insert(word);
		}
	}
	coutEnd();
	return true;
}

void playWords(string& voice, vector<string>& words)
{
	// Play words
	coutBegin("Playing words");
	string cmd;
	for(auto word : words)
	{
		coutE(word);
		cmd = cmd + "aplay " + get_selfpath() + voice + "/" + word + ".wav; ";
	}
	system(cmd.c_str()); // UNSECURE: Directory traversal / Command Injection
	coutEnd();
}

int main(int argc, char *argv[])
{
	string voice;
	string text;
	set<string> sounds;
	vector<string> words;

	try
	{
		if(!tryParseParams(voice, text, argc, argv))
		{
			coutH();
			return EX_USAGE;
		}

		if(!loadVoice(voice, sounds))
		{
			return EX_OK;
		}

		splitTextIntoWords(text, words);

		if(!createWords(voice, words, sounds))
		{
			return EX_OK;
		}

		playWords(voice, words);
  	}
	catch(exception& e)
	{
		cout << endl << endl << "Exception: " << e.what() << endl;
	}

	return EX_OK;
}<commit_msg>Bugfix<commit_after>// Copyright (c) 2014 Marcin Polaczyk http://mpolaczyk.pl

#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <set>
#include <string.h>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <sysexits.h>
#include <exception>

using namespace std;

inline void coutBegin(const string& text) { cout << "=== " << text << " ===" << endl; }
inline void coutEnd() { cout << endl; }
inline void coutE(const string& text) { cout << ' ' << text; }
inline void coutH() { cout << "Format: --voice <voice> --text \"<text>\"" << endl << "Where <voice> is directory name with wav files and <text> is a text to process." << endl; }

string get_selfpath() {
    char buff[1024];
    ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
    if (len != -1) {
      buff[len] = '\0';
	  string ans(buff);
      return ans.substr(0, ans.length() - 5);
    } else {
     /* handle error condition */
    }
}

void getUTF8Char(const int& i, const string& word, string& outChar, int& outLen)
{
	int num = 0;
	int position = 7;
	while ((word[i] & (1 << position)) == (1 << position))
	{
		num++;
		position--;
	}

	outLen = (num == 0 ? 1 : num);
	outChar = word.substr(i, outLen);
}

bool mergeSounds(string& word, const string& voice, set<string>& sounds)
{
    string cmd = "./wavmerge ";
    cout << endl;

	// Current combination
	string current = "";
	// Next combination
	string next = "";

	int di;

    for ( int i = 0 ; i <= word.length(); i+=di)
    {
		di = 0;

		// If current combination is empty, get first not processed character
		if (current == "")
		{
			getUTF8Char(i, word, current, di);
		}

		// Check if current combination exists
		if(current != "" && sounds.find(current) != sounds.end())
		{
			// If we have more characters
			int din = 0;
			if(i+di < word.length())
			{
				// Build next combination
				string x;
				getUTF8Char(i+di, word, x, din);
				next = current + x;
			}
			else
			{
				next = "";
			}

			// Check if next combination exists
			if(din > 0 && sounds.find(next) != sounds.end())
			{
				// Save next combination to current and continue
				current = next;
				di += din;
			}
			else
			{
				// Send combination to merge and continue
				cmd = cmd + " " + voice + "/" + current + ".wav";
				current = "";
				next = "";
			}
		}

    }
	cout << endl << cmd << endl;
    system(cmd.c_str()); // UNSECURE: Directory traversal / Command Injection
    cmd = "mv merge.wav " + voice + "/" + word + ".wav";
    system(cmd.c_str()); // UNSECURE: Directory traversal / Command Injection
    return true;
}

bool tryParseParams(string& voice, string& text, int& argc, char *argv[])
{
	// Check params
	if(argc != 5 || strcmp(argv[1], "--voice") != 0 || strcmp(argv[3], "--text") != 0) { return false; }

	// Configure
	voice = argv[2];
	text = argv[4];
	return true;
}

bool loadVoice(string& voice, set<string>& sounds)
{
    // Get all waves from directory and save to file
    coutBegin("Looking for sounds of: '" + voice + "'");

	string cmd = "find " + voice + " -type f -name \"*.wav\" -exec basename {} .wav \\; > " + voice + "/sounds";
	system(cmd.c_str()); // UNSECURE: Directory traversal / Command Injection

	ifstream soundsFile(voice + "/sounds", ifstream::in);
	if (soundsFile.is_open())
	{
		// Each line has sound name, store it
		string line;
		while (getline(soundsFile, line))
		{
			coutE(line);
			sounds.insert(line);
		}
		soundsFile.close();
	}

	bool isEmpty = sounds.empty();
	if(isEmpty) { coutE("No sounds available..."); }

    coutEnd();

	return !isEmpty;
}

void splitTextIntoWords(string& text, vector<string>& words)
{
	// Split text into words
	coutBegin("Parsing text into words");

	istringstream iss(text);
	string word;
	while (iss >> word)
	{
		coutE(word);
		words.push_back(word);
	}

	coutEnd();
}

bool createWords(string& voice, vector<string>& words, set<string>& sounds)
{
	// Create wave files for words
	coutBegin("Creating word sounds");
	for(auto word : words)
	{
		if (sounds.find(word) == sounds.end())
		{
			coutE(word);
			if (!mergeSounds(word, voice, sounds)) { return false; }
			sounds.insert(word);
		}
	}
	coutEnd();
	return true;
}

void playWords(string& voice, vector<string>& words)
{
	// Play words
	coutBegin("Playing words");
	string cmd;
	for(auto word : words)
	{
		coutE(word);
		cmd = cmd + "aplay " + voice + "/" + word + ".wav; ";
	}
	system(cmd.c_str()); // UNSECURE: Directory traversal / Command Injection
	coutEnd();
}

int main(int argc, char *argv[])
{
	cout << get_selfpath() << endl;

	string voice;
	string text;
	set<string> sounds;
	vector<string> words;

	try
	{
		if(!tryParseParams(voice, text, argc, argv))
		{
			coutH();
			return EX_USAGE;
		}

		if(!loadVoice(voice, sounds))
		{
			return EX_OK;
		}

		splitTextIntoWords(text, words);

		if(!createWords(voice, words, sounds))
		{
			return EX_OK;
		}

		playWords(voice, words);
  	}
	catch(exception& e)
	{
		cout << endl << endl << "Exception: " << e.what() << endl;
	}

	return EX_OK;
}<|endoftext|>


<commit_before>#include "geosAlgorithm.h"
#include "stdio.h"
#include "math.h"

/**
* Computes the distance from a point p to a line segment AB
*
* Note: NON-ROBUST!
*/
double CGAlgorithms::distancePointLine(Coordinate p,Coordinate A,Coordinate B){
	//if start==end, then use pt distance
	if (A==B) return A.distance(B);

    // otherwise use comp.graphics.algorithms Frequently Asked Questions method
    /*(1)     	      AC dot AB
                   r = ---------
                         ||AB||^2
		r has the following meaning:
		r=0 P = A
		r=1 P = B
		r<0 P is on the backward extension of AB
		r>1 P is on the forward extension of AB
		0<r<1 P is interior to AB
	*/
	double r=((p.x-A.x)*(B.x-A.x)+(p.y-A.y)*(B.y-A.y))/
			 ((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));
	if (r<0) return p.distance(A);
	if (r>1) return p.distance(B);
    /*(2)
		     (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
		s = -----------------------------
		             	L^2

		Then the distance from C to P = |s|*L.
	*/
	double s=((A.y-p.y)*(B.x-A.x)-(A.x-p.x)*(B.y-A.y))/
			 ((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));
	return fabs(s)*sqrt(((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y)));
}

/**
* Computes the distance from a line segment AB to a line segment CD
*
* Note: NON-ROBUST!
*/
double CGAlgorithms::distanceLineLine(Coordinate A,Coordinate B,Coordinate C,Coordinate D){
	// check for zero-length segments
	if (A==B) return distancePointLine(A,C,D);
	if (C==D) return distancePointLine(D,A,B);

    // AB and CD are line segments
    /* from comp.graphics.algo

	Solving the above for r and s yields
				(Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
	           r = ----------------------------- (eqn 1)
				(Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)

		 	(Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
		s = ----------------------------- (eqn 2)
			(Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
	Let P be the position vector of the intersection point, then
		P=A+r(B-A) or
		Px=Ax+r(Bx-Ax)
		Py=Ay+r(By-Ay)
	By examining the values of r & s, you can also determine some other
limiting conditions:
		If 0<=r<=1 & 0<=s<=1, intersection exists
		r<0 or r>1 or s<0 or s>1 line segments do not intersect
		If the denominator in eqn 1 is zero, AB & CD are parallel
		If the numerator in eqn 1 is also zero, AB & CD are collinear.

	*/
	double r_top=(A.y-C.y)*(D.x-C.x)-(A.x-C.x)*(D.y-C.y);
	double r_bot=(B.x-A.x)*(D.y-C.y)-(B.y-A.y)*(D.x-C.x);
	double s_top=(A.y-C.y)*(B.x-A.x)-(A.x-C.x)*(B.y-A.y);
	double s_bot=(B.x-A.x)*(D.y-C.y)-(B.y-A.y)*(D.x-C.x);
	if ((r_bot==0)||(s_bot==0)) {
		return min(distancePointLine(A,C,D),min(distancePointLine(B,C,D),min(distancePointLine(C,A,B),distancePointLine(D,A,B))));
	}
	double s=s_top/s_bot;
	double r=r_top/r_bot;
	if ((r<0)||( r>1)||(s<0)||(s>1)) {
		//no intersection
		return min(distancePointLine(A,C,D),min(distancePointLine(B,C,D),min(distancePointLine(C,A,B),distancePointLine(D,A,B))));
	}
	return 0.0; //intersection exists
}

/**
* Returns the signed area for a ring.  The area is positive if
* the ring is oriented CW.
*/
double CGAlgorithms::signedArea(CoordinateList& ring) {
	if (ring.getSize()<3) return 0.0;
	double sum=0.0;
	double ax=ring.getAt(0).x;
	double ay=ring.getAt(0).y;
	for (int i=1;i<ring.getSize()-1;i++) {
		double bx=ring.getAt(i).x;
		double by=ring.getAt(i).y;
		double cx=ring.getAt(i+1).x;
		double cy=ring.getAt(i+1).y;
		sum+=ax*by-ay*bx+ay*cx-ax*cy+bx*cy-cx*by;
	}
	return -sum/2.0;
}

/**
* Returns the length of a list of line segments.
*/
double CGAlgorithms::length(CoordinateList& pts) {
	if (pts.getSize()<1) return 0.0;
	double sum=0.0;
	for(int i=1;i<pts.getSize();i++) {
		sum+=pts.getAt(i).distance(pts.getAt(i - 1));
	}
	return sum;
}
<commit_msg>First pass of CoordinateList interface replacement.<commit_after>#include "geosAlgorithm.h"
#include "stdio.h"
#include "math.h"

/**
* Computes the distance from a point p to a line segment AB
*
* Note: NON-ROBUST!
*/
double CGAlgorithms::distancePointLine(Coordinate p,Coordinate A,Coordinate B){
	//if start==end, then use pt distance
	if (A==B) return A.distance(B);

    // otherwise use comp.graphics.algorithms Frequently Asked Questions method
    /*(1)     	      AC dot AB
                   r = ---------
                         ||AB||^2
		r has the following meaning:
		r=0 P = A
		r=1 P = B
		r<0 P is on the backward extension of AB
		r>1 P is on the forward extension of AB
		0<r<1 P is interior to AB
	*/
	double r=((p.x-A.x)*(B.x-A.x)+(p.y-A.y)*(B.y-A.y))/
			 ((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));
	if (r<0) return p.distance(A);
	if (r>1) return p.distance(B);
    /*(2)
		     (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
		s = -----------------------------
		             	L^2

		Then the distance from C to P = |s|*L.
	*/
	double s=((A.y-p.y)*(B.x-A.x)-(A.x-p.x)*(B.y-A.y))/
			 ((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));
	return fabs(s)*sqrt(((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y)));
}

/**
* Computes the distance from a line segment AB to a line segment CD
*
* Note: NON-ROBUST!
*/
double CGAlgorithms::distanceLineLine(Coordinate A,Coordinate B,Coordinate C,Coordinate D){
	// check for zero-length segments
	if (A==B) return distancePointLine(A,C,D);
	if (C==D) return distancePointLine(D,A,B);

    // AB and CD are line segments
    /* from comp.graphics.algo

	Solving the above for r and s yields
				(Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
	           r = ----------------------------- (eqn 1)
				(Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)

		 	(Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
		s = ----------------------------- (eqn 2)
			(Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
	Let P be the position vector of the intersection point, then
		P=A+r(B-A) or
		Px=Ax+r(Bx-Ax)
		Py=Ay+r(By-Ay)
	By examining the values of r & s, you can also determine some other
limiting conditions:
		If 0<=r<=1 & 0<=s<=1, intersection exists
		r<0 or r>1 or s<0 or s>1 line segments do not intersect
		If the denominator in eqn 1 is zero, AB & CD are parallel
		If the numerator in eqn 1 is also zero, AB & CD are collinear.

	*/
	double r_top=(A.y-C.y)*(D.x-C.x)-(A.x-C.x)*(D.y-C.y);
	double r_bot=(B.x-A.x)*(D.y-C.y)-(B.y-A.y)*(D.x-C.x);
	double s_top=(A.y-C.y)*(B.x-A.x)-(A.x-C.x)*(B.y-A.y);
	double s_bot=(B.x-A.x)*(D.y-C.y)-(B.y-A.y)*(D.x-C.x);
	if ((r_bot==0)||(s_bot==0)) {
		return min(distancePointLine(A,C,D),min(distancePointLine(B,C,D),min(distancePointLine(C,A,B),distancePointLine(D,A,B))));
	}
	double s=s_top/s_bot;
	double r=r_top/r_bot;
	if ((r<0)||( r>1)||(s<0)||(s>1)) {
		//no intersection
		return min(distancePointLine(A,C,D),min(distancePointLine(B,C,D),min(distancePointLine(C,A,B),distancePointLine(D,A,B))));
	}
	return 0.0; //intersection exists
}

/**
* Returns the signed area for a ring.  The area is positive if
* the ring is oriented CW.
*/
<<<<<<< CGAlgorithms.cpp
double CGAlgorithms::signedArea(CoordinateList* ring) {
	if (ring->getSize()<3) return 0.0;
=======
double CGAlgorithms::signedArea(CoordinateList& ring) {
	if (ring.getSize()<3) return 0.0;
>>>>>>> 1.2
	double sum=0.0;
	double ax=ring->getAt(0).x;
	double ay=ring->getAt(0).y;
	for (int i=1;i<ring->getSize()-1;i++) {
		double bx=ring->getAt(i).x;
		double by=ring->getAt(i).y;
		double cx=ring->getAt(i+1).x;
		double cy=ring->getAt(i+1).y;
		sum+=ax*by-ay*bx+ay*cx-ax*cy+bx*cy-cx*by;
	}
	return -sum/2.0;
}

/**
* Returns the length of a list of line segments.
*/
<<<<<<< CGAlgorithms.cpp
double CGAlgorithms::length(CoordinateList* pts) {
	if (pts->getSize()<1) return 0.0;
=======
double CGAlgorithms::length(CoordinateList& pts) {
	if (pts.getSize()<1) return 0.0;
>>>>>>> 1.2
	double sum=0.0;
	for(int i=1;i<pts->getSize();i++) {
		sum+=pts->getAt(i).distance(pts->getAt(i - 1));
	}
	return sum;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2011 Laszlo Papp <djszapi@archlinux.us>
 *
 * This library 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.
 *
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "qgitrevwalk.h"

#include "qgitcommit.h"
#include "qgitrepository.h"

#include <git2/revwalk.h>

using namespace LibQGit2;

QGitRevWalk::QGitRevWalk(const QGitRepository& repository)
{
    git_revwalk_new(&m_revWalk, repository.data());
}

QGitRevWalk::QGitRevWalk( const QGitRevWalk& other )
{
    m_revWalk = other.m_revWalk;
}

QGitRevWalk::~QGitRevWalk()
{
    git_revwalk_free(m_revWalk);
}

void QGitRevWalk::reset() const
{
    return git_revwalk_reset(m_revWalk);
}

int QGitRevWalk::push(const QGitOId& oid) const
{
    return git_revwalk_push(m_revWalk, oid.data());
}

int QGitRevWalk::hide(const QGitOId& oid) const
{
    return git_revwalk_hide(m_revWalk, oid.data());
}

QGitOId QGitRevWalk::next()
{
    QGitOId oid;
    git_revwalk_next(oid.data(), m_revWalk);
    return oid;
}

void QGitRevWalk::sorting(unsigned int sortMode)
void QGitRevWalk::setSorting(SortModes sortMode)
{
    // wrap c defines
    unsigned int sort = GIT_SORT_NONE;
    if (sortMode | Time)
        sort |= GIT_SORT_TIME;
    if (sortMode | Topological)
        sort |= GIT_SORT_TOPOLOGICAL;
    if (sortMode | Reverse)
        sort |= GIT_SORT_REVERSE;

    git_revwalk_sorting(m_revWalk, sort);
}

QGitRepository QGitRevWalk::repository()
{
    return QGitRepository(git_revwalk_repository(m_revWalk));
}

git_revwalk* QGitRevWalk::data() const
{
    return m_revWalk;
}

const git_revwalk* QGitRevWalk::constData() const
{
    return m_revWalk;
}

<commit_msg>wrapped GIT_SORT_… flags to Qt style flags; avoid forcing direct usage of libgit2 headers; renamed method sorting to setSorting as it is actually a setter<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2011 Laszlo Papp <djszapi@archlinux.us>
 *
 * This library 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.
 *
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "qgitrevwalk.h"

#include "qgitcommit.h"
#include "qgitrepository.h"

#include <git2/revwalk.h>

using namespace LibQGit2;

QGitRevWalk::QGitRevWalk(const QGitRepository& repository)
{
    git_revwalk_new(&m_revWalk, repository.data());
}

QGitRevWalk::QGitRevWalk( const QGitRevWalk& other )
{
    m_revWalk = other.m_revWalk;
}

QGitRevWalk::~QGitRevWalk()
{
    git_revwalk_free(m_revWalk);
}

void QGitRevWalk::reset() const
{
    return git_revwalk_reset(m_revWalk);
}

int QGitRevWalk::push(const QGitOId& oid) const
{
    return git_revwalk_push(m_revWalk, oid.data());
}

int QGitRevWalk::hide(const QGitOId& oid) const
{
    return git_revwalk_hide(m_revWalk, oid.data());
}

QGitOId QGitRevWalk::next()
{
    QGitOId oid;
    git_revwalk_next(oid.data(), m_revWalk);
    return oid;
}

void QGitRevWalk::setSorting(SortModes sortMode)
{
    // wrap c defines
    unsigned int sort = GIT_SORT_NONE;
    if (sortMode | Time)
        sort |= GIT_SORT_TIME;
    if (sortMode | Topological)
        sort |= GIT_SORT_TOPOLOGICAL;
    if (sortMode | Reverse)
        sort |= GIT_SORT_REVERSE;

    git_revwalk_sorting(m_revWalk, sort);
}

QGitRepository QGitRevWalk::repository()
{
    return QGitRepository(git_revwalk_repository(m_revWalk));
}

git_revwalk* QGitRevWalk::data() const
{
    return m_revWalk;
}

const git_revwalk* QGitRevWalk::constData() const
{
    return m_revWalk;
}

<|endoftext|>