<commit_before>/*  libscratch - Multipurpose objective C++ library.
    Copyright (C) 2012 - 2013  Angelo Geels

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

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

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#include <cstdio> // for printf
#include <iostream> // for std::cin.get

#include <Scratch.h>

static INDEX _ctTests = 0;
static INDEX _ctFailed = 0;

#define TEST(expr) {                            \
  BOOL bSuccess = (expr);                       \
  _ctTests++;                                   \
  ASSERT(bSuccess);                             \
  printf("  Test #%d: (%s) ", _ctTests, #expr); \
  if(!bSuccess) {                               \
    _ctFailed++;                                \
    printf("FAILED!\n");                        \
  } else {                                      \
    printf("OK\n");                             \
  }                                             \
}

/// String testing
void TestString()
{
  printf("Testing strings\n");

  CString strTest;
  strTest += "Lib";
  strTest += "Scratch";
  strTest = strTest.ToLower();
  TEST(strTest == "libscratch");

  strTest += " is great";
  CStackArray<CString> astrParse = strTest.Split(" ");
  TEST(astrParse[2] == "great");
  TEST(astrParse[2][1] == 'r');

  CString strTest2 = strTest.Replace("great", "cool");
  TEST(strTest2 == "libscratch is cool");
}

/// Stack array testing
void TestStackArray()
{
  printf("Testing stack arrays\n");

  CStackArray<INDEX> aiNumbers;
  TEST(aiNumbers.Count() == 0);

  aiNumbers.Push() = 5;
  aiNumbers.Push() = 10;
  aiNumbers.Push() = 15;
  TEST(aiNumbers.Count() == 3);
  TEST(aiNumbers[0] == 5);
  TEST(aiNumbers[1] == 10);
  TEST(aiNumbers[2] + aiNumbers[0] == 20);

  TEST(aiNumbers.Pop() == 15);
  TEST(aiNumbers.Count() == 2);
}

/// Dictionary testing
void TestDictionary()
{
  printf("Testing dictionary\n");

  CDictionary<CString, INDEX> diTest;
  TEST(!diTest.HasKey("Test"));

  diTest["Test"] = 100;
  diTest["Test2"] = 200;
  TEST(diTest.HasKey("Test"));
  TEST(diTest["Test"] == 100);

  diTest.RemoveByKey("Test");
  TEST(diTest.Count() == 1);
  TEST(!diTest.HasKey("Test"));
}

/// Test file stream
void TestFilestream()
{
  printf("Testing file streams\n");

  // this test will create a Test.bin file, containing an integer 5 and the text "Hello!"
  CFileStream fsTest;
  fsTest.Open("Test.bin", "w");
  fsTest << INDEX(5);
  fsTest << "Hello!";
  fsTest.Close();

  // as a follow-up, we will read the same file from a seperate file stream
  CFileStream fsTestRead;
  fsTestRead.Open("Test.bin", "r");

  INDEX iTest = 0;
  fsTestRead >> iTest;
  TEST(iTest == 5);

  CString strTest;
  fsTestRead >> strTest;
  TEST(strTest == "Hello!");

  // note that closing the stream is optional (destructor does it for us), however we need to have it closed for the unlink below
  fsTestRead.Close();

  // remove the test file from the system
  unlink("Test.bin");
}

int main()
{
  // perform tests
  TestString();
  TestStackArray();
  TestDictionary();
  TestFilestream();

  // report test results
  printf("\n\nResults: %d out of %d went OK.\n\n", _ctTests - _ctFailed, _ctTests);

  // check if all went OK
  if(_ctFailed == 0) {
    // it did! no failures. :)
    printf("All OK!\n");
  } else {
    // oops, there's a bug somewhere. please report!
    printf("Some problems seem to have popped up. Please report a bug.\n");
  }

  std::cin.get();
  return 0;
}
<commit_msg>Added vector tests<commit_after>/*  libscratch - Multipurpose objective C++ library.
    Copyright (C) 2012 - 2013  Angelo Geels

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

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

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#include <cstdio> // for printf
#include <iostream> // for std::cin.get

#include <Scratch.h>

static INDEX _ctTests = 0;
static INDEX _ctFailed = 0;

#define TEST(expr) {                            \
  BOOL bSuccess = (expr);                       \
  _ctTests++;                                   \
  ASSERT(bSuccess);                             \
  printf("  Test #%d: (%s) ", _ctTests, #expr); \
  if(!bSuccess) {                               \
    _ctFailed++;                                \
    printf("FAILED!\n");                        \
  } else {                                      \
    printf("OK\n");                             \
  }                                             \
}

/// String testing
void TestString()
{
  printf("Testing strings\n");

  CString strTest;
  strTest += "Lib";
  strTest += "Scratch";
  strTest = strTest.ToLower();
  TEST(strTest == "libscratch");

  strTest += " is great";
  CStackArray<CString> astrParse = strTest.Split(" ");
  TEST(astrParse[2] == "great");
  TEST(astrParse[2][1] == 'r');

  CString strTest2 = strTest.Replace("great", "cool");
  TEST(strTest2 == "libscratch is cool");
}

/// Stack array testing
void TestStackArray()
{
  printf("Testing stack arrays\n");

  CStackArray<INDEX> aiNumbers;
  TEST(aiNumbers.Count() == 0);

  aiNumbers.Push() = 5;
  aiNumbers.Push() = 10;
  aiNumbers.Push() = 15;
  TEST(aiNumbers.Count() == 3);
  TEST(aiNumbers[0] == 5);
  TEST(aiNumbers[1] == 10);
  TEST(aiNumbers[2] + aiNumbers[0] == 20);

  TEST(aiNumbers.Pop() == 15);
  TEST(aiNumbers.Count() == 2);
}

/// Dictionary testing
void TestDictionary()
{
  printf("Testing dictionary\n");

  CDictionary<CString, INDEX> diTest;
  TEST(!diTest.HasKey("Test"));

  diTest["Test"] = 100;
  diTest["Test2"] = 200;
  TEST(diTest.HasKey("Test"));
  TEST(diTest["Test"] == 100);

  diTest.RemoveByKey("Test");
  TEST(diTest.Count() == 1);
  TEST(!diTest.HasKey("Test"));
}

/// Test file stream
void TestFilestream()
{
  printf("Testing file streams\n");

  // this test will create a Test.bin file, containing an integer 5 and the text "Hello!"
  CFileStream fsTest;
  fsTest.Open("Test.bin", "w");
  fsTest << INDEX(5);
  fsTest << "Hello!";
  fsTest.Close();

  // as a follow-up, we will read the same file from a seperate file stream
  CFileStream fsTestRead;
  fsTestRead.Open("Test.bin", "r");

  INDEX iTest = 0;
  fsTestRead >> iTest;
  TEST(iTest == 5);

  CString strTest;
  fsTestRead >> strTest;
  TEST(strTest == "Hello!");

  // note that closing the stream is optional (destructor does it for us), however we need to have it closed for the unlink below
  fsTestRead.Close();

  // remove the test file from the system
  unlink("Test.bin");
}

/// Vector tests
void TestVectors()
{
  printf("Testing vectors\n");

  Vector3f vTest(1, 0, 0);
  TEST(vTest.Length() == 1.0f);

  vTest *= 5.0f;
  TEST(vTest.Length() == 5.0f);

  vTest.x = 3;
  vTest.y = 4;
  TEST(vTest.Length() == 5.0f);

  vTest.Normalize();
  TEST(vTest.Length() == 1.0f);
}

int main()
{
  // perform tests
  TestString();
  TestStackArray();
  TestDictionary();
  TestFilestream();
  TestVectors();

  // report test results
  printf("\n\nResults: %d out of %d went OK.\n\n", _ctTests - _ctFailed, _ctTests);

  // check if all went OK
  if(_ctFailed == 0) {
    // it did! no failures. :)
    printf("All OK!\n");
  } else {
    // oops, there's a bug somewhere. please report!
    printf("Some problems seem to have popped up. Please report a bug.\n");
  }

  std::cin.get();
  return 0;
}
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_BASEFUNCTIONSET_FEM_HH
#define DUNE_GDT_BASEFUNCTIONSET_FEM_HH

#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>

#include <dune/fem/space/basefunctions/basefunctionsetinterface.hh>
#include <dune/fem/space/common/discretefunctionspace.hh>

#include <dune/stuff/common/memory.hh>

#include "interface.hh"

namespace Dune {
namespace GDT {
namespace BaseFunctionSet {

// forward, to be used in the traits and to allow for specialization
template <class FemBaseFunctionSetTraits, class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp,
          int rangeDim, int rangeDimCols = 1>
class FemWrapper;

template <class FemBaseFunctionSetTraits, class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp,
          int rangeDim, int rangeDimCols = 1>
class FemWrapperTraits
{
public:
  typedef FemWrapper<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim,
                     rangeDimCols> derived_type;
  typedef typename Dune::Fem::BaseFunctionSetInterface<FemBaseFunctionSetTraits>::BaseFunctionSetType BackendType;
  typedef EntityImp EntityType;
};

template <class FemBaseFunctionSetTraits, class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp,
          int rangeDim>
class FemWrapper<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
    : public BaseFunctionSetInterface<FemWrapperTraits<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim,
                                                       RangeFieldImp, rangeDim, 1>,
                                      DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
{
  typedef FemWrapper<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
      ThisType;
  typedef BaseFunctionSetInterface<FemWrapperTraits<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim,
                                                    RangeFieldImp, rangeDim, 1>,
                                   DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1> BaseType;

public:
  typedef FemWrapperTraits<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
      Traits;
  typedef typename Traits::BackendType BackendType;
  typedef typename Traits::EntityType EntityType;

  typedef DomainFieldImp DomainFieldType;
  static const unsigned int dimDomain = domainDim;
  typedef Dune::FieldVector<DomainFieldType, dimDomain> DomainType;
  typedef RangeFieldImp RangeFieldType;
  static const unsigned int dimRange     = rangeDim;
  static const unsigned int dimRangeCols = 1;
  typedef Dune::FieldVector<RangeFieldType, dimRange> RangeType;
  typedef Dune::FieldMatrix<RangeFieldType, dimRange, dimDomain> JacobianRangeType;

  template <class S>
  FemWrapper(const Dune::Fem::DiscreteFunctionSpaceInterface<S>& femSpace, const EntityType& ent)
    : BaseType(ent)
    , order_(femSpace.order())
    , backend_(new BackendType(femSpace.baseFunctionSet(this->entity())))
  {
  }

  FemWrapper(ThisType&& source)
    : BaseType(source.entity())
    , order_(std::move(source.order_))
    , backend_(std::move(source.backend_))
  {
  }

  FemWrapper(const ThisType& /*other*/) = delete;

  ThisType& operator=(const ThisType& /*other*/) = delete;

  const BackendType& backend() const
  {
    return *backend_;
  }

  virtual size_t size() const DS_OVERRIDE
  {
    return backend_->size();
  }

  virtual size_t order() const DS_OVERRIDE
  {
    return order_;
  }

  virtual void evaluate(const DomainType& xx, std::vector<RangeType>& ret) const DS_OVERRIDE
  {
    assert(ret.size() >= backend_->size());
    backend_->evaluateAll(xx, ret);
  }

  using BaseType::evaluate;

  virtual void jacobian(const DomainType& xx, std::vector<JacobianRangeType>& ret) const DS_OVERRIDE
  {
    assert(ret.size() >= backend_->size());
    backend_->jacobianAll(xx, this->entity().geometry().jacobianInverseTransposed(xx), ret);
  }

  using BaseType::jacobian;

private:
  const size_t order_;
  std::unique_ptr<const BackendType> backend_;
}; // class FemWrapper

} // namespace BaseFunctionSet
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_BASEFUNCTIONSET_FEM_HH
<commit_msg>[basefunctionset.fem] add proper guards<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_BASEFUNCTIONSET_FEM_HH
#define DUNE_GDT_BASEFUNCTIONSET_FEM_HH

#include <type_traits>

#include <dune/common/typetraits.hh>
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>

#ifdef HAVE_DUNE_FEM
#include <dune/fem/space/basefunctions/basefunctionsetinterface.hh>
#include <dune/fem/space/common/discretefunctionspace.hh>
#endif // HAVE_DUNE_FEM

#include <dune/stuff/common/memory.hh>

#include "interface.hh"

namespace Dune {
namespace GDT {
namespace BaseFunctionSet {

#ifdef HAVE_DUNE_FEM

// forward, to be used in the traits and to allow for specialization
template <class FemBaseFunctionSetTraits, class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp,
          int rangeDim, int rangeDimCols = 1>
class FemWrapper
{
  static_assert(Dune::AlwaysFalse<FemBaseFunctionSetTraits>::value, "Untested for these dimensions!");
};

template <class FemBaseFunctionSetTraits, class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp,
          int rangeDim, int rangeDimCols = 1>
class FemWrapperTraits
{
public:
  typedef FemWrapper<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim,
                     rangeDimCols> derived_type;
  typedef typename Dune::Fem::BaseFunctionSetInterface<FemBaseFunctionSetTraits>::BaseFunctionSetType BackendType;
  typedef EntityImp EntityType;
};

template <class FemBaseFunctionSetTraits, class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp,
          int rangeDim>
class FemWrapper<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
    : public BaseFunctionSetInterface<FemWrapperTraits<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim,
                                                       RangeFieldImp, rangeDim, 1>,
                                      DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
{
  typedef FemWrapper<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
      ThisType;
  typedef BaseFunctionSetInterface<FemWrapperTraits<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim,
                                                    RangeFieldImp, rangeDim, 1>,
                                   DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1> BaseType;

public:
  typedef FemWrapperTraits<FemBaseFunctionSetTraits, EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
      Traits;
  typedef typename Traits::BackendType BackendType;
  typedef typename Traits::EntityType EntityType;

  typedef DomainFieldImp DomainFieldType;
  static const unsigned int dimDomain = domainDim;
  typedef Dune::FieldVector<DomainFieldType, dimDomain> DomainType;
  typedef RangeFieldImp RangeFieldType;
  static const unsigned int dimRange     = rangeDim;
  static const unsigned int dimRangeCols = 1;
  typedef Dune::FieldVector<RangeFieldType, dimRange> RangeType;
  typedef Dune::FieldMatrix<RangeFieldType, dimRange, dimDomain> JacobianRangeType;

  template <class S>
  FemWrapper(const Dune::Fem::DiscreteFunctionSpaceInterface<S>& femSpace, const EntityType& ent)
    : BaseType(ent)
    , order_(femSpace.order())
    , backend_(new BackendType(femSpace.baseFunctionSet(this->entity())))
  {
  }

  FemWrapper(ThisType&& source)
    : BaseType(source.entity())
    , order_(std::move(source.order_))
    , backend_(std::move(source.backend_))
  {
  }

  FemWrapper(const ThisType& /*other*/) = delete;

  ThisType& operator=(const ThisType& /*other*/) = delete;

  const BackendType& backend() const
  {
    return *backend_;
  }

  virtual size_t size() const DS_OVERRIDE
  {
    return backend_->size();
  }

  virtual size_t order() const DS_OVERRIDE
  {
    return order_;
  }

  virtual void evaluate(const DomainType& xx, std::vector<RangeType>& ret) const DS_OVERRIDE
  {
    assert(ret.size() >= backend_->size());
    backend_->evaluateAll(xx, ret);
  }

  using BaseType::evaluate;

  virtual void jacobian(const DomainType& xx, std::vector<JacobianRangeType>& ret) const DS_OVERRIDE
  {
    assert(ret.size() >= backend_->size());
    backend_->jacobianAll(xx, this->entity().geometry().jacobianInverseTransposed(xx), ret);
  }

  using BaseType::jacobian;

private:
  const size_t order_;
  std::unique_ptr<const BackendType> backend_;
}; // class FemWrapper

#else // HAVE_DUNE_FEM

template <class FemBaseFunctionSetTraits, class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp,
          int rangeDim, int rangeDimCols = 1>
class FemWrapper
{
  static_assert(Dune::AlwaysFalse<FemBaseFunctionSetTraits>::value, "You are missing dune-fem!");
};

#endif // HAVE_DUNE_FEM

} // namespace BaseFunctionSet
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_BASEFUNCTIONSET_FEM_HH
<|endoftext|>


<commit_before>#ifndef DUNE_HELPER_TOOLS_GRID_INTERSECTION_HH
#define DUNE_FEMTOOLS_GRID_INTERSECTION_HH

#ifdef HAVE_CMAKE_CONFIG
 #include "cmake_config.h"
#else
 #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

// dune-common includes
#include <dune/common/fvector.hh>
#include <dune/common/static_assert.hh>

// dune-stuff
#include <dune/stuff/common/string.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

/**
  \brief      prints some basic information about a Dune::Intersection, namely the number of its corners and the
              coordinates of those corners.
  \tparam     IntersectionType
              Dune::Intersection compatible
  \param[in]  intersection
              Dune::Intersection, whose information should be printed
  \param[out] stream
              std::ostream, into which the information is printed
  **/
template< class IntersectionType >
void printIntersection( const IntersectionType& intersection, std::ostream& stream = std::cout )
{
  typedef typename IntersectionType::Geometry
    GeometryType;

  typedef typename GeometryType::GlobalCoordinate
    GlobalPointType;

  const GeometryType& geometry = intersection.geometry();

  const int numCorners = geometry.corners();

  std::string prefix = "Dune::Intersection (" + Dune::Stuff::Common::toString( numCorners ) + " corner";
  if( numCorners != 1 )
  {
    prefix += "s";
  }
  prefix += "): ";
  const unsigned int missing = 32 - prefix.size();
  if( missing > 0 )
  {
    for( unsigned int i = 0; i < missing; ++i )
    {
      prefix += " ";
    }
  }
  const std::string whitespace = Dune::Stuff::Common::whitespaceify( prefix );

  stream << prefix << "[ (";
  for( int i = 0; i < numCorners; ++i )
  {
    const GlobalPointType corner = geometry.corner( i );
    for( unsigned int j = 0; j < corner.size(); ++ j )
    {
      stream << corner[j];
      if( j < corner.size() - 1 )
      {
        stream << ", " ;
      }
    }
    stream << ")";
    if( i < geometry.corners() - 1 )
    {
      stream << "," << std::endl << whitespace << "  (";
    }
    else{
      stream << " ]" << std::endl;
    }
  }

} // end function print

template< class IntersectionType, class FieldType, int size >
bool intersectionContains( const IntersectionType& /*intersection*/, const Dune::FieldVector< FieldType, size >& /*globalPoint*/ )
{
  dune_static_assert( size < 3, "Dune::FemTools::Grid::Intersection::contains() not implemented for more than 2 dimension!" );
  return false;
}

template< class IntersectionType, class FieldType >
bool intersectionContains( const IntersectionType& intersection, const Dune::FieldVector< FieldType, 1 >& globalPoint )
{
  typedef Dune::FieldVector< FieldType, 1 >
    GlobalPointType;

  typedef typename IntersectionType::Geometry
    GeometryType;

  const GeometryType& geometry = intersection.geometry();

  // get the only corner
  const GlobalPointType corner = geometry.corner( 0 );
  // check if the point is the corner
  if( corner == globalPoint )
  {
    return true;
  }

  return false;
} // end function contains

template< class IntersectionType, class FieldType >
bool intersectionContains( const IntersectionType& intersection, const Dune::FieldVector< FieldType, 2 > & globalPoint )
{
  typedef Dune::FieldVector< FieldType, 2 >
    GlobalPointType;

  typedef typename IntersectionType::Geometry
    GeometryType;

  const GeometryType& geometry = intersection.geometry();

  // get the two corners
  const GlobalPointType firstCorner = geometry.corner( 0 );
  const GlobalPointType secondCorner = geometry.corner( 1 );

  // check, that point is on the line between the two points
  const FieldType x1 = ( globalPoint[0] - firstCorner[0] ) / ( secondCorner[0] - firstCorner[0] );
  const FieldType x2 = ( globalPoint[1] - firstCorner[1] ) / ( secondCorner[1] - firstCorner[1] );
  if( !( x1 > x2 ) && !( x1 < x2 ) && !( x1 < 0.0 ) && !( x1 > 1.0 ) )
  {
    return true;
  }

  return false;
} // end function contains

} // end namespace Grid
} // end of namespace Stuff
} // end namespace Dune

#endif // DUNE_FEMTOOLS_GRID_INTERSECTION_HH
/** Copyright (c) 2012, Felix Albrecht
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice, this
   *    list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * The views and conclusions contained in the software and documentation are those
   * of the authors and should not be interpreted as representing official policies,
   * either expressed or implied, of the FreeBSD Project.
   **/
<commit_msg>[grid] fix headerguard snafu<commit_after>#ifndef DUNE_STUFF_GRID_INTERSECTION_HH
#define DUNE_STUFF_GRID_INTERSECTION_HH

#ifdef HAVE_CMAKE_CONFIG
 #include "cmake_config.h"
#else
 #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

// dune-common includes
#include <dune/common/fvector.hh>
#include <dune/common/static_assert.hh>

// dune-stuff
#include <dune/stuff/common/string.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

/**
  \brief      prints some basic information about a Dune::Intersection, namely the number of its corners and the
              coordinates of those corners.
  \tparam     IntersectionType
              Dune::Intersection compatible
  \param[in]  intersection
              Dune::Intersection, whose information should be printed
  \param[out] stream
              std::ostream, into which the information is printed
  **/
template< class IntersectionType >
void printIntersection( const IntersectionType& intersection, std::ostream& stream = std::cout )
{
  typedef typename IntersectionType::Geometry
    GeometryType;

  typedef typename GeometryType::GlobalCoordinate
    GlobalPointType;

  const GeometryType& geometry = intersection.geometry();

  const int numCorners = geometry.corners();

  std::string prefix = "Dune::Intersection (" + Dune::Stuff::Common::toString( numCorners ) + " corner";
  if( numCorners != 1 )
  {
    prefix += "s";
  }
  prefix += "): ";
  const unsigned int missing = 32 - prefix.size();
  if( missing > 0 )
  {
    for( unsigned int i = 0; i < missing; ++i )
    {
      prefix += " ";
    }
  }
  const std::string whitespace = Dune::Stuff::Common::whitespaceify( prefix );

  stream << prefix << "[ (";
  for( int i = 0; i < numCorners; ++i )
  {
    const GlobalPointType corner = geometry.corner( i );
    for( unsigned int j = 0; j < corner.size(); ++ j )
    {
      stream << corner[j];
      if( j < corner.size() - 1 )
      {
        stream << ", " ;
      }
    }
    stream << ")";
    if( i < geometry.corners() - 1 )
    {
      stream << "," << std::endl << whitespace << "  (";
    }
    else{
      stream << " ]" << std::endl;
    }
  }

} // end function print

template< class IntersectionType, class FieldType, int size >
bool intersectionContains( const IntersectionType& /*intersection*/, const Dune::FieldVector< FieldType, size >& /*globalPoint*/ )
{
  dune_static_assert( size < 3, "Dune::FemTools::Grid::Intersection::contains() not implemented for more than 2 dimension!" );
  return false;
}

template< class IntersectionType, class FieldType >
bool intersectionContains( const IntersectionType& intersection, const Dune::FieldVector< FieldType, 1 >& globalPoint )
{
  typedef Dune::FieldVector< FieldType, 1 >
    GlobalPointType;

  typedef typename IntersectionType::Geometry
    GeometryType;

  const GeometryType& geometry = intersection.geometry();

  // get the only corner
  const GlobalPointType corner = geometry.corner( 0 );
  // check if the point is the corner
  if( corner == globalPoint )
  {
    return true;
  }

  return false;
} // end function contains

template< class IntersectionType, class FieldType >
bool intersectionContains( const IntersectionType& intersection, const Dune::FieldVector< FieldType, 2 > & globalPoint )
{
  typedef Dune::FieldVector< FieldType, 2 >
    GlobalPointType;

  typedef typename IntersectionType::Geometry
    GeometryType;

  const GeometryType& geometry = intersection.geometry();

  // get the two corners
  const GlobalPointType firstCorner = geometry.corner( 0 );
  const GlobalPointType secondCorner = geometry.corner( 1 );

  // check, that point is on the line between the two points
  const FieldType x1 = ( globalPoint[0] - firstCorner[0] ) / ( secondCorner[0] - firstCorner[0] );
  const FieldType x2 = ( globalPoint[1] - firstCorner[1] ) / ( secondCorner[1] - firstCorner[1] );
  if( !( x1 > x2 ) && !( x1 < x2 ) && !( x1 < 0.0 ) && !( x1 > 1.0 ) )
  {
    return true;
  }

  return false;
} // end function contains

} // end namespace Grid
} // end of namespace Stuff
} // end namespace Dune

#endif // DUNE_STUFF_GRID_INTERSECTION_HH
/** Copyright (c) 2012, Felix Albrecht
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice, this
   *    list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * The views and conclusions contained in the software and documentation are those
   * of the authors and should not be interpreted as representing official policies,
   * either expressed or implied, of the FreeBSD Project.
   **/
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012,2017-2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

#ifndef __BASE_COMPILER_HH__
#define __BASE_COMPILER_HH__

#include <memory>

// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

#if defined(__GNUC__) // clang or gcc
#  define M5_ATTR_NORETURN  __attribute__((noreturn))
#  define M5_DUMMY_RETURN
#  define M5_VAR_USED __attribute__((unused))
#  define M5_ATTR_PACKED __attribute__ ((__packed__))
#  define M5_NO_INLINE __attribute__ ((__noinline__))
#  define M5_DEPRECATED __attribute__((deprecated))
#  define M5_DEPRECATED_MSG(MSG) __attribute__((deprecated(MSG)))
#  define M5_UNREACHABLE __builtin_unreachable()
#  define M5_PUBLIC __attribute__ ((visibility ("default")))
#  define M5_LOCAL __attribute__ ((visibility ("hidden")))
#endif

#if defined(__clang__)
#  define M5_CLASS_VAR_USED M5_VAR_USED
#else
#  define M5_CLASS_VAR_USED
#endif

// This can be removed once all compilers support C++17
#if defined __has_cpp_attribute
    // Note: We must separate this if statement because GCC < 5.0 doesn't
    //       support the function-like syntax in #if statements.
    #if __has_cpp_attribute(fallthrough)
        #define M5_FALLTHROUGH [[fallthrough]]
    #else
        #define M5_FALLTHROUGH
    #endif

    #if __has_cpp_attribute(nodiscard)
        #define M5_NODISCARD [[nodiscard]]
    #else
        #define M5_NODISCARD
    #endif
#else
    // Unsupported (and no warning) on GCC < 7.
    #define M5_FALLTHROUGH

    #define M5_NODISCARD
#endif

// std::make_unique redefined for C++11 compilers
namespace m5
{

#if __cplusplus == 201402L // C++14

using std::make_unique;

#else // C++11

/** Defining custom version of make_unique: m5::make_unique<>() */
template<typename T, typename... Args>
std::unique_ptr<T>
make_unique( Args&&... constructor_args )
{
    return std::unique_ptr<T>(
               new T( std::forward<Args>(constructor_args)... )
           );
}

#endif // __cplusplus == 201402L

} //namespace m5

#endif // __BASE_COMPILER_HH__
<commit_msg>base: Replace cppversion == version with >= version<commit_after>/*
 * Copyright (c) 2012,2017-2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

#ifndef __BASE_COMPILER_HH__
#define __BASE_COMPILER_HH__

#include <memory>

// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

#if defined(__GNUC__) // clang or gcc
#  define M5_ATTR_NORETURN  __attribute__((noreturn))
#  define M5_DUMMY_RETURN
#  define M5_VAR_USED __attribute__((unused))
#  define M5_ATTR_PACKED __attribute__ ((__packed__))
#  define M5_NO_INLINE __attribute__ ((__noinline__))
#  define M5_DEPRECATED __attribute__((deprecated))
#  define M5_DEPRECATED_MSG(MSG) __attribute__((deprecated(MSG)))
#  define M5_UNREACHABLE __builtin_unreachable()
#  define M5_PUBLIC __attribute__ ((visibility ("default")))
#  define M5_LOCAL __attribute__ ((visibility ("hidden")))
#endif

#if defined(__clang__)
#  define M5_CLASS_VAR_USED M5_VAR_USED
#else
#  define M5_CLASS_VAR_USED
#endif

// This can be removed once all compilers support C++17
#if defined __has_cpp_attribute
    // Note: We must separate this if statement because GCC < 5.0 doesn't
    //       support the function-like syntax in #if statements.
    #if __has_cpp_attribute(fallthrough)
        #define M5_FALLTHROUGH [[fallthrough]]
    #else
        #define M5_FALLTHROUGH
    #endif

    #if __has_cpp_attribute(nodiscard)
        #define M5_NODISCARD [[nodiscard]]
    #else
        #define M5_NODISCARD
    #endif
#else
    // Unsupported (and no warning) on GCC < 7.
    #define M5_FALLTHROUGH

    #define M5_NODISCARD
#endif

// std::make_unique redefined for C++11 compilers
namespace m5
{

#if __cplusplus >= 201402L // C++14

using std::make_unique;

#else // C++11

/** Defining custom version of make_unique: m5::make_unique<>() */
template<typename T, typename... Args>
std::unique_ptr<T>
make_unique( Args&&... constructor_args )
{
    return std::unique_ptr<T>(
               new T( std::forward<Args>(constructor_args)... )
           );
}

#endif // __cplusplus >= 201402L

} //namespace m5

#endif // __BASE_COMPILER_HH__
<|endoftext|>


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

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <arith_uint256.h>
#include <clientversion.h>
#include <coins.h>
#include <consensus/consensus.h>
#include <core_io.h>
#include <key_io.h>
#include <policy/rbf.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <univalue.h>
#include <util/moneystr.h>
#include <util/rbf.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>

#include <functional>
#include <memory>
#include <stdio.h>
#include <thread>

#include <boost/algorithm/string.hpp>

static const int CONTINUE_EXECUTION=-1;

const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;

static void SetupBitcoinUtilArgs(ArgsManager &argsman)
{
    SetupHelpOptions(argsman);

    argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);

    SetupChainParamsBaseOptions(argsman);
}

// This function returns either one of EXIT_ codes when it's expected to stop the process or
// CONTINUE_EXECUTION when it's expected to continue further.
static int AppInitUtil(int argc, char* argv[])
{
    SetupBitcoinUtilArgs(gArgs);
    std::string error;
    if (!gArgs.ParseParameters(argc, argv, error)) {
        tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error);
        return EXIT_FAILURE;
    }

    // Check for chain settings (Params() calls are only valid after this clause)
    try {
        SelectParams(gArgs.GetChainName());
    } catch (const std::exception& e) {
        tfm::format(std::cerr, "Error: %s\n", e.what());
        return EXIT_FAILURE;
    }

    if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
        // First part of help message is specific to this utility
        std::string strUsage = PACKAGE_NAME " bitcoin-util utility version " + FormatFullVersion() + "\n";
        if (!gArgs.IsArgSet("-version")) {
            strUsage += "\n"
                "Usage:  bitcoin-util [options] [commands]  Do stuff\n";
            strUsage += "\n" + gArgs.GetHelpMessage();
        }

        tfm::format(std::cout, "%s", strUsage);

        if (argc < 2) {
            tfm::format(std::cerr, "Error: too few parameters\n");
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
    }
    return CONTINUE_EXECUTION;
}

static void grind_task(uint32_t nBits, CBlockHeader& header_orig, uint32_t offset, uint32_t step, std::atomic<bool>& found)
{
    arith_uint256 target;
    bool neg, over;
    target.SetCompact(nBits, &neg, &over);
    if (target == 0 || neg || over) return;
    CBlockHeader header = header_orig; // working copy
    header.nNonce = offset;

    uint32_t finish = std::numeric_limits<uint32_t>::max() - step;
    finish = finish - (finish % step) + offset;

    while (!found && header.nNonce < finish) {
        const uint32_t next = (finish - header.nNonce < 5000*step) ? finish : header.nNonce + 5000*step;
        do {
            if (UintToArith256(header.GetHash()) <= target) {
                if (!found.exchange(true)) {
                    header_orig.nNonce = header.nNonce;
                }
                return;
            }
            header.nNonce += step;
        } while(header.nNonce != next);
    }
}

static int Grind(int argc, char* argv[], std::string& strPrint)
{
    if (argc != 1) {
        strPrint = "Must specify block header to grind";
        return 1;
    }

    CBlockHeader header;
    if (!DecodeHexBlockHeader(header, argv[0])) {
        strPrint = "Could not decode block header";
        return 1;
    }

    uint32_t nBits = header.nBits;
    std::atomic<bool> found{false};

    std::vector<std::thread> threads;
    int n_tasks = std::max(1u, std::thread::hardware_concurrency());
    for (int i = 0; i < n_tasks; ++i) {
        threads.emplace_back( grind_task, nBits, std::ref(header), i, n_tasks, std::ref(found) );
    }
    for (auto& t : threads) {
        t.join();
    }
    if (!found) {
        strPrint = "Could not satisfy difficulty target";
        return 1;
    }

    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
    ss << header;
    strPrint = HexStr(ss);
    return 0;
}

static int CommandLineUtil(int argc, char* argv[])
{
    if (argc <= 1) return 1;

    std::string strPrint;
    int nRet = 0;

    try {
        while (argc > 1 && IsSwitchChar(argv[1][0]) && (argv[1][1] != 0)) {
            --argc;
            ++argv;
        }

        char* command = argv[1];
        if (strcmp(command, "grind") == 0) {
            nRet = Grind(argc-2, argv+2, strPrint);
        } else {
            strPrint = strprintf("Unknown command %s", command);
            nRet = 1;
        }
    }
    catch (const std::exception& e) {
        strPrint = std::string("error: ") + e.what();
        nRet = EXIT_FAILURE;
    }
    catch (...) {
        PrintExceptionContinue(nullptr, "CommandLineUtil()");
        throw;
    }

    if (strPrint != "") {
        tfm::format(nRet == 0 ? std::cout : std::cerr, "%s\n", strPrint);
    }
    return nRet;
}

int main(int argc, char* argv[])
{
    SetupEnvironment();

    try {
        int ret = AppInitUtil(argc, argv);
        if (ret != CONTINUE_EXECUTION)
            return ret;
    }
    catch (const std::exception& e) {
        PrintExceptionContinue(&e, "AppInitUtil()");
        return EXIT_FAILURE;
    } catch (...) {
        PrintExceptionContinue(nullptr, "AppInitUtil()");
        return EXIT_FAILURE;
    }

    int ret = EXIT_FAILURE;
    try {
        ret = CommandLineUtil(argc, argv);
    }
    catch (const std::exception& e) {
        PrintExceptionContinue(&e, "CommandLineUtil()");
    } catch (...) {
        PrintExceptionContinue(nullptr, "CommandLineUtil()");
    }
    return ret;
}
<commit_msg>add std::atomic include to bitcoin-util.cpp<commit_after>// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <arith_uint256.h>
#include <clientversion.h>
#include <coins.h>
#include <consensus/consensus.h>
#include <core_io.h>
#include <key_io.h>
#include <policy/rbf.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <univalue.h>
#include <util/moneystr.h>
#include <util/rbf.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>

#include <atomic>
#include <functional>
#include <memory>
#include <stdio.h>
#include <thread>

#include <boost/algorithm/string.hpp>

static const int CONTINUE_EXECUTION=-1;

const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;

static void SetupBitcoinUtilArgs(ArgsManager &argsman)
{
    SetupHelpOptions(argsman);

    argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);

    SetupChainParamsBaseOptions(argsman);
}

// This function returns either one of EXIT_ codes when it's expected to stop the process or
// CONTINUE_EXECUTION when it's expected to continue further.
static int AppInitUtil(int argc, char* argv[])
{
    SetupBitcoinUtilArgs(gArgs);
    std::string error;
    if (!gArgs.ParseParameters(argc, argv, error)) {
        tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error);
        return EXIT_FAILURE;
    }

    // Check for chain settings (Params() calls are only valid after this clause)
    try {
        SelectParams(gArgs.GetChainName());
    } catch (const std::exception& e) {
        tfm::format(std::cerr, "Error: %s\n", e.what());
        return EXIT_FAILURE;
    }

    if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
        // First part of help message is specific to this utility
        std::string strUsage = PACKAGE_NAME " bitcoin-util utility version " + FormatFullVersion() + "\n";
        if (!gArgs.IsArgSet("-version")) {
            strUsage += "\n"
                "Usage:  bitcoin-util [options] [commands]  Do stuff\n";
            strUsage += "\n" + gArgs.GetHelpMessage();
        }

        tfm::format(std::cout, "%s", strUsage);

        if (argc < 2) {
            tfm::format(std::cerr, "Error: too few parameters\n");
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
    }
    return CONTINUE_EXECUTION;
}

static void grind_task(uint32_t nBits, CBlockHeader& header_orig, uint32_t offset, uint32_t step, std::atomic<bool>& found)
{
    arith_uint256 target;
    bool neg, over;
    target.SetCompact(nBits, &neg, &over);
    if (target == 0 || neg || over) return;
    CBlockHeader header = header_orig; // working copy
    header.nNonce = offset;

    uint32_t finish = std::numeric_limits<uint32_t>::max() - step;
    finish = finish - (finish % step) + offset;

    while (!found && header.nNonce < finish) {
        const uint32_t next = (finish - header.nNonce < 5000*step) ? finish : header.nNonce + 5000*step;
        do {
            if (UintToArith256(header.GetHash()) <= target) {
                if (!found.exchange(true)) {
                    header_orig.nNonce = header.nNonce;
                }
                return;
            }
            header.nNonce += step;
        } while(header.nNonce != next);
    }
}

static int Grind(int argc, char* argv[], std::string& strPrint)
{
    if (argc != 1) {
        strPrint = "Must specify block header to grind";
        return 1;
    }

    CBlockHeader header;
    if (!DecodeHexBlockHeader(header, argv[0])) {
        strPrint = "Could not decode block header";
        return 1;
    }

    uint32_t nBits = header.nBits;
    std::atomic<bool> found{false};

    std::vector<std::thread> threads;
    int n_tasks = std::max(1u, std::thread::hardware_concurrency());
    for (int i = 0; i < n_tasks; ++i) {
        threads.emplace_back( grind_task, nBits, std::ref(header), i, n_tasks, std::ref(found) );
    }
    for (auto& t : threads) {
        t.join();
    }
    if (!found) {
        strPrint = "Could not satisfy difficulty target";
        return 1;
    }

    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
    ss << header;
    strPrint = HexStr(ss);
    return 0;
}

static int CommandLineUtil(int argc, char* argv[])
{
    if (argc <= 1) return 1;

    std::string strPrint;
    int nRet = 0;

    try {
        while (argc > 1 && IsSwitchChar(argv[1][0]) && (argv[1][1] != 0)) {
            --argc;
            ++argv;
        }

        char* command = argv[1];
        if (strcmp(command, "grind") == 0) {
            nRet = Grind(argc-2, argv+2, strPrint);
        } else {
            strPrint = strprintf("Unknown command %s", command);
            nRet = 1;
        }
    }
    catch (const std::exception& e) {
        strPrint = std::string("error: ") + e.what();
        nRet = EXIT_FAILURE;
    }
    catch (...) {
        PrintExceptionContinue(nullptr, "CommandLineUtil()");
        throw;
    }

    if (strPrint != "") {
        tfm::format(nRet == 0 ? std::cout : std::cerr, "%s\n", strPrint);
    }
    return nRet;
}

int main(int argc, char* argv[])
{
    SetupEnvironment();

    try {
        int ret = AppInitUtil(argc, argv);
        if (ret != CONTINUE_EXECUTION)
            return ret;
    }
    catch (const std::exception& e) {
        PrintExceptionContinue(&e, "AppInitUtil()");
        return EXIT_FAILURE;
    } catch (...) {
        PrintExceptionContinue(nullptr, "AppInitUtil()");
        return EXIT_FAILURE;
    }

    int ret = EXIT_FAILURE;
    try {
        ret = CommandLineUtil(argc, argv);
    }
    catch (const std::exception& e) {
        PrintExceptionContinue(&e, "CommandLineUtil()");
    } catch (...) {
        PrintExceptionContinue(nullptr, "CommandLineUtil()");
    }
    return ret;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 National ICT Australia Limited (NICTA)
 *
 * 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 "bonmin_model.hpp"
#include "bonmin_minlp.hpp"

#include "common.hpp"

using namespace MadOpt;

namespace MadOpt {

struct BonminModelImpl {
    BonminModelImpl(BonminModel* model){
        Bapp = new Bonmin::BonminSetup();
        Bapp->initializeOptionsAndJournalist();
        bonmin_callback = new BonminUserClass(model);
    }

    ~BonminModelImpl(){
        delete Bapp;
    }

    Bonmin::BonminSetup* Bapp;
    Ipopt::SmartPtr<Bonmin::TMINLP> bonmin_callback;
};
}

BonminModel::BonminModel(): Model(){
    impl = new BonminModelImpl(this);
}

BonminModel::~BonminModel(){
    delete impl;
}

void BonminModel::solve(){
    if (timelimit >= 0)
        setNumericOption("bonmin.time_limit", timelimit);

    if (not show_solver){
        setIntegerOption("print_level", 0);
        setIntegerOption("bonmin.bb_log_level", 0);
        setIntegerOption("bonmin.nlp_log_level", 0);
        setStringOption("sb", "yes");
    }

    try {
      impl->Bapp->initialize(GetRawPtr(impl->bonmin_callback));
      Bonmin::Bab bb;
      bb(impl->Bapp);

    }
    catch(Bonmin::TNLPSolver::UnsolvedError &E) {
      solution.setStatus(Solution::SolverStatus::UNSOLVED_ERROR);
    }

    // impl->Bapp->initialize(GetRawPtr(impl->bonmin_callback));
    // Bonmin::Bab bb;
    // bb(impl->Bapp);

    model_changed = false;
}

void BonminModel::setStringOption(std::string key, std::string value){
    impl->Bapp->options()->SetStringValue(key, value);
}

void BonminModel::setNumericOption(std::string key, double value){
    impl->Bapp->options()->SetNumericValue(key, value);
}

void BonminModel::setIntegerOption(std::string key, int value){
    impl->Bapp->options()->SetIntegerValue(key, value);
}
<commit_msg>Solved #12<commit_after>/*
 * Copyright 2014 National ICT Australia Limited (NICTA)
 *
 * 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 "bonmin_model.hpp"
#include "bonmin_minlp.hpp"

#include "common.hpp"

using namespace MadOpt;

namespace MadOpt {

struct BonminModelImpl {
    BonminModelImpl(BonminModel* model){
        Bapp = new Bonmin::BonminSetup();
        Bapp->initializeOptionsAndJournalist();
        bonmin_callback = new BonminUserClass(model);
    }

    ~BonminModelImpl(){
        delete Bapp;
    }

    Bonmin::BonminSetup* Bapp;
    Ipopt::SmartPtr<Bonmin::TMINLP> bonmin_callback;
};
}

BonminModel::BonminModel(): Model(){
    impl = new BonminModelImpl(this);
}

BonminModel::~BonminModel(){
    delete impl;
}

void BonminModel::solve(){
    if (timelimit >= 0)
        setNumericOption("bonmin.time_limit", timelimit);

    if (not show_solver){
        setIntegerOption("print_level", 0);
        setIntegerOption("bonmin.bb_log_level", 0);
        setIntegerOption("bonmin.nlp_log_level", 0);
        setStringOption("sb", "yes");
    }

    try {
        impl->Bapp->initialize(GetRawPtr(impl->bonmin_callback));
        Bonmin::Bab bb;
        bb(impl->Bapp);
    }
    catch(Bonmin::TNLPSolver::UnsolvedError *E) {
        solution.setStatus(Solution::SolverStatus::UNSOLVED_ERROR);
        delete E;
    }
    catch(Bonmin::TNLPSolver::UnsolvedError &E) {
        solution.setStatus(Solution::SolverStatus::UNSOLVED_ERROR);
    }
    // Other possible exceptions we may want to catch here:
    // OsiTMINLPInterface::SimpleError &E
    // CoinError &E

    model_changed = false;
}

void BonminModel::setStringOption(std::string key, std::string value){
    impl->Bapp->options()->SetStringValue(key, value);
}

void BonminModel::setNumericOption(std::string key, double value){
    impl->Bapp->options()->SetNumericValue(key, value);
}

void BonminModel::setIntegerOption(std::string key, int value){
    impl->Bapp->options()->SetIntegerValue(key, value);
}
<|endoftext|>


<commit_before>/******
ootree: An easy to use and highly configurable C++ template tree class,
using STL container style interfaces.

Copyright (c) 2010 Erik Erlandson

Author:  Erik Erlandson <erikerlandson@yahoo.com>

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 <iostream>
using namespace std;

// use the mtree header and namespace
#include "ootree.h"
using namespace ootree;

int main(int argc, char** argv) {
    return 0;
}
<commit_msg>Added 1st example -- hello world<commit_after>/******
ootree: An easy to use and highly configurable C++ template tree class,
using STL container style interfaces.

Copyright (c) 2010 Erik Erlandson

Author:  Erik Erlandson <erikerlandson@yahoo.com>

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 <iostream>
using namespace std;

// use the mtree header and namespace
#include "ootree.h"
using namespace ootree;

int main(int argc, char** argv) {
    // declare a tree of strings
    tree<const char*> t;
    typedef tree<const char*>::bf_iterator bf_iterator;

    // insert a string at root (ply 0)
    t.insert("Hello");

    // insert strings at ply 1
    t.root().insert(" ");
    t.root().insert("world");

    // insert strings at ply 2
    t.root()[0].insert("!");
    t.root()[1].insert("\n");

    // output data in breadth first order to print a traditional message
    for (bf_iterator j(t.bf_begin());  j != t.bf_end();  ++j)
        cout << j->data();

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Alexandru Dutu
 */

/**
 * @file
 * Definitions of page table
 */
#include <fstream>
#include <map>
#include <string>

#include "base/bitfield.hh"
#include "base/intmath.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "debug/MMU.hh"
#include "mem/multi_level_page_table.hh"
#include "sim/faults.hh"
#include "sim/sim_object.hh"

using namespace std;
using namespace TheISA;

template <class ISAOps>
MultiLevelPageTable<ISAOps>::MultiLevelPageTable(const std::string &__name,
                                                 uint64_t _pid, System *_sys)
    : PageTableBase(__name, _pid), system(_sys),
    logLevelSize(PageTableLayout),
    numLevels(logLevelSize.size())
{
}

template <class ISAOps>
MultiLevelPageTable<ISAOps>::~MultiLevelPageTable()
{
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::initState(ThreadContext* tc)
{
    basePtr = pTableISAOps.getBasePtr(tc);
    if (basePtr == 0) basePtr++;
    DPRINTF(MMU, "basePtr: %d\n", basePtr);

    system->pagePtr = basePtr;

    /* setting first level of the page table */
    uint64_t log_req_size = floorLog2(sizeof(PageTableEntry)) +
                            logLevelSize[numLevels-1];
    assert(log_req_size >= PageShift);
    uint64_t npages = 1 << (log_req_size - PageShift);

    Addr paddr = system->allocPhysPages(npages);

    PortProxy &p = system->physProxy;
    p.memsetBlob(paddr, 0, npages << PageShift);
}

template <class ISAOps>
bool
MultiLevelPageTable<ISAOps>::walk(Addr vaddr, bool allocate, Addr &PTE_addr)
{
    std::vector<uint64_t> offsets = pTableISAOps.getOffsets(vaddr);

    Addr level_base = basePtr;
    for (int i = numLevels - 1; i > 0; i--) {

        Addr entry_addr = (level_base<<PageShift) +
                          offsets[i] * sizeof(PageTableEntry);

        PortProxy &p = system->physProxy;
        PageTableEntry entry = p.read<PageTableEntry>(entry_addr);

        Addr next_entry_pnum = pTableISAOps.getPnum(entry);
        if (next_entry_pnum == 0) {

            if (!allocate) return false;

            uint64_t log_req_size = floorLog2(sizeof(PageTableEntry)) +
                                    logLevelSize[i-1];
            assert(log_req_size >= PageShift);
            uint64_t npages = 1 << (log_req_size - PageShift);

            DPRINTF(MMU, "Allocating %d pages needed for entry in level %d\n",
                    npages, i - 1);

            /* allocate new entry */
            Addr next_entry_paddr = system->allocPhysPages(npages);
            p.memsetBlob(next_entry_paddr, 0, npages << PageShift);

            next_entry_pnum = next_entry_paddr >> PageShift;
            pTableISAOps.setPnum(entry, next_entry_pnum);
            pTableISAOps.setPTEFields(entry);
            p.write<PageTableEntry>(entry_addr, entry);

        }
        DPRINTF(MMU, "Level %d base: %d offset: %d entry: %d\n",
                i, level_base, offsets[i], next_entry_pnum);
        level_base = next_entry_pnum;

    }
    PTE_addr = (level_base<<PageShift) +
        offsets[0] * sizeof(PageTableEntry);
    DPRINTF(MMU, "Returning PTE_addr: %x\n", PTE_addr);
    return true;
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::map(Addr vaddr, Addr paddr,
                                 int64_t size, bool clobber)
{
    // starting address must be page aligned
    assert(pageOffset(vaddr) == 0);

    DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr + size);

    PortProxy &p = system->physProxy;

    for (; size > 0; size -= pageSize, vaddr += pageSize, paddr += pageSize) {
        Addr PTE_addr;
        if (walk(vaddr, true, PTE_addr)) {
            PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
            Addr entry_paddr = pTableISAOps.getPnum(PTE);
            if (!clobber && entry_paddr == 0) {
                pTableISAOps.setPnum(PTE, paddr >> PageShift);
                pTableISAOps.setPTEFields(PTE);
                p.write<PageTableEntry>(PTE_addr, PTE);
                DPRINTF(MMU, "New mapping: %#x-%#x\n", vaddr, paddr);
            } else {
                fatal("addr 0x%x already mapped to %x", vaddr, entry_paddr);
            }

            eraseCacheEntry(vaddr);
            updateCache(vaddr, TlbEntry(pid, vaddr, paddr));
        }

    }
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::remap(Addr vaddr, int64_t size, Addr new_vaddr)
{
    assert(pageOffset(vaddr) == 0);
    assert(pageOffset(new_vaddr) == 0);

    DPRINTF(MMU, "moving pages from vaddr %08p to %08p, size = %d\n", vaddr,
            new_vaddr, size);

    PortProxy &p = system->physProxy;

    for (; size > 0;
         size -= pageSize, vaddr += pageSize, new_vaddr += pageSize)
    {
        Addr PTE_addr;
        if (walk(vaddr, false, PTE_addr)) {
            PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
            Addr paddr = pTableISAOps.getPnum(PTE);

            if (paddr == 0) {
                fatal("Page fault while remapping");
            } else {
                /* unmapping vaddr */
                pTableISAOps.setPnum(PTE, 0);
                p.write<PageTableEntry>(PTE_addr, PTE);

                /* maping new_vaddr */
                Addr new_PTE_addr;
                walk(new_vaddr, true, new_PTE_addr);
                PageTableEntry new_PTE = p.read<PageTableEntry>(new_PTE_addr);

                pTableISAOps.setPnum(new_PTE, paddr>>PageShift);
                pTableISAOps.setPTEFields(new_PTE);
                p.write<PageTableEntry>(new_PTE_addr, new_PTE);
                DPRINTF(MMU, "Remapping: %#x-%#x\n", vaddr, new_PTE_addr);
            }

            eraseCacheEntry(vaddr);
            updateCache(new_vaddr, TlbEntry(pid, new_vaddr, paddr));
        } else {
            fatal("Page fault while remapping");
        }
    }
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::unmap(Addr vaddr, int64_t size)
{
    assert(pageOffset(vaddr) == 0);

    DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr+ size);

    PortProxy &p = system->physProxy;

    for (; size > 0; size -= pageSize, vaddr += pageSize) {
        Addr PTE_addr;
        if (walk(vaddr, false, PTE_addr)) {
            PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
            Addr paddr = pTableISAOps.getPnum(PTE);
            if (paddr == 0) {
                fatal("PageTable::allocate: address 0x%x not mapped", vaddr);
            } else {
                pTableISAOps.setPnum(PTE, 0);
                p.write<PageTableEntry>(PTE_addr, PTE);
                DPRINTF(MMU, "Unmapping: %#x\n", vaddr);
            }
           eraseCacheEntry(vaddr);
        } else {
            fatal("Page fault while unmapping");
        }
    }

}

template <class ISAOps>
bool
MultiLevelPageTable<ISAOps>::isUnmapped(Addr vaddr, int64_t size)
{
    // starting address must be page aligned
    assert(pageOffset(vaddr) == 0);
    PortProxy &p = system->physProxy;

    for (; size > 0; size -= pageSize, vaddr += pageSize) {
        Addr PTE_addr;
        if (walk(vaddr, false, PTE_addr)) {
            PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
            if (pTableISAOps.getPnum(PTE) != 0)
                return false;
        }
    }

    return true;
}

template <class ISAOps>
bool
MultiLevelPageTable<ISAOps>::lookup(Addr vaddr, TlbEntry &entry)
{
    Addr page_addr = pageAlign(vaddr);

    if (pTableCache[0].valid && pTableCache[0].vaddr == page_addr) {
        entry = pTableCache[0].entry;
        return true;
    }
    if (pTableCache[1].valid && pTableCache[1].vaddr == page_addr) {
        entry = pTableCache[1].entry;
        return true;
    }
    if (pTableCache[2].valid && pTableCache[2].vaddr == page_addr) {
        entry = pTableCache[2].entry;
        return true;
    }

    DPRINTF(MMU, "lookup page_addr: %#x\n", page_addr);
    Addr PTE_addr;
    if (walk(page_addr, false, PTE_addr)) {
        PortProxy &p = system->physProxy;
        PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
        Addr pnum = pTableISAOps.getPnum(PTE);
        if (pnum == 0)
            return false;

        entry = TlbEntry(pid, vaddr, pnum << PageShift);
        updateCache(page_addr, entry);
    } else {
        return false;
    }
    return true;
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::serialize(std::ostream &os)
{
    /** Since, the page table is stored in system memory
     * which is serialized separately, we will serialize
     * just the base pointer
     */
    paramOut(os, "ptable.pointer", basePtr);
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::unserialize(Checkpoint *cp,
                                         const std::string &section)
{
    paramIn(cp, section, "ptable.pointer", basePtr);
}
<commit_msg>mem: Multi Level Page Table bug fix<commit_after>/*
 * Copyright (c) 2014 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Alexandru Dutu
 */

/**
 * @file
 * Definitions of page table
 */
#include <fstream>
#include <map>
#include <string>

#include "base/bitfield.hh"
#include "base/intmath.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "debug/MMU.hh"
#include "mem/multi_level_page_table.hh"
#include "sim/faults.hh"
#include "sim/sim_object.hh"

using namespace std;
using namespace TheISA;

template <class ISAOps>
MultiLevelPageTable<ISAOps>::MultiLevelPageTable(const std::string &__name,
                                                 uint64_t _pid, System *_sys)
    : PageTableBase(__name, _pid), system(_sys),
    logLevelSize(PageTableLayout),
    numLevels(logLevelSize.size())
{
}

template <class ISAOps>
MultiLevelPageTable<ISAOps>::~MultiLevelPageTable()
{
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::initState(ThreadContext* tc)
{
    basePtr = pTableISAOps.getBasePtr(tc);
    if (basePtr == 0) basePtr++;
    DPRINTF(MMU, "basePtr: %d\n", basePtr);

    system->pagePtr = basePtr;

    /* setting first level of the page table */
    uint64_t log_req_size = floorLog2(sizeof(PageTableEntry)) +
                            logLevelSize[numLevels-1];
    assert(log_req_size >= PageShift);
    uint64_t npages = 1 << (log_req_size - PageShift);

    Addr paddr = system->allocPhysPages(npages);

    PortProxy &p = system->physProxy;
    p.memsetBlob(paddr, 0, npages << PageShift);
}

template <class ISAOps>
bool
MultiLevelPageTable<ISAOps>::walk(Addr vaddr, bool allocate, Addr &PTE_addr)
{
    std::vector<uint64_t> offsets = pTableISAOps.getOffsets(vaddr);

    Addr level_base = basePtr;
    for (int i = numLevels - 1; i > 0; i--) {

        Addr entry_addr = (level_base<<PageShift) +
                          offsets[i] * sizeof(PageTableEntry);

        PortProxy &p = system->physProxy;
        PageTableEntry entry = p.read<PageTableEntry>(entry_addr);

        Addr next_entry_pnum = pTableISAOps.getPnum(entry);
        if (next_entry_pnum == 0) {

            if (!allocate) return false;

            uint64_t log_req_size = floorLog2(sizeof(PageTableEntry)) +
                                    logLevelSize[i-1];
            assert(log_req_size >= PageShift);
            uint64_t npages = 1 << (log_req_size - PageShift);

            DPRINTF(MMU, "Allocating %d pages needed for entry in level %d\n",
                    npages, i - 1);

            /* allocate new entry */
            Addr next_entry_paddr = system->allocPhysPages(npages);
            p.memsetBlob(next_entry_paddr, 0, npages << PageShift);

            next_entry_pnum = next_entry_paddr >> PageShift;
            pTableISAOps.setPnum(entry, next_entry_pnum);
            pTableISAOps.setPTEFields(entry);
            p.write<PageTableEntry>(entry_addr, entry);

        }
        DPRINTF(MMU, "Level %d base: %d offset: %d entry: %d\n",
                i, level_base, offsets[i], next_entry_pnum);
        level_base = next_entry_pnum;

    }
    PTE_addr = (level_base<<PageShift) +
        offsets[0] * sizeof(PageTableEntry);
    DPRINTF(MMU, "Returning PTE_addr: %x\n", PTE_addr);
    return true;
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::map(Addr vaddr, Addr paddr,
                                 int64_t size, bool clobber)
{
    // starting address must be page aligned
    assert(pageOffset(vaddr) == 0);

    DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr + size);

    PortProxy &p = system->physProxy;

    for (; size > 0; size -= pageSize, vaddr += pageSize, paddr += pageSize) {
        Addr PTE_addr;
        if (walk(vaddr, true, PTE_addr)) {
            PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
            Addr entry_paddr = pTableISAOps.getPnum(PTE);
            if (!clobber && entry_paddr != 0) {
                fatal("addr 0x%x already mapped to %x", vaddr, entry_paddr);
            }
            pTableISAOps.setPnum(PTE, paddr >> PageShift);
            pTableISAOps.setPTEFields(PTE);
            p.write<PageTableEntry>(PTE_addr, PTE);
            DPRINTF(MMU, "New mapping: %#x-%#x\n", vaddr, paddr);

            eraseCacheEntry(vaddr);
            updateCache(vaddr, TlbEntry(pid, vaddr, paddr));
        }

    }
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::remap(Addr vaddr, int64_t size, Addr new_vaddr)
{
    assert(pageOffset(vaddr) == 0);
    assert(pageOffset(new_vaddr) == 0);

    DPRINTF(MMU, "moving pages from vaddr %08p to %08p, size = %d\n", vaddr,
            new_vaddr, size);

    PortProxy &p = system->physProxy;

    for (; size > 0;
         size -= pageSize, vaddr += pageSize, new_vaddr += pageSize)
    {
        Addr PTE_addr;
        if (walk(vaddr, false, PTE_addr)) {
            PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
            Addr paddr = pTableISAOps.getPnum(PTE);

            if (paddr == 0) {
                fatal("Page fault while remapping");
            } else {
                /* unmapping vaddr */
                pTableISAOps.setPnum(PTE, 0);
                p.write<PageTableEntry>(PTE_addr, PTE);

                /* maping new_vaddr */
                Addr new_PTE_addr;
                walk(new_vaddr, true, new_PTE_addr);
                PageTableEntry new_PTE = p.read<PageTableEntry>(new_PTE_addr);

                pTableISAOps.setPnum(new_PTE, paddr>>PageShift);
                pTableISAOps.setPTEFields(new_PTE);
                p.write<PageTableEntry>(new_PTE_addr, new_PTE);
                DPRINTF(MMU, "Remapping: %#x-%#x\n", vaddr, new_PTE_addr);
            }

            eraseCacheEntry(vaddr);
            updateCache(new_vaddr, TlbEntry(pid, new_vaddr, paddr));
        } else {
            fatal("Page fault while remapping");
        }
    }
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::unmap(Addr vaddr, int64_t size)
{
    assert(pageOffset(vaddr) == 0);

    DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr+ size);

    PortProxy &p = system->physProxy;

    for (; size > 0; size -= pageSize, vaddr += pageSize) {
        Addr PTE_addr;
        if (walk(vaddr, false, PTE_addr)) {
            PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
            Addr paddr = pTableISAOps.getPnum(PTE);
            if (paddr == 0) {
                fatal("PageTable::allocate: address 0x%x not mapped", vaddr);
            } else {
                pTableISAOps.setPnum(PTE, 0);
                p.write<PageTableEntry>(PTE_addr, PTE);
                DPRINTF(MMU, "Unmapping: %#x\n", vaddr);
            }
           eraseCacheEntry(vaddr);
        } else {
            fatal("Page fault while unmapping");
        }
    }

}

template <class ISAOps>
bool
MultiLevelPageTable<ISAOps>::isUnmapped(Addr vaddr, int64_t size)
{
    // starting address must be page aligned
    assert(pageOffset(vaddr) == 0);
    PortProxy &p = system->physProxy;

    for (; size > 0; size -= pageSize, vaddr += pageSize) {
        Addr PTE_addr;
        if (walk(vaddr, false, PTE_addr)) {
            PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
            if (pTableISAOps.getPnum(PTE) != 0)
                return false;
        }
    }

    return true;
}

template <class ISAOps>
bool
MultiLevelPageTable<ISAOps>::lookup(Addr vaddr, TlbEntry &entry)
{
    Addr page_addr = pageAlign(vaddr);

    if (pTableCache[0].valid && pTableCache[0].vaddr == page_addr) {
        entry = pTableCache[0].entry;
        return true;
    }
    if (pTableCache[1].valid && pTableCache[1].vaddr == page_addr) {
        entry = pTableCache[1].entry;
        return true;
    }
    if (pTableCache[2].valid && pTableCache[2].vaddr == page_addr) {
        entry = pTableCache[2].entry;
        return true;
    }

    DPRINTF(MMU, "lookup page_addr: %#x\n", page_addr);
    Addr PTE_addr;
    if (walk(page_addr, false, PTE_addr)) {
        PortProxy &p = system->physProxy;
        PageTableEntry PTE = p.read<PageTableEntry>(PTE_addr);
        Addr pnum = pTableISAOps.getPnum(PTE);
        if (pnum == 0)
            return false;

        entry = TlbEntry(pid, vaddr, pnum << PageShift);
        updateCache(page_addr, entry);
    } else {
        return false;
    }
    return true;
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::serialize(std::ostream &os)
{
    /** Since, the page table is stored in system memory
     * which is serialized separately, we will serialize
     * just the base pointer
     */
    paramOut(os, "ptable.pointer", basePtr);
}

template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::unserialize(Checkpoint *cp,
                                         const std::string &section)
{
    paramIn(cp, section, "ptable.pointer", basePtr);
}
<|endoftext|>


<commit_before>// UiaDll.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "Locator.h"
#include "DynamicAssemblyResolver.h"
#include "StringHelper.h"

IUIAutomation* getGlobalIUIAutomation() ;

using namespace RAutomation::UIA;
using namespace RAutomation::UIA::Controls;
using namespace RAutomation::UIA::Extensions;

using namespace System::Diagnostics;

extern "C" {
	__declspec(dllexport) void initialize(char* privateAssemblyDirectory) {
		DynamicAssemblyResolver::PrivatePath = gcnew String(privateAssemblyDirectory);
	}

	__declspec ( dllexport ) bool ElementExists(const FindInformation& findInformation) {
    return Element::Exists(Locator::FindFor(findInformation));
	}

	__declspec ( dllexport ) int NativeWindowHandle(const FindInformation& findInformation) {
    return Element::NativeWindowHandle(Locator::FindFor(findInformation));
	}

	__declspec ( dllexport ) int HandleFromPoint(int xCoord, int yCoord) {
		auto element = AutomationElement::FromPoint(Point((double)xCoord, (double)yCoord));
		return Element::NativeWindowHandle(element);
	}

	__declspec ( dllexport ) int BoundingRectangle(const FindInformation& findInformation, long *rectangle) {
		try {
			auto boundary = Element::BoundingRectangle(Locator::FindFor(findInformation));

			rectangle[0] = (long)boundary.Left;
			rectangle[1] = (long)boundary.Top;
			rectangle[2] = (long)boundary.Right;
			rectangle[3] = (long)boundary.Bottom;
			return 1;
		}
		catch(Exception^ e) {
			Console::WriteLine("BoundingRectangle:  {0}", e->Message);
			return 0;
		}
	}

	__declspec ( dllexport ) int ControlType(const FindInformation& findInformation) {
		try {
      return Element::ControlType(Locator::FindFor(findInformation))->Id;
		} catch(Exception^ e) {
			Console::WriteLine("ControlType:  {0}", e->Message);
			return 0;
		}
	}

	__declspec ( dllexport ) int ProcessId(const FindInformation& findInformation) {
		try {
      return Element::ProcessId(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Console::WriteLine("ProcessId:  {0}", e->Message);
			return 0;
		}
	}

	__declspec ( dllexport ) void Name(const FindInformation& findInformation, char* name, const int nameLength) {
		try {
      auto currentName = Element::Name(Locator::FindFor(findInformation));
	  StringHelper::CopyToUnmanagedString(currentName, name, nameLength);
		} catch(Exception^ e) {
			Console::WriteLine("Name:  {0}", e->Message);
		}
	}

	__declspec ( dllexport ) void ClassName(const FindInformation& findInformation, char* className, const int classNameLength) {
		try {
      auto currentClassName = Element::ClassName(Locator::FindFor(findInformation));
			StringHelper::CopyToUnmanagedString(currentClassName, className, classNameLength);
		} catch(Exception^ e) {
			Console::WriteLine("ClassName:  {0}", e->Message);
		}
	}

	__declspec ( dllexport ) bool IsEnabled(const FindInformation& findInformation) {
		try {
			return Element::IsEnabled(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Console::WriteLine("IsEnabled:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) bool IsFocused(const FindInformation& findInformation) {
		try {
			return Element::IsFocused(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Console::WriteLine("IsFocused:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) bool SetControlFocus(const FindInformation& findInformation) {
		try {
			Locator::FindFor(findInformation)->SetFocus();
			return true;
		} catch(Exception^ e) {
			Console::WriteLine("IsFocused:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) int GetClassNames(const FindInformation& findInformation, const char* classNames[]) {
		auto allChildren = Locator::FindFor(findInformation)->FindAll(System::Windows::Automation::TreeScope::Subtree, Condition::TrueCondition);

		if( NULL != classNames ) {
			StringHelper::CopyClassNames(allChildren, classNames);
		}

		return allChildren->Count;
	}

	__declspec ( dllexport ) IUIAutomationElement *RA_ElementFromHandle(HWND hwnd) {
		IUIAutomationElement *pElement ;

		HRESULT hr = getGlobalIUIAutomation()->ElementFromHandle(hwnd, &pElement) ;
		if (SUCCEEDED(hr))
			return pElement ;
		else {
			printf("RA_ElementFromHandle: Cannot find element from handle 0x%x. HRESULT was 0x%x\r\n", hwnd, hr) ;
			return NULL ;
		}
	}

	__declspec ( dllexport ) int RA_CurrentIsOffscreen(IUIAutomationElement *pElement, int *visible) {
		BOOL offscreen;

		HRESULT hr = pElement->get_CurrentIsOffscreen(&offscreen) ;
		if (SUCCEEDED(hr)) {
			if(offscreen){
				*visible = 1;
			}
			else
			{
				*visible = 0;
			}
			return 1;
		}
		else {
			printf("RA_CurrentIsOffscreen: get_CurrentIsOffscreen failed 0x%x\r\n", hr) ;
			return 0 ;
		}
	}

	__declspec ( dllexport ) bool IsSet(const FindInformation& findInformation) {
		try {
			return Element::IsToggled(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Debug::WriteLine("IsSet:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) bool IsSelected(const FindInformation& findInformation) {
		try {
			return Element::IsSelected(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Debug::WriteLine("IsSelected:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) bool RA_Click(const FindInformation& findInformation, char* errorInfo, const int errorInfoSize) {
		try {
			return Clicker::Click(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			if( errorInfo ) {
				StringHelper::CopyToUnmanagedString(e->ToString(), errorInfo, errorInfoSize);
			}

      return false;
		}
	}

	__declspec ( dllexport ) void RA_ExpandItemByValue(const FindInformation& findInformation, const char* whichItem) {
		try {
			auto expander = gcnew Expander(Locator::FindFor(findInformation));
      expander->Expand(gcnew String(whichItem));
		} catch(Exception^ e) {
			Console::WriteLine(e->ToString());
		}
	}

	__declspec ( dllexport ) void RA_ExpandItemByIndex(const FindInformation& findInformation, const int whichItemIndex) {
		try {
			auto expander = gcnew Expander(Locator::FindFor(findInformation));
			expander->Expand(whichItemIndex);
		} catch(Exception^ e) {
			Console::WriteLine(e->ToString());
		}
	}

	__declspec ( dllexport ) void RA_CollapseItemByValue(const FindInformation& findInformation, const char* whichItem) {
		try {
			auto collapser = gcnew Collapser(Locator::FindFor(findInformation));
			collapser->Collapse(gcnew String(whichItem));
		} catch(Exception^ e) {
			Console::WriteLine(e->ToString());
		}
	}

	__declspec ( dllexport ) void RA_CollapseItemByIndex(const FindInformation& findInformation, const int whichItemIndex) {
		try {
			auto collapser = gcnew Collapser(Locator::FindFor(findInformation));
			collapser->Collapse(whichItemIndex);
		} catch(Exception^ e) {
			Console::WriteLine(e->ToString());
		}
	}
}
<commit_msg>Revert "get rid of RA_ClickMouse / RA_MoveMouse"<commit_after>// UiaDll.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "Locator.h"
#include "DynamicAssemblyResolver.h"
#include "StringHelper.h"

IUIAutomation* getGlobalIUIAutomation() ;

using namespace RAutomation::UIA;
using namespace RAutomation::UIA::Controls;
using namespace RAutomation::UIA::Extensions;

using namespace System::Diagnostics;

extern "C" {
	__declspec(dllexport) void initialize(char* privateAssemblyDirectory) {
		DynamicAssemblyResolver::PrivatePath = gcnew String(privateAssemblyDirectory);
	}

	__declspec ( dllexport ) bool ElementExists(const FindInformation& findInformation) {
    return Element::Exists(Locator::FindFor(findInformation));
	}

	__declspec ( dllexport ) int NativeWindowHandle(const FindInformation& findInformation) {
    return Element::NativeWindowHandle(Locator::FindFor(findInformation));
	}

	__declspec ( dllexport ) int HandleFromPoint(int xCoord, int yCoord) {
		auto element = AutomationElement::FromPoint(Point((double)xCoord, (double)yCoord));
		return Element::NativeWindowHandle(element);
	}

	__declspec ( dllexport ) int BoundingRectangle(const FindInformation& findInformation, long *rectangle) {
		try {
			auto boundary = Element::BoundingRectangle(Locator::FindFor(findInformation));

			rectangle[0] = (long)boundary.Left;
			rectangle[1] = (long)boundary.Top;
			rectangle[2] = (long)boundary.Right;
			rectangle[3] = (long)boundary.Bottom;
			return 1;
		}
		catch(Exception^ e) {
			Console::WriteLine("BoundingRectangle:  {0}", e->Message);
			return 0;
		}
	}

	__declspec ( dllexport ) int ControlType(const FindInformation& findInformation) {
		try {
      return Element::ControlType(Locator::FindFor(findInformation))->Id;
		} catch(Exception^ e) {
			Console::WriteLine("ControlType:  {0}", e->Message);
			return 0;
		}
	}

	__declspec ( dllexport ) int ProcessId(const FindInformation& findInformation) {
		try {
      return Element::ProcessId(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Console::WriteLine("ProcessId:  {0}", e->Message);
			return 0;
		}
	}

	__declspec ( dllexport ) void Name(const FindInformation& findInformation, char* name, const int nameLength) {
		try {
      auto currentName = Element::Name(Locator::FindFor(findInformation));
	  StringHelper::CopyToUnmanagedString(currentName, name, nameLength);
		} catch(Exception^ e) {
			Console::WriteLine("Name:  {0}", e->Message);
		}
	}

	__declspec ( dllexport ) void ClassName(const FindInformation& findInformation, char* className, const int classNameLength) {
		try {
      auto currentClassName = Element::ClassName(Locator::FindFor(findInformation));
			StringHelper::CopyToUnmanagedString(currentClassName, className, classNameLength);
		} catch(Exception^ e) {
			Console::WriteLine("ClassName:  {0}", e->Message);
		}
	}

	__declspec ( dllexport ) bool IsEnabled(const FindInformation& findInformation) {
		try {
			return Element::IsEnabled(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Console::WriteLine("IsEnabled:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) bool IsFocused(const FindInformation& findInformation) {
		try {
			return Element::IsFocused(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Console::WriteLine("IsFocused:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) bool SetControlFocus(const FindInformation& findInformation) {
		try {
			Locator::FindFor(findInformation)->SetFocus();
			return true;
		} catch(Exception^ e) {
			Console::WriteLine("IsFocused:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) int GetClassNames(const FindInformation& findInformation, const char* classNames[]) {
		auto allChildren = Locator::FindFor(findInformation)->FindAll(System::Windows::Automation::TreeScope::Subtree, Condition::TrueCondition);

		if( NULL != classNames ) {
			StringHelper::CopyClassNames(allChildren, classNames);
		}

		return allChildren->Count;
	}

	__declspec ( dllexport ) IUIAutomationElement *RA_ElementFromHandle(HWND hwnd) {
		IUIAutomationElement *pElement ;

		HRESULT hr = getGlobalIUIAutomation()->ElementFromHandle(hwnd, &pElement) ;
		if (SUCCEEDED(hr))
			return pElement ;
		else {
			printf("RA_ElementFromHandle: Cannot find element from handle 0x%x. HRESULT was 0x%x\r\n", hwnd, hr) ;
			return NULL ;
		}
	}

	__declspec ( dllexport ) long RA_ClickMouse() {
		mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
		mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
		return 0;
	}

	__declspec ( dllexport ) long RA_MoveMouse(int x, int y) {
		return SetCursorPos(x,y);
	}

	__declspec ( dllexport ) int RA_CurrentIsOffscreen(IUIAutomationElement *pElement, int *visible) {
		BOOL offscreen;

		HRESULT hr = pElement->get_CurrentIsOffscreen(&offscreen) ;
		if (SUCCEEDED(hr)) {
			if(offscreen){
				*visible = 1;
			}
			else
			{
				*visible = 0;
			}
			return 1;
		}
		else {
			printf("RA_CurrentIsOffscreen: get_CurrentIsOffscreen failed 0x%x\r\n", hr) ;
			return 0 ;
		}
	}

	__declspec ( dllexport ) bool IsSet(const FindInformation& findInformation) {
		try {
			return Element::IsToggled(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Debug::WriteLine("IsSet:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) bool IsSelected(const FindInformation& findInformation) {
		try {
			return Element::IsSelected(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			Debug::WriteLine("IsSelected:  {0}", e->Message);
			return false;
		}
	}

	__declspec ( dllexport ) bool RA_Click(const FindInformation& findInformation, char* errorInfo, const int errorInfoSize) {
		try {
			return Clicker::Click(Locator::FindFor(findInformation));
		} catch(Exception^ e) {
			if( errorInfo ) {
				StringHelper::CopyToUnmanagedString(e->ToString(), errorInfo, errorInfoSize);
			}

      return false;
		}
	}

	__declspec ( dllexport ) void RA_ExpandItemByValue(const FindInformation& findInformation, const char* whichItem) {
		try {
			auto expander = gcnew Expander(Locator::FindFor(findInformation));
      expander->Expand(gcnew String(whichItem));
		} catch(Exception^ e) {
			Console::WriteLine(e->ToString());
		}
	}

	__declspec ( dllexport ) void RA_ExpandItemByIndex(const FindInformation& findInformation, const int whichItemIndex) {
		try {
			auto expander = gcnew Expander(Locator::FindFor(findInformation));
			expander->Expand(whichItemIndex);
		} catch(Exception^ e) {
			Console::WriteLine(e->ToString());
		}
	}

	__declspec ( dllexport ) void RA_CollapseItemByValue(const FindInformation& findInformation, const char* whichItem) {
		try {
			auto collapser = gcnew Collapser(Locator::FindFor(findInformation));
			collapser->Collapse(gcnew String(whichItem));
		} catch(Exception^ e) {
			Console::WriteLine(e->ToString());
		}
	}

	__declspec ( dllexport ) void RA_CollapseItemByIndex(const FindInformation& findInformation, const int whichItemIndex) {
		try {
			auto collapser = gcnew Collapser(Locator::FindFor(findInformation));
			collapser->Collapse(whichItemIndex);
		} catch(Exception^ e) {
			Console::WriteLine(e->ToString());
		}
	}
}
<|endoftext|>


<commit_before>#include "calc.h"
#include <stdexcept>
#include <sstream>
#include <istream>
#include <limits>

int sign(const int i) {
	return (int(0) < i) - (i < int(0));
}

void throw_overflow_if(const bool condition) {
	if (condition) throw std::invalid_argument { "overflow" };
}

// Calculates the result of two numbers a and b and basic math operator.
int calc(const int a, const int b, const char operator_symbol) {
	using int_limits = std::numeric_limits<int>;
	const int int_max { int_limits::max() }, int_min { int_limits::min() };

	switch (operator_symbol) {
		case '*': {
			int result { a * b };
			throw_overflow_if((sign(a) * sign(b) != sign(result)) || (a != 0 && result / a != b));
			return result;
		}
		case '/':
			if (b == 0) throw std::domain_error{"division by zero"};
			return a / b;
		case '+':
			throw_overflow_if((a >= 0) && (int_max - a < b));
			throw_overflow_if((a <  0) && (b < int_min - a));
			return a + b;
		case '-': {
			throw_overflow_if((a >= 0) && (int_max - a < -b));
			throw_overflow_if((a  < 0) && (-b < int_min - a));
			return a - b;
		}
		case '%':
			if (b == 0) throw std::domain_error{"division by zero"};
			return a % b;
	}

	auto reason = std::string("invalid operator: ");
	reason.push_back(operator_symbol);
	throw std::invalid_argument{reason};
}

int calc(std::istream &input) {
	int a {0}, b {0};
	char operator_symbol { };
	input >> a >> operator_symbol >> b;
	if (input.fail())
			throw std::invalid_argument{ "malformed input term"};
	return calc(a, b, operator_symbol);
}
<commit_msg>recognize malformed input terms<commit_after>#include "calc.h"
#include <stdexcept>
#include <sstream>
#include <istream>
#include <limits>

int sign(const int i) {
	return (int(0) < i) - (i < int(0));
}

void throw_overflow_if(const bool condition) {
	if (condition) throw std::invalid_argument { "overflow" };
}

// Calculates the result of two numbers a and b and basic math operator.
int calc(const int a, const int b, const char operator_symbol) {
	using int_limits = std::numeric_limits<int>;
	const int int_max { int_limits::max() }, int_min { int_limits::min() };

	switch (operator_symbol) {
		case '*': {
			int result { a * b };
			throw_overflow_if((sign(a) * sign(b) != sign(result)) || (a != 0 && result / a != b));
			return result;
		}
		case '/':
			if (b == 0) throw std::domain_error{"division by zero"};
			return a / b;
		case '+':
			throw_overflow_if((a >= 0) && (int_max - a < b));
			throw_overflow_if((a <  0) && (b < int_min - a));
			return a + b;
		case '-': {
			throw_overflow_if((a >= 0) && (int_max - a < -b));
			throw_overflow_if((a  < 0) && (-b < int_min - a));
			return a - b;
		}
		case '%':
			if (b == 0) throw std::domain_error{"division by zero"};
			return a % b;
	}

	auto reason = std::string("invalid operator: ");
	reason.push_back(operator_symbol);
	throw std::invalid_argument{reason};
}

int calc(std::istream &input) {
	int a {0}, b {0};
	char operator_symbol { };
	std::string term {};
	std::getline(input, term);
	std::istringstream term_input { term };
	term_input >> a >> operator_symbol >> b;
	if (term_input.fail() || !term_input.eof())
			throw std::invalid_argument{ "malformed input term"};
	return calc(a, b, operator_symbol);
}
<|endoftext|>