<commit_before>#include "stdafx.h"

#include "../Application.h"
#include "../ModuleScripting.h"
#include "../ComponentScript.h"
#include "../ComponentTransform.h"
#include "../ComponentCollider.h"
#include "../ModuleGOManager.h"
#include "../ComponentCar.h"
#include "../GameObject.h"
#include "../PhysBody3D.h"

namespace CarPositionController
{
	//Public
	GameObject* car1 = nullptr;
	GameObject* car2 = nullptr;

	ComponentCar* c1 = nullptr;
	ComponentCar* c2 = nullptr;

	void CarPositionController_GetPublics(map<const char*, string>* public_chars, map<const char*, int>* public_ints, map<const char*, float>* public_float, map<const char*, bool>* public_bools, map<const char*, GameObject*>* public_gos)
	{
		public_gos->insert(pair<const char*, GameObject*>("car1", car1));
		public_gos->insert(pair<const char*, GameObject*>("car2", car2));
	}

	void CarPositionController_UpdatePublics(GameObject* game_object)
	{
		ComponentScript* CarPositionController_script = (ComponentScript*)game_object->GetComponent(ComponentType::C_SCRIPT);
		car1 = CarPositionController_script->public_gos.at("car1");
		car2 = CarPositionController_script->public_gos.at("car2");
	}

	void CarPositionController_ActualizePublics(GameObject* game_object)
	{
		ComponentScript* CarPositionController_script = (ComponentScript*)game_object->GetComponent(ComponentType::C_SCRIPT);
		CarPositionController_script->public_gos.at("car1") = car1;
		CarPositionController_script->public_gos.at("car2") = car2;
	}

	void CarPositionController_Start(GameObject* game_object)
	{
		if (car1 && car2)
		{
			c1 = (ComponentCar*)car1->GetComponent(C_CAR);
			c2 = (ComponentCar*)car2->GetComponent(C_CAR);
		}
	}

	void CarPositionController_Update(GameObject* game_object)
	{
		if (c1 && c2)
		{
			if (c1->n_checkpoints > c2->n_checkpoints)
			{
				c1->place = 1;
				c2->place = 2;
			}
			else if (c2->n_checkpoints > c1->n_checkpoints)
			{
				c2->place = 1;
				c1->place = 2;
			}
			else if(c1->n_checkpoints > 0 && c2->n_checkpoints > 0)
			{
				ComponentTransform* trs1 = (ComponentTransform*)car1->GetComponent(C_TRANSFORM);
				ComponentTransform* trs2 = (ComponentTransform*)car2->GetComponent(C_TRANSFORM);
				if (c1->last_check_pos.DistanceSq(trs1->GetPosition()) > c2->last_check_pos.DistanceSq(trs2->GetPosition()))
				{
					c1->place = 1;
					c2->place = 2;
				}
				else
				{
					c2->place = 1;
					c1->place = 2;
				}
			}
		}
	}

	void CarPositionController_OnCollision(GameObject* game_object, PhysBody3D* col)
	{
	}
}<commit_msg>BugFix<commit_after>#include "stdafx.h"

#include "../Application.h"
#include "../ModuleScripting.h"
#include "../ComponentScript.h"
#include "../ComponentTransform.h"
#include "../ComponentCollider.h"
#include "../ModuleGOManager.h"
#include "../ComponentCar.h"
#include "../GameObject.h"
#include "../PhysBody3D.h"

namespace CarPositionController
{
	//Public
	GameObject* car1 = nullptr;
	GameObject* car2 = nullptr;

	ComponentCar* c1 = nullptr;
	ComponentCar* c2 = nullptr;

	void CarPositionController_GetPublics(map<const char*, string>* public_chars, map<const char*, int>* public_ints, map<const char*, float>* public_float, map<const char*, bool>* public_bools, map<const char*, GameObject*>* public_gos)
	{
		public_gos->insert(pair<const char*, GameObject*>("car1", car1));
		public_gos->insert(pair<const char*, GameObject*>("car2", car2));
	}

	void CarPositionController_UpdatePublics(GameObject* game_object)
	{
		ComponentScript* CarPositionController_script = (ComponentScript*)game_object->GetComponent(ComponentType::C_SCRIPT);
		car1 = CarPositionController_script->public_gos.at("car1");
		car2 = CarPositionController_script->public_gos.at("car2");
	}

	void CarPositionController_ActualizePublics(GameObject* game_object)
	{
		ComponentScript* CarPositionController_script = (ComponentScript*)game_object->GetComponent(ComponentType::C_SCRIPT);
		CarPositionController_script->public_gos.at("car1") = car1;
		CarPositionController_script->public_gos.at("car2") = car2;
	}

	void CarPositionController_Start(GameObject* game_object)
	{
		if (car1 && car2)
		{
			c1 = (ComponentCar*)car1->GetComponent(C_CAR);
			c2 = (ComponentCar*)car2->GetComponent(C_CAR);
		}
	}

	void CarPositionController_Update(GameObject* game_object)
	{
		if (c1 && c2)
		{
			if (c1->lap == c2->lap)
			{
				if (c1->n_checkpoints > c2->n_checkpoints)
				{
					c1->place = 1;
					c2->place = 2;
				}
				else if (c2->n_checkpoints > c1->n_checkpoints)
				{
					c2->place = 1;
					c1->place = 2;
				}
				else if (c1->n_checkpoints > 0 && c2->n_checkpoints > 0)
				{
					ComponentTransform* trs1 = (ComponentTransform*)car1->GetComponent(C_TRANSFORM);
					ComponentTransform* trs2 = (ComponentTransform*)car2->GetComponent(C_TRANSFORM);
					if (c1->last_check_pos.DistanceSq(trs1->GetPosition()) > c2->last_check_pos.DistanceSq(trs2->GetPosition()))
					{
						c1->place = 1;
						c2->place = 2;
					}
					else
					{
						c2->place = 1;
						c1->place = 2;
					}
				}
			}
			else
			{
				if (c1->lap > c2->lap)
				{
					c1->place = 1;
					c2->place = 2;
				}
				else
				{
					c2->place = 1;
					c1->place = 2;
				}
			}
		}
	}

	void CarPositionController_OnCollision(GameObject* game_object, PhysBody3D* col)
	{
	}
}<|endoftext|>


<commit_before>#include "CppUnitTest.h"
#include <string>
#include <vector>
#include <array>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace std;

namespace algo
{
    template<class Traits>
    class tokens
    {
        typedef vector<typename Traits::type> token_vector;
        token_vector tokens_;

    public:
        typedef typename token_vector::iterator iterator;
        typedef typename token_vector::const_iterator const_iterator;
        typedef typename Traits::type token_type;

        tokens() {}
        explicit tokens(size_t count) : tokens_(count) {}
        tokens(std::initializer_list<token_type> init) : tokens_(init) {}
        bool empty() const { return tokens_.size() == 0; }
        size_t size() const { return tokens_.size(); }
        token_type& operator[](size_t i) { return tokens_[i]; };
        const token_type& operator[](size_t i) const { return const_cast<tokens&>(*this)[i]; };

        iterator begin() { return tokens_.begin(); }
        const_iterator begin() const { return tokens_.begin(); }
        const_iterator cbegin() const { return tokens_.cbegin(); }
        iterator end() { return tokens_.end(); }
        const_iterator end() const { return tokens_.end(); }
        const_iterator cend() const { return tokens_.cend(); }

        void from_string(string s)
        {
            auto newTokens = Traits::tokenize(s);
            tokens_.insert(tokens_.end(), newTokens.begin(), newTokens.end());
        }
    };
}

namespace algo { namespace spec
{
    struct s { string val; };

    template<size_t N>
    struct test_token_traits
    {
        typedef s type;
        static array<s, N> tokenize(const string&) { return array<s, N>(); }
    };

    template<size_t N>
    using test_tokens = tokens<test_token_traits<N>>;

    TEST_CLASS(can_recognize_tokens)
	{
	public:

        TEST_METHOD(should_not_have_any_tokens_when_default_constructed)
		{
            test_tokens<0> testTokens;
            Assert::IsTrue(testTokens.empty());
		}

        TEST_METHOD(should_recognize_a_token_in_a_string)
        {
            test_tokens<1> testTokens;
            testTokens.from_string("irrelevant");
            Assert::AreEqual(1U, testTokens.size());
        }

        TEST_METHOD(should_recognize_more_than_one_token_in_a_string)
        {
            test_tokens<3> testTokens;
            testTokens.from_string("irrelevant");
            Assert::AreEqual(3U, testTokens.size());
        }

        TEST_METHOD(should_accumulate_tokens_from_successive_strings)
        {
            test_tokens<2> testTokens(3);
            testTokens.from_string("irrelevant");
            Assert::AreEqual(5U, testTokens.size());
        }

        TEST_METHOD(should_be_able_to_enumerate_tokens)
        {
            test_tokens<0> testTokens(3);
            size_t i = 0;
            for (s tok : testTokens) { ++i; }
            Assert::AreEqual(3U, i);
        }

        TEST_METHOD(should_be_able_to_enumerate_const_tokens_from_a_const_container)
        {
            const test_tokens<0> testTokens(3);
            size_t i = 0;
            for (const s tok : testTokens) { ++i; }
            Assert::AreEqual(3U, i);
        }

        TEST_METHOD(should_be_able_to_enumerate_const_tokens_from_a_non_const_container)
        {
            typedef test_tokens<0>::const_iterator const_iter;
            test_tokens<0> testTokens(3);
            size_t i = 0;
            for (const_iter it = testTokens.cbegin(); it != testTokens.cend(); ++it) { ++i; }
            Assert::AreEqual(3U, i);
        }

        TEST_METHOD(should_be_able_to_access_tokens_by_their_index)
        {
            test_tokens<0> testTokens = { { "one" }, { "two" }, { "three" } };
            Assert::AreEqual("one", testTokens[0].val.c_str());
            Assert::AreEqual("two", testTokens[1].val.c_str());
            Assert::AreEqual("three", testTokens[2].val.c_str());
        }

        TEST_METHOD(should_be_able_to_access_tokens_from_a_const_container_by_ther_index)
        {
            const test_tokens<0> testTokens = { { "one" } };
            Assert::AreEqual("one", testTokens[0].val.c_str());
        }

    };
}}
<commit_msg>tabs --> spaces<commit_after>#include "CppUnitTest.h"
#include <string>
#include <vector>
#include <array>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace std;

namespace algo
{
    template<class Traits>
    class tokens
    {
        typedef vector<typename Traits::type> token_vector;
        token_vector tokens_;

    public:
        typedef typename token_vector::iterator iterator;
        typedef typename token_vector::const_iterator const_iterator;
        typedef typename Traits::type token_type;

        tokens() {}
        explicit tokens(size_t count) : tokens_(count) {}
        tokens(std::initializer_list<token_type> init) : tokens_(init) {}
        bool empty() const { return tokens_.size() == 0; }
        size_t size() const { return tokens_.size(); }
        token_type& operator[](size_t i) { return tokens_[i]; };
        const token_type& operator[](size_t i) const { return const_cast<tokens&>(*this)[i]; };

        iterator begin() { return tokens_.begin(); }
        const_iterator begin() const { return tokens_.begin(); }
        const_iterator cbegin() const { return tokens_.cbegin(); }
        iterator end() { return tokens_.end(); }
        const_iterator end() const { return tokens_.end(); }
        const_iterator cend() const { return tokens_.cend(); }

        void from_string(string s)
        {
            auto newTokens = Traits::tokenize(s);
            tokens_.insert(tokens_.end(), newTokens.begin(), newTokens.end());
        }
    };
}

namespace algo { namespace spec
{
    struct s { string val; };

    template<size_t N>
    struct test_token_traits
    {
        typedef s type;
        static array<s, N> tokenize(const string&) { return array<s, N>(); }
    };

    template<size_t N>
    using test_tokens = tokens<test_token_traits<N>>;

    TEST_CLASS(can_recognize_tokens)
    {
    public:

        TEST_METHOD(should_not_have_any_tokens_when_default_constructed)
        {
            test_tokens<0> testTokens;
            Assert::IsTrue(testTokens.empty());
        }

        TEST_METHOD(should_recognize_a_token_in_a_string)
        {
            test_tokens<1> testTokens;
            testTokens.from_string("irrelevant");
            Assert::AreEqual(1U, testTokens.size());
        }

        TEST_METHOD(should_recognize_more_than_one_token_in_a_string)
        {
            test_tokens<3> testTokens;
            testTokens.from_string("irrelevant");
            Assert::AreEqual(3U, testTokens.size());
        }

        TEST_METHOD(should_accumulate_tokens_from_successive_strings)
        {
            test_tokens<2> testTokens(3);
            testTokens.from_string("irrelevant");
            Assert::AreEqual(5U, testTokens.size());
        }

        TEST_METHOD(should_be_able_to_enumerate_tokens)
        {
            test_tokens<0> testTokens(3);
            size_t i = 0;
            for (s tok : testTokens) { ++i; }
            Assert::AreEqual(3U, i);
        }

        TEST_METHOD(should_be_able_to_enumerate_const_tokens_from_a_const_container)
        {
            const test_tokens<0> testTokens(3);
            size_t i = 0;
            for (const s tok : testTokens) { ++i; }
            Assert::AreEqual(3U, i);
        }

        TEST_METHOD(should_be_able_to_enumerate_const_tokens_from_a_non_const_container)
        {
            typedef test_tokens<0>::const_iterator const_iter;
            test_tokens<0> testTokens(3);
            size_t i = 0;
            for (const_iter it = testTokens.cbegin(); it != testTokens.cend(); ++it) { ++i; }
            Assert::AreEqual(3U, i);
        }

        TEST_METHOD(should_be_able_to_access_tokens_by_their_index)
        {
            test_tokens<0> testTokens = { { "one" }, { "two" }, { "three" } };
            Assert::AreEqual("one", testTokens[0].val.c_str());
            Assert::AreEqual("two", testTokens[1].val.c_str());
            Assert::AreEqual("three", testTokens[2].val.c_str());
        }

        TEST_METHOD(should_be_able_to_access_tokens_from_a_const_container_by_ther_index)
        {
            const test_tokens<0> testTokens = { { "one" } };
            Assert::AreEqual("one", testTokens[0].val.c_str());
        }

    };
}}
<|endoftext|>


<commit_before>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CCopasiMethod.cpp,v $
//   $Revision: 1.53 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2008/09/16 18:30:09 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

/**
 *  CCopasiMethod class.
 *  This class is used to describe a task in COPASI. This class is
 *  intended to be used as the parent class for all methods whithin COPASI.
 *
 *  Created for Copasi by Stefan Hoops 2003
 */

#include "copasi.h"

#include "CCopasiMethod.h"
#include "CCopasiMessage.h"
#include "CCopasiProblem.h"
#include "model/CModel.h"

const std::string CCopasiMethod::SubTypeName[] =
  {
    "Not set",
    "Random Search",
    "Random Search (PVM)",
    "Simulated Annealing",
    "Genetic Algorithm",
    "Evolutionary Programming",
    "Steepest Descent",
    "Hybrid GA/SA",
    "Genetic Algorithm SR",
    "Hooke & Jeeves",
    "Levenberg - Marquardt",
    "Nelder - Mead",
    "Evolution Strategy (SRES)",
    "Current Solution Statistics",
    "Particle Swarm",
    "Praxis",
    "Truncated Newton",
    "Enhanced Newton",
    "Deterministic (LSODA)",
    "Deterministic (LSODAR)",
    "Stochastic (Gibson + Bruck)",
    "Hybrid (Runge-Kutta)",
    "Hybrid (LSODA)",
#ifdef COPASI_TSSA
    "ILDM (LSODA,Deuflhard)",
    "ILDM (LSODA,Modified)",
    "CSP (LSODA)",
#endif // COPASI_TSSA
    "Stochastic (\xcf\x84-Leap)",
    "MCA Method (Reder)",
    "Scan Framework",
    "Wolf Method",
#ifdef COPASI_TSS
    "Time Scale Separation Method",
#endif // COPASI_TSS
    "Sensitivities Method",
#ifdef COPASI_SSA
    "Stoichiometric Stability Analysis",
#endif // COPASI_SSA
    "EFM Algorithm",
    "Householder Reduction",
    ""
  };

const char* CCopasiMethod::XMLSubType[] =
  {
    "NotSet",
    "RandomSearch",
    "RandomSearch(PVM)",
    "SimulatedAnnealing",
    "GeneticAlgorithm",
    "EvolutionaryProgram",
    "SteepestDescent",
    "HybridGASA",
    "GeneticAlgorithmSR",
    "HookeJeeves",
    "LevenbergMarquardt",
    "NelderMead",
    "EvolutionaryStrategySR",
    "CurrentSolutionStatistics",
    "ParticleSwarm",
    "Praxis",
    "TruncatedNewton",
    "EnhancedNewton",
    "Deterministic(LSODA)",
    "Deterministic(LSODAR)",
    "Stochastic",
    "Hybrid",
    "Hybrid (LSODA)",
#ifdef COPASI_DEBUG
    "TimeScaleSeparation(ILDM,Deuflhard)",
    "TimeScaleSeparation(ILDM,Modified)",
    "TimeScaleSeparation(CSP)",
#endif // COPASI_DEBUG
    "TauLeap",
    "MCAMethod(Reder)",
    "ScanFramework",
    "WolfMethod",
#ifdef COPASI_TSS
    "TimeScaleSeparationMethod",
#endif // COPASI_TSS
    "SensitivitiesMethod",
#ifdef COPASI_SSA
    "StoichiometricStabilityAnalysis",
#endif // COPASI_SSA
    "EFMAlgorithm",
    "Householder",
    NULL
  };

//    std::string mType;

CCopasiMethod::SubType CCopasiMethod::TypeNameToEnum(const std::string & subTypeName)
{
  unsigned C_INT32 i = 0;
  while (SubTypeName[i] != subTypeName && SubTypeName[i] != "")
    i++;

  if (CCopasiMethod::SubTypeName[i] != "") return (CCopasiMethod::SubType) i;
  else return CCopasiMethod::unset;
}

CCopasiMethod::CCopasiMethod():
    CCopasiParameterGroup("NoName", NULL, "Method"),
    mType(CCopasiTask::unset),
    mSubType(unset),
    mpCallBack(NULL)
    //mpReport(NULL)
{setObjectName(SubTypeName[mType]);}

CCopasiMethod::CCopasiMethod(const CCopasiTask::Type & type,
                             const CCopasiMethod::SubType & subType,
                             const CCopasiContainer * pParent):
    CCopasiParameterGroup(CCopasiTask::TypeName[type], pParent, "Method"),
    mType(type),
    mSubType(subType),
    mpCallBack(NULL)
    //mpReport(NULL)
{setObjectName(SubTypeName[mSubType]);}

CCopasiMethod::CCopasiMethod(const CCopasiMethod & src,
                             const CCopasiContainer * pParent):
    CCopasiParameterGroup(src, pParent),
    mType(src.mType),
    mSubType(src.mSubType),
    mpCallBack(src.mpCallBack)
    //mpReport(src.mpReport)
{}

CCopasiMethod::~CCopasiMethod() {}

bool CCopasiMethod::setCallBack(CProcessReport * pCallBack)
{
  mpCallBack = pCallBack;
  return true;
}

const CCopasiTask::Type & CCopasiMethod::getType() const {return mType;}

// void CCopasiMethod::setType(const CCopasiTask::Type & type) {mType = type;}

const CCopasiMethod::SubType & CCopasiMethod::getSubType() const
  {return mSubType;}

// void CCopasiMethod::setSubType(const CCopasiMethod::SubType & subType)
// {mSubType = subType;}

//virtual
bool CCopasiMethod::isValidProblem(const CCopasiProblem * pProblem)
{
  if (!pProblem)
    {
      //no problem
      CCopasiMessage(CCopasiMessage::EXCEPTION, MCCopasiMethod + 2);
      return false;
    }

  if (! pProblem->getModel())
    {
      //no model
      CCopasiMessage(CCopasiMessage::EXCEPTION, MCCopasiMethod + 3);
      return false;
    }

  if (pProblem->getModel()->getEvents().size())
    {
      if (mType == CCopasiTask::steadyState)
        {
          CCopasiMessage(CCopasiMessage::WARNING, MCCopasiMethod + 4, "Steady-State");
          return false;
        }

      if (mType == CCopasiTask::timeCourse && mSubType == CCopasiMethod::deterministic)
        {
          CCopasiMessage(CCopasiMessage::ERRoR, MCCopasiMethod + 4, "Time Course with deterministic method (LSODA)");
          return false;
        }

      if (mType == CCopasiTask::mca)
        {
          CCopasiMessage(CCopasiMessage::WARNING, MCCopasiMethod + 4, "Metabolic Control Analysis");
          return false;
        }

      if (mType == CCopasiTask::lyap)
        {
          CCopasiMessage(CCopasiMessage::ERRoR, MCCopasiMethod + 4, "Lyapunov Exponents");
          return false;
        }

#ifdef COPASI_TSSA
      if (mType == CCopasiTask::tssAnalysis)
        {
          CCopasiMessage(CCopasiMessage::ERRoR, MCCopasiMethod + 4, "Time Scale Separation Analysis");
          return false;
        }
#endif // COPASI_TSSA
    }

  return true;
}

void CCopasiMethod::load(CReadConfig & /* configBuffer */,
                         CReadConfig::Mode /* mode */)
{fatalError();}

void CCopasiMethod::print(std::ostream * ostream) const
  {*ostream << *this;}

std::ostream &operator<<(std::ostream &os, const CCopasiMethod & o)
{
  os << "Method: " << o.getObjectName() << std::endl;

  CCopasiParameterGroup::parameterGroup::const_iterator it =
    o.CCopasiParameter::getValue().pGROUP->begin();
  CCopasiParameterGroup::parameterGroup::const_iterator end =
    o.CCopasiParameter::getValue().pGROUP->end();

  for (; it != end; ++it)
    {
      (*it)->print(&os);
      os << std::endl;
    }

  return os;
}
<commit_msg>synchronize enum and xml strings<commit_after>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CCopasiMethod.cpp,v $
//   $Revision: 1.54 $
//   $Name:  $
//   $Author: ssahle $
//   $Date: 2008/10/20 12:31:05 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

/**
 *  CCopasiMethod class.
 *  This class is used to describe a task in COPASI. This class is
 *  intended to be used as the parent class for all methods whithin COPASI.
 *
 *  Created for Copasi by Stefan Hoops 2003
 */

#include "copasi.h"

#include "CCopasiMethod.h"
#include "CCopasiMessage.h"
#include "CCopasiProblem.h"
#include "model/CModel.h"

const std::string CCopasiMethod::SubTypeName[] =
  {
    "Not set",
    "Random Search",
    "Random Search (PVM)",
    "Simulated Annealing",
    "Genetic Algorithm",
    "Evolutionary Programming",
    "Steepest Descent",
    "Hybrid GA/SA",
    "Genetic Algorithm SR",
    "Hooke & Jeeves",
    "Levenberg - Marquardt",
    "Nelder - Mead",
    "Evolution Strategy (SRES)",
    "Current Solution Statistics",
    "Particle Swarm",
    "Praxis",
    "Truncated Newton",
    "Enhanced Newton",
    "Deterministic (LSODA)",
    "Deterministic (LSODAR)",
    "Stochastic (Gibson + Bruck)",
    "Hybrid (Runge-Kutta)",
    "Hybrid (LSODA)",
#ifdef COPASI_TSSA
    "ILDM (LSODA,Deuflhard)",
    "ILDM (LSODA,Modified)",
    "CSP (LSODA)",
#endif // COPASI_TSSA
    "Stochastic (\xcf\x84-Leap)",
    "MCA Method (Reder)",
    "Scan Framework",
    "Wolf Method",
#ifdef COPASI_TSS
    "Time Scale Separation Method",
#endif // COPASI_TSS
    "Sensitivities Method",
#ifdef COPASI_SSA
    "Stoichiometric Stability Analysis",
#endif // COPASI_SSA
    "EFM Algorithm",
    "Householder Reduction",
    ""
  };

const char* CCopasiMethod::XMLSubType[] =
  {
    "NotSet",
    "RandomSearch",
    "RandomSearch(PVM)",
    "SimulatedAnnealing",
    "GeneticAlgorithm",
    "EvolutionaryProgram",
    "SteepestDescent",
    "HybridGASA",
    "GeneticAlgorithmSR",
    "HookeJeeves",
    "LevenbergMarquardt",
    "NelderMead",
    "EvolutionaryStrategySR",
    "CurrentSolutionStatistics",
    "ParticleSwarm",
    "Praxis",
    "TruncatedNewton",
    "EnhancedNewton",
    "Deterministic(LSODA)",
    "Deterministic(LSODAR)",
    "Stochastic",
    "Hybrid",
    "Hybrid (LSODA)",
#ifdef COPASI_TSSA
    "TimeScaleSeparation(ILDM,Deuflhard)",
    "TimeScaleSeparation(ILDM,Modified)",
    "TimeScaleSeparation(CSP)",
#endif // COPASI_DEBUG
    "TauLeap",
    "MCAMethod(Reder)",
    "ScanFramework",
    "WolfMethod",
#ifdef COPASI_TSS
    "TimeScaleSeparationMethod",
#endif // COPASI_TSS
    "SensitivitiesMethod",
#ifdef COPASI_SSA
    "StoichiometricStabilityAnalysis",
#endif // COPASI_SSA
    "EFMAlgorithm",
    "Householder",
    NULL
  };

//    std::string mType;

CCopasiMethod::SubType CCopasiMethod::TypeNameToEnum(const std::string & subTypeName)
{
  unsigned C_INT32 i = 0;
  while (SubTypeName[i] != subTypeName && SubTypeName[i] != "")
    i++;

  if (CCopasiMethod::SubTypeName[i] != "") return (CCopasiMethod::SubType) i;
  else return CCopasiMethod::unset;
}

CCopasiMethod::CCopasiMethod():
    CCopasiParameterGroup("NoName", NULL, "Method"),
    mType(CCopasiTask::unset),
    mSubType(unset),
    mpCallBack(NULL)
    //mpReport(NULL)
{setObjectName(SubTypeName[mType]);}

CCopasiMethod::CCopasiMethod(const CCopasiTask::Type & type,
                             const CCopasiMethod::SubType & subType,
                             const CCopasiContainer * pParent):
    CCopasiParameterGroup(CCopasiTask::TypeName[type], pParent, "Method"),
    mType(type),
    mSubType(subType),
    mpCallBack(NULL)
    //mpReport(NULL)
{setObjectName(SubTypeName[mSubType]);}

CCopasiMethod::CCopasiMethod(const CCopasiMethod & src,
                             const CCopasiContainer * pParent):
    CCopasiParameterGroup(src, pParent),
    mType(src.mType),
    mSubType(src.mSubType),
    mpCallBack(src.mpCallBack)
    //mpReport(src.mpReport)
{}

CCopasiMethod::~CCopasiMethod() {}

bool CCopasiMethod::setCallBack(CProcessReport * pCallBack)
{
  mpCallBack = pCallBack;
  return true;
}

const CCopasiTask::Type & CCopasiMethod::getType() const {return mType;}

// void CCopasiMethod::setType(const CCopasiTask::Type & type) {mType = type;}

const CCopasiMethod::SubType & CCopasiMethod::getSubType() const
  {return mSubType;}

// void CCopasiMethod::setSubType(const CCopasiMethod::SubType & subType)
// {mSubType = subType;}

//virtual
bool CCopasiMethod::isValidProblem(const CCopasiProblem * pProblem)
{
  if (!pProblem)
    {
      //no problem
      CCopasiMessage(CCopasiMessage::EXCEPTION, MCCopasiMethod + 2);
      return false;
    }

  if (! pProblem->getModel())
    {
      //no model
      CCopasiMessage(CCopasiMessage::EXCEPTION, MCCopasiMethod + 3);
      return false;
    }

  if (pProblem->getModel()->getEvents().size())
    {
      if (mType == CCopasiTask::steadyState)
        {
          CCopasiMessage(CCopasiMessage::WARNING, MCCopasiMethod + 4, "Steady-State");
          return false;
        }

      if (mType == CCopasiTask::timeCourse && mSubType == CCopasiMethod::deterministic)
        {
          CCopasiMessage(CCopasiMessage::ERRoR, MCCopasiMethod + 4, "Time Course with deterministic method (LSODA)");
          return false;
        }

      if (mType == CCopasiTask::mca)
        {
          CCopasiMessage(CCopasiMessage::WARNING, MCCopasiMethod + 4, "Metabolic Control Analysis");
          return false;
        }

      if (mType == CCopasiTask::lyap)
        {
          CCopasiMessage(CCopasiMessage::ERRoR, MCCopasiMethod + 4, "Lyapunov Exponents");
          return false;
        }

#ifdef COPASI_TSSA
      if (mType == CCopasiTask::tssAnalysis)
        {
          CCopasiMessage(CCopasiMessage::ERRoR, MCCopasiMethod + 4, "Time Scale Separation Analysis");
          return false;
        }
#endif // COPASI_TSSA
    }

  return true;
}

void CCopasiMethod::load(CReadConfig & /* configBuffer */,
                         CReadConfig::Mode /* mode */)
{fatalError();}

void CCopasiMethod::print(std::ostream * ostream) const
  {*ostream << *this;}

std::ostream &operator<<(std::ostream &os, const CCopasiMethod & o)
{
  os << "Method: " << o.getObjectName() << std::endl;

  CCopasiParameterGroup::parameterGroup::const_iterator it =
    o.CCopasiParameter::getValue().pGROUP->begin();
  CCopasiParameterGroup::parameterGroup::const_iterator end =
    o.CCopasiParameter::getValue().pGROUP->end();

  for (; it != end; ++it)
    {
      (*it)->print(&os);
      os << std::endl;
    }

  return os;
}
<|endoftext|>


<commit_before><commit_msg>first repository<commit_after>#include <stdio.h>

int main()
{
	printf("My first git hub repository.\n");
	return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<commit_msg>--allow-empty_message<commit_after>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<|endoftext|>


<commit_before>#include <deque>
#include <vector>
#include <sys/mman.h>

#include "it.x64.asm.h"

uint64_t rejit_thread_read_utf8(const rejit_threadset_t *nfa)
{
    return rejit_read_utf8((const uint8_t *) nfa->input, nfa->length);
}

struct re2jit::native
{
    void *_code;
    void *_entry;
    size_t _size;

    native(re2::Prog *prog) : _code(NULL), _entry(NULL), _size(0)
    {
        size_t i;
        size_t n = prog->size();

        std::vector< uint8_t > code;
        // A map of opcode offsets to actual offsets in the compiled code.
        // Populated while emitting code, used for linking later.
        std::vector< size_t > vtable(n);
        // For each opcode id, stores the list of positions in generated code where a jump
        // or a reference to that opcode is necessary. The linker should insert an appropriate
        // entry from `vtable` at each of these.
        std::vector< std::vector<size_t> > backrefs(n);

        // If the program starts with a failing opcode, we can use that to redirect
        // all conditional rets instead of jumping over them.
        XORL_EAX_EAX();
        RETQ();

        // States not reachable from the entry point don't need to be compiled. Duh.
        std::vector< bool > reachable(n);
        // Whether multiple transitions have the i-th opcode as a target. We have to maintain
        // a bit vector of visited states to avoid going into an infinite loop; however,
        // opcodes with indegree 1 can never be at the start of a loop, so we can avoid
        // some memory lookups on these.
        std::vector< bool > is_a_loop(n);

        {
            std::deque< size_t > visit;
            visit.push_back(prog->start());
            reachable[prog->start()] = true;

            while (!visit.empty()) {
                i = visit.front();
                visit.pop_front();

                RE2JIT_WITH_INST(op, prog, i,
                    // re2jit::inst *
                    if (!reachable[op->out()]) {
                        reachable[op->out()] = true;
                        visit.push_back(op->out());
                    } else {
                        is_a_loop[op->out()] = true;
                    },

                    // re2::Prog::Inst *
                    switch (op->opcode()) {
                        case re2::kInstAlt:
                        case re2::kInstAltMatch:
                            if (!reachable[op->out1()]) {
                                reachable[op->out1()] = true;
                                visit.push_back(op->out1());
                            } else {
                                is_a_loop[op->out1()] = true;
                            }

                        default:
                            if (!reachable[op->out()]) {
                                reachable[op->out()] = true;
                                visit.push_back(op->out());
                            } else {
                                is_a_loop[op->out()] = true;
                            }

                        case re2::kInstFail:
                        case re2::kInstMatch:
                            break;
                    }
                );
            }
        }

        for (i = 0; i < n; i++) if (reachable[i]) {
            vtable[i] = code.size();

            // Each opcode should conform to System V ABI calling convention.
            //   %rdi :: struct rejit_threadset_t *
            //   %rsi, %rdx, %rcx, %r8, %r9 :: undefined
            // Return value:
            //   %rax :: int -- 1 if found a match, 0 otherwise

            // kInstFail will do `ret` anyway.
            if (prog->inst(i)->opcode() != re2::kInstFail && is_a_loop[i]) {
                //    mov (%rdi).visited, %rsi
                MOVB_MRDI_RSI(offsetof(struct rejit_threadset_t, visited));
                //    test 1<<(i%8), %rsi[i / 8]
                TEST_IMMB_MRSI(1 << (i % 8), i / 8);
                //    ret [if non-zero]
                RETQ_IF(JMP_NE);
                //    or 1<<(i%8), %rsi[i / 8]
                ORB_IMM_MRSI(1 << (i % 8), i / 8);
            }

            RE2JIT_WITH_INST(op, prog, i,
                switch (op->opcode()) {
                    case re2jit::inst::kUnicodeType: {
                        //    push %rdi
                        PUSH_RDI();
                        //    call rejit_thread_read_utf8
                        CALL_IMM(&rejit_thread_read_utf8);
                        //    pop %rdi
                        POP_RDI();
                        //    mov %rax, %rdx
                        MOVQ_RAX_RDX();
                        //    shr $32, %rdx
                        SHRQ_IMM_RDX(32);
                        //    ret [if ==]
                        RETQ_IF(JMP_ZERO);
                        //    mov %eax, %eax  <-- zero upper 32 bits
                        MOVL_EAX_EAX();
                        //    mov UNICODE_CODEPOINT_TYPE, %rsi  <-- no `add imm64, r64`
                        MOVQ_IMM_RSI((uint64_t) UNICODE_CODEPOINT_TYPE);
                        //    add %rsi, %rax
                        ADDQ_RSI_RAX();
                        //    mov (%rax), %cl
                        MOV__MRAX__CL();
                        //    and UNICODE_GENERAL, %cl
                        ANDB_IMM__CL(UNICODE_GENERAL);
                        //    cmp arg, %cl
                        CMPB_IMM__CL(op->arg());
                        //    ret [if !=]
                        RETQ_IF(JMP_NE);
                        //    mov code+vtable[out], %rsi
                        MOVQ_TBL_RSI(op->out());
                        //    jmp rejit_thread_wait
                        JMPL_IMM(&rejit_thread_wait);
                        break;
                    }

                    case re2jit::inst::kBackReference: {
                        //    cmp arg*2, (%rdi).groups
                        CMPL_IMM_MRDI(op->arg() * 2, offsetof(struct rejit_threadset_t, groups));
                        //    ret [if <=]  <-- wan't enough space to record that group
                        RETQ_IF(JMP_LE_U);

                        //    mov (%rdi).running, %rsi
                        MOVB_MRDI_RSI(offsetof(struct rejit_threadset_t, running));
                        //    mov (%rsi).groups[arg*2], %eax
                        MOVL_MRSI_EAX(offsetof(struct rejit_thread_t, groups) + sizeof(int) * (op->arg() * 2));
                        //    mov (%rsi).groups[arg*2+1], %ecx
                        MOVL_MRSI_ECX(offsetof(struct rejit_thread_t, groups) + sizeof(int) * (op->arg() * 2 + 1));

                        //    cmp $-1, %eax
                        CMPB_IMM_EAX(0xFF);
                        //    ret [if ==]
                        RETQ_IF(JMP_EQ);

                        //    sub %eax, %ecx
                        SUBL_EAX_ECX();
                        //    ret [if <]
                        RETQ_IF(JMP_LT);
                        //    je code+vtable[out]
                        JMP_TBL(JMP_EQ, op->out());
                        //    mov %ecx, %edx
                        MOVL_ECX_EDX();

                        //    mov %rdi, %r8
                        MOVQ_RDI_R8_();
                        //    mov (%r8).input, %rdi
                        MOVB_MR8__RDI(offsetof(struct rejit_threadset_t, input));
                        //    mov %rdi, %rsi
                        MOVQ_RDI_RSI();
                        //    sub (%r8).offset, %rsi
                        SUBB_MR8__RSI(offsetof(struct rejit_threadset_t, offset));
                        //    add %rax, %rsi
                        ADDQ_RAX_RSI();
                        //    repz cmpsb
                        //    ^    ^-- compare bytes at (%rdi) and (%rsi), increment both
                        //    \-- repeat while ZF is set and %rcx is non-zero
                        //    Essentially, this opcode is `ZF, SF = memcmp(%rdi, %rsi, %rcx)`.
                        REPZ_CMPSB();
                        //    mov %r8, %rdi
                        MOVQ_R8__RDI();
                        //    ret [if !=]
                        RETQ_IF(JMP_NE);

                        //    mov code+vtable[out], %rsi
                        MOVQ_TBL_RSI(op->out());
                        //    jmp rejit_thread_wait
                        JMPL_IMM(&rejit_thread_wait);
                        break;
                    }

                    default:
                        re2jit::debug::write("re2jit::x64: unknown extcode %hu\n", op->opcode());
                        RETQ();
                        break;
                },

                switch (op->opcode()) {
                    case re2::kInstAltMatch:
                    case re2::kInstAlt:
                        //    call code+vtable[out]
                        PUSH_RDI(); CALL_TBL(op->out()); POP_RDI();
                        //    test %eax, %eax -- non-zero if found a match
                        TEST_EAX_EAX();
                        //    jnz -> ret, skipping over `xor %eax, %eax`
                        JMP_ABS(JMP_NZ, 2L);

                        if ((size_t) op->out1() != i + 1) {
                            //    jmp  code+vtable[out1]
                            JMP_UNCOND_TBL(op->out1());
                        }

                        break;

                    case re2::kInstByteRange:
                        //    cmp $0, (%rdi).length
                        CMPB_IMM_MRDI(0, offsetof(struct rejit_threadset_t, length));
                        //    ret [if ==]
                        RETQ_IF(JMP_EQ);

                        //    mov (%rdi).input, %rax
                        MOVB_MRDI_RAX(offsetof(struct rejit_threadset_t, input));
                        //    mov (%rax), %cl
                        MOV__MRAX__CL();

                        if (op->foldcase()) {
                            //    cmp $'A', %cl
                            CMPB_IMM__CL('A');
                            //    jb skip
                            JMP_OVER(JMP_LT_U, {
                                //    cmp $'Z', %cl
                                CMPB_IMM__CL('Z');
                                //    ja  skip
                                JMP_OVER(JMP_GT_U,
                                    //    add $'a'-'A', %cl
                                    ADDB_IMM__CL('a' - 'A'));
                            }); // skip:
                        }

                        if (op->hi() == op->lo()) {
                            //    cmp lo, %cl
                            CMPB_IMM__CL(op->lo());
                            //    ret [if !=]
                            RETQ_IF(JMP_NE);
                        } else {
                            //    sub lo, %cl
                            SUBB_IMM__CL(op->lo());
                            //    cmp hi-lo, %cl
                            CMPB_IMM__CL(op->hi() - op->lo());
                            //    ret [if >]
                            RETQ_IF(JMP_GT_U);
                        }

                        //    mov code+vtable[out], %rsi
                        MOVQ_TBL_RSI(op->out());
                        //    mov $1, %edx
                        MOVL_IMM_EDX(1u);
                        //    jmp rejit_thread_wait
                        JMPL_IMM(&rejit_thread_wait);
                        break;

                    case re2::kInstCapture:
                        //    cmp cap, (%rdi).groups
                        CMPL_IMM_MRDI(op->cap(), offsetof(struct rejit_threadset_t, groups));
                        //    jbe code+vtable[out]
                        JMP_TBL(JMP_LE_U, op->out());

                        //    mov (%rdi).running, %rcx
                        MOVB_MRDI_RCX(offsetof(struct rejit_threadset_t, running));
                        //    mov (%rdi).offset, %rax
                        MOVB_MRDI_RAX(offsetof(struct rejit_threadset_t, offset));
                        //    mov (%rcx).groups[cap], %esi
                        MOVL_MRCX_ESI(offsetof(struct rejit_thread_t, groups) + sizeof(int) * op->cap());
                        //    mov %eax, (%rcx).groups[cap]
                        MOVL_EAX_MRCX(offsetof(struct rejit_thread_t, groups) + sizeof(int) * op->cap());

                        //    call code+vtable[out]
                        PUSH_RDI(); PUSH_RSI(); CALL_TBL(op->out()); POP_RSI(); POP_RDI();

                        //    mov (%rdi).running, %rcx
                        MOVB_MRDI_RCX(offsetof(struct rejit_threadset_t, running));
                        //    mov %esi, (%rcx).groups[cap]
                        MOVL_ESI_MRCX(offsetof(struct rejit_thread_t, groups) + sizeof(int) * op->cap());
                        //    ret
                        RETQ();
                        break;

                    case re2::kInstEmptyWidth:
                        //    mov (%rdi).empty, %eax
                        MOVB_MRDI_EAX(offsetof(struct rejit_threadset_t, empty));
                        //    not %eax
                        NOTL_EAX();
                        //    test empty, %eax
                        TEST_IMM_EAX(op->empty());
                        //    ret [if non-zero]
                        RETQ_IF(JMP_NZ);

                        if ((size_t) op->out() != i + 1) {
                            //    jmp code+vtable[out]
                            JMP_UNCOND_TBL(op->out());
                        }

                        break;

                    case re2::kInstNop:
                        if ((size_t) op->out() != i + 1) {
                            //    jmp code+vtable[out]
                            JMP_UNCOND_TBL(op->out());
                        }
                        break;

                    case re2::kInstMatch:
                        //    jmp rejit_thread_match
                        JMPL_IMM(&rejit_thread_match);
                        break;

                    case re2::kInstFail:
                        //    ret
                        RETQ();
                        break;

                    default:
                        re2jit::debug::write("re2jit::x64: unknown opcode %d\n", op->opcode());
                        return;
                }
            );
        }

        uint8_t *target = (uint8_t *) mmap(0, code.size(),
                                           PROT_READ | PROT_WRITE,
                                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

        if (target == (uint8_t *) -1) {
            return;
        }

        {
            uint8_t *target2 = target;

            for (uint8_t byte : code) {
                *target2++ = byte;
            }
        }

        for (i = 0; i < n; i++) {
            for (size_t ref : backrefs[i]) {
                if (IS_JUMP_TARGET(ref)) {
                    int32_t offset = vtable[i] - (ref + 4);
                    // jumps use 32-bit signed offsets, thus the target is relative to ref+4.
                    memcpy(target + ref, &offset, sizeof(offset));
                } else {
                    uint64_t addr = (size_t) (target + vtable[i]);
                    // movq -- 64-bit absolute pointer
                    memcpy(target + ref, &addr, sizeof(addr));
                }
            }
        }

        if (mprotect(target, code.size(), PROT_READ | PROT_EXEC) == -1) {
            munmap(target, code.size());
            return;
        }

        _code  = target;
        _entry = target + vtable[prog->start()];
        _size  = code.size();
    }

   ~native()
    {
        munmap(_code, _size);
    }

    rejit_entry_t entry() const
    {
        return (rejit_entry_t) _entry;
    }

    void run(struct rejit_threadset_t *nfa) const
    {
        rejit_thread_dispatch(nfa);
    }
};
<commit_msg>Use DFS for dead code elimination.<commit_after>#include <vector>
#include <sys/mman.h>

#include "it.x64.asm.h"

uint64_t rejit_thread_read_utf8(const rejit_threadset_t *nfa)
{
    return rejit_read_utf8((const uint8_t *) nfa->input, nfa->length);
}

struct re2jit::native
{
    void *_code;
    void *_entry;
    size_t _size;

    native(re2::Prog *prog) : _code(NULL), _entry(NULL), _size(0)
    {
        size_t i;
        size_t n = prog->size();

        std::vector< uint8_t > code;
        // A map of opcode offsets to actual offsets in the compiled code.
        // Populated while emitting code, used for linking later.
        std::vector< size_t > vtable(n);
        // For each opcode id, stores the list of positions in generated code where a jump
        // or a reference to that opcode is necessary. The linker should insert an appropriate
        // entry from `vtable` at each of these.
        std::vector< std::vector<size_t> > backrefs(n);

        // If the program starts with a failing opcode, we can use that to redirect
        // all conditional rets instead of jumping over them.
        XORL_EAX_EAX();
        RETQ();

        // How many transitions have the i-th opcode as a target. We have to maintain
        // a bit vector of visited states to avoid going into an infinite loop; however,
        // opcodes with indegree 1 can never be at the start of a loop, so we can avoid
        // some memory lookups on these.
        std::vector< unsigned > indegree(n);

        ssize_t *stack = new ssize_t[prog->size()];
        ssize_t *stptr = stack;
        indegree[*stptr++ = prog->start()]++;

        while (stptr != stack)
            RE2JIT_WITH_INST(op, prog, *--stptr,
                // re2jit::inst *
                if (!indegree[op->out()]++)
                    *stptr++ = op->out();

                // re2::Prog::Inst *
              , switch (op->opcode()) {
                    case re2::kInstAlt:
                    case re2::kInstAltMatch:
                        if (!indegree[op->out1()]++)
                            *stptr++ = op->out1();

                    default:
                        if (!indegree[op->out()]++)
                            *stptr++ = op->out();

                    case re2::kInstFail:
                    case re2::kInstMatch:
                        break;
                }
            );

        delete[] stack;

        for (i = 0; i < n; i++) if (indegree[i]) {
            vtable[i] = code.size();

            // Each opcode should conform to System V ABI calling convention.
            //   %rdi :: struct rejit_threadset_t *
            //   %rsi, %rdx, %rcx, %r8, %r9 :: undefined
            // Return value:
            //   %rax :: int -- 1 if found a match, 0 otherwise

            // kInstFail will do `ret` anyway.
            if (prog->inst(i)->opcode() != re2::kInstFail && indegree[i] > 1) {
                //    mov (%rdi).visited, %rsi
                MOVB_MRDI_RSI(offsetof(struct rejit_threadset_t, visited));
                //    test 1<<(i%8), %rsi[i / 8]
                TEST_IMMB_MRSI(1 << (i % 8), i / 8);
                //    ret [if non-zero]
                RETQ_IF(JMP_NE);
                //    or 1<<(i%8), %rsi[i / 8]
                ORB_IMM_MRSI(1 << (i % 8), i / 8);
            }

            RE2JIT_WITH_INST(op, prog, i,
                switch (op->opcode()) {
                    case re2jit::inst::kUnicodeType: {
                        //    push %rdi
                        PUSH_RDI();
                        //    call rejit_thread_read_utf8
                        CALL_IMM(&rejit_thread_read_utf8);
                        //    pop %rdi
                        POP_RDI();
                        //    mov %rax, %rdx
                        MOVQ_RAX_RDX();
                        //    shr $32, %rdx
                        SHRQ_IMM_RDX(32);
                        //    ret [if ==]
                        RETQ_IF(JMP_ZERO);
                        //    mov %eax, %eax  <-- zero upper 32 bits
                        MOVL_EAX_EAX();
                        //    mov UNICODE_CODEPOINT_TYPE, %rsi  <-- no `add imm64, r64`
                        MOVQ_IMM_RSI((uint64_t) UNICODE_CODEPOINT_TYPE);
                        //    add %rsi, %rax
                        ADDQ_RSI_RAX();
                        //    mov (%rax), %cl
                        MOV__MRAX__CL();
                        //    and UNICODE_GENERAL, %cl
                        ANDB_IMM__CL(UNICODE_GENERAL);
                        //    cmp arg, %cl
                        CMPB_IMM__CL(op->arg());
                        //    ret [if !=]
                        RETQ_IF(JMP_NE);
                        //    mov code+vtable[out], %rsi
                        MOVQ_TBL_RSI(op->out());
                        //    jmp rejit_thread_wait
                        JMPL_IMM(&rejit_thread_wait);
                        break;
                    }

                    case re2jit::inst::kBackReference: {
                        //    cmp arg*2, (%rdi).groups
                        CMPL_IMM_MRDI(op->arg() * 2, offsetof(struct rejit_threadset_t, groups));
                        //    ret [if <=]  <-- wan't enough space to record that group
                        RETQ_IF(JMP_LE_U);

                        //    mov (%rdi).running, %rsi
                        MOVB_MRDI_RSI(offsetof(struct rejit_threadset_t, running));
                        //    mov (%rsi).groups[arg*2], %eax
                        MOVL_MRSI_EAX(offsetof(struct rejit_thread_t, groups) + sizeof(int) * (op->arg() * 2));
                        //    mov (%rsi).groups[arg*2+1], %ecx
                        MOVL_MRSI_ECX(offsetof(struct rejit_thread_t, groups) + sizeof(int) * (op->arg() * 2 + 1));

                        //    cmp $-1, %eax
                        CMPB_IMM_EAX(0xFF);
                        //    ret [if ==]
                        RETQ_IF(JMP_EQ);

                        //    sub %eax, %ecx
                        SUBL_EAX_ECX();
                        //    ret [if <]
                        RETQ_IF(JMP_LT);
                        //    je code+vtable[out]
                        JMP_TBL(JMP_EQ, op->out());
                        //    mov %ecx, %edx
                        MOVL_ECX_EDX();

                        //    mov %rdi, %r8
                        MOVQ_RDI_R8_();
                        //    mov (%r8).input, %rdi
                        MOVB_MR8__RDI(offsetof(struct rejit_threadset_t, input));
                        //    mov %rdi, %rsi
                        MOVQ_RDI_RSI();
                        //    sub (%r8).offset, %rsi
                        SUBB_MR8__RSI(offsetof(struct rejit_threadset_t, offset));
                        //    add %rax, %rsi
                        ADDQ_RAX_RSI();
                        //    repz cmpsb
                        //    ^    ^-- compare bytes at (%rdi) and (%rsi), increment both
                        //    \-- repeat while ZF is set and %rcx is non-zero
                        //    Essentially, this opcode is `ZF, SF = memcmp(%rdi, %rsi, %rcx)`.
                        REPZ_CMPSB();
                        //    mov %r8, %rdi
                        MOVQ_R8__RDI();
                        //    ret [if !=]
                        RETQ_IF(JMP_NE);

                        //    mov code+vtable[out], %rsi
                        MOVQ_TBL_RSI(op->out());
                        //    jmp rejit_thread_wait
                        JMPL_IMM(&rejit_thread_wait);
                        break;
                    }

                    default:
                        re2jit::debug::write("re2jit::x64: unknown extcode %hu\n", op->opcode());
                        RETQ();
                        break;
                },

                switch (op->opcode()) {
                    case re2::kInstAltMatch:
                    case re2::kInstAlt:
                        //    call code+vtable[out]
                        PUSH_RDI(); CALL_TBL(op->out()); POP_RDI();
                        //    test %eax, %eax -- non-zero if found a match
                        TEST_EAX_EAX();
                        //    jnz -> ret, skipping over `xor %eax, %eax`
                        JMP_ABS(JMP_NZ, 2L);

                        if ((size_t) op->out1() != i + 1) {
                            //    jmp  code+vtable[out1]
                            JMP_UNCOND_TBL(op->out1());
                        }

                        break;

                    case re2::kInstByteRange:
                        //    cmp $0, (%rdi).length
                        CMPB_IMM_MRDI(0, offsetof(struct rejit_threadset_t, length));
                        //    ret [if ==]
                        RETQ_IF(JMP_EQ);

                        //    mov (%rdi).input, %rax
                        MOVB_MRDI_RAX(offsetof(struct rejit_threadset_t, input));
                        //    mov (%rax), %cl
                        MOV__MRAX__CL();

                        if (op->foldcase()) {
                            //    cmp $'A', %cl
                            CMPB_IMM__CL('A');
                            //    jb skip
                            JMP_OVER(JMP_LT_U, {
                                //    cmp $'Z', %cl
                                CMPB_IMM__CL('Z');
                                //    ja  skip
                                JMP_OVER(JMP_GT_U,
                                    //    add $'a'-'A', %cl
                                    ADDB_IMM__CL('a' - 'A'));
                            }); // skip:
                        }

                        if (op->hi() == op->lo()) {
                            //    cmp lo, %cl
                            CMPB_IMM__CL(op->lo());
                            //    ret [if !=]
                            RETQ_IF(JMP_NE);
                        } else {
                            //    sub lo, %cl
                            SUBB_IMM__CL(op->lo());
                            //    cmp hi-lo, %cl
                            CMPB_IMM__CL(op->hi() - op->lo());
                            //    ret [if >]
                            RETQ_IF(JMP_GT_U);
                        }

                        //    mov code+vtable[out], %rsi
                        MOVQ_TBL_RSI(op->out());
                        //    mov $1, %edx
                        MOVL_IMM_EDX(1u);
                        //    jmp rejit_thread_wait
                        JMPL_IMM(&rejit_thread_wait);
                        break;

                    case re2::kInstCapture:
                        //    cmp cap, (%rdi).groups
                        CMPL_IMM_MRDI(op->cap(), offsetof(struct rejit_threadset_t, groups));
                        //    jbe code+vtable[out]
                        JMP_TBL(JMP_LE_U, op->out());

                        //    mov (%rdi).running, %rcx
                        MOVB_MRDI_RCX(offsetof(struct rejit_threadset_t, running));
                        //    mov (%rdi).offset, %rax
                        MOVB_MRDI_RAX(offsetof(struct rejit_threadset_t, offset));
                        //    mov (%rcx).groups[cap], %esi
                        MOVL_MRCX_ESI(offsetof(struct rejit_thread_t, groups) + sizeof(int) * op->cap());
                        //    mov %eax, (%rcx).groups[cap]
                        MOVL_EAX_MRCX(offsetof(struct rejit_thread_t, groups) + sizeof(int) * op->cap());

                        //    call code+vtable[out]
                        PUSH_RDI(); PUSH_RSI(); CALL_TBL(op->out()); POP_RSI(); POP_RDI();

                        //    mov (%rdi).running, %rcx
                        MOVB_MRDI_RCX(offsetof(struct rejit_threadset_t, running));
                        //    mov %esi, (%rcx).groups[cap]
                        MOVL_ESI_MRCX(offsetof(struct rejit_thread_t, groups) + sizeof(int) * op->cap());
                        //    ret
                        RETQ();
                        break;

                    case re2::kInstEmptyWidth:
                        //    mov (%rdi).empty, %eax
                        MOVB_MRDI_EAX(offsetof(struct rejit_threadset_t, empty));
                        //    not %eax
                        NOTL_EAX();
                        //    test empty, %eax
                        TEST_IMM_EAX(op->empty());
                        //    ret [if non-zero]
                        RETQ_IF(JMP_NZ);

                        if ((size_t) op->out() != i + 1) {
                            //    jmp code+vtable[out]
                            JMP_UNCOND_TBL(op->out());
                        }

                        break;

                    case re2::kInstNop:
                        if ((size_t) op->out() != i + 1) {
                            //    jmp code+vtable[out]
                            JMP_UNCOND_TBL(op->out());
                        }
                        break;

                    case re2::kInstMatch:
                        //    jmp rejit_thread_match
                        JMPL_IMM(&rejit_thread_match);
                        break;

                    case re2::kInstFail:
                        //    ret
                        RETQ();
                        break;

                    default:
                        re2jit::debug::write("re2jit::x64: unknown opcode %d\n", op->opcode());
                        return;
                }
            );
        }

        uint8_t *target = (uint8_t *) mmap(0, code.size(),
                                           PROT_READ | PROT_WRITE,
                                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

        if (target == (uint8_t *) -1) {
            return;
        }

        {
            uint8_t *target2 = target;

            for (uint8_t byte : code) {
                *target2++ = byte;
            }
        }

        for (i = 0; i < n; i++) {
            for (size_t ref : backrefs[i]) {
                if (IS_JUMP_TARGET(ref)) {
                    int32_t offset = vtable[i] - (ref + 4);
                    // jumps use 32-bit signed offsets, thus the target is relative to ref+4.
                    memcpy(target + ref, &offset, sizeof(offset));
                } else {
                    uint64_t addr = (size_t) (target + vtable[i]);
                    // movq -- 64-bit absolute pointer
                    memcpy(target + ref, &addr, sizeof(addr));
                }
            }
        }

        if (mprotect(target, code.size(), PROT_READ | PROT_EXEC) == -1) {
            munmap(target, code.size());
            return;
        }

        _code  = target;
        _entry = target + vtable[prog->start()];
        _size  = code.size();
    }

   ~native()
    {
        munmap(_code, _size);
    }

    rejit_entry_t entry() const
    {
        return (rejit_entry_t) _entry;
    }

    void run(struct rejit_threadset_t *nfa) const
    {
        rejit_thread_dispatch(nfa);
    }
};
<|endoftext|>


<commit_before>#include <catch.hpp>
#include <rapidcheck-catch.h>

#include "rapidcheck/newgen/Exec.h"

#include "util/Predictable.h"
#include "util/GenUtils.h"

using namespace rc;
using namespace rc::newgen::detail;
using namespace rc::test;

TEST_CASE("newgen::exec") {
    prop("yields the same result as execRaw but without recipe",
         [](const GenParams &params) {
             using Tuple = std::tuple<int, int, int>;

             const auto callable = [](const FixedCountdown<2> &a) {
                 return std::make_tuple(
                     a.value,
                     *genFixedCountdown(2),
                     *genFixedCountdown(2));
             };

             const auto expected = newgen::map(
                 execRaw(callable), [](const std::pair<Tuple, Recipe> &p) {
                     return p.first;
                 })(params.random, params.size);

             const auto actual = newgen::exec(callable)(params.random,
                                                        params.size);

             RC_ASSERT(actual == expected);
         });

    SECTION("works with non-copyable types") {
        auto shrinkable = newgen::exec([=](NonCopyable nc) {
            return std::move(nc);
        })(Random(), 0);
        REQUIRE(isArbitraryPredictable(shrinkable.value()));
    }
}
<commit_msg>Move ExecTests to new framework<commit_after>#include <catch.hpp>
#include <rapidcheck-catch.h>

#include "rapidcheck/newgen/Exec.h"

#include "util/Predictable.h"
#include "util/GenUtils.h"

using namespace rc;
using namespace rc::newgen::detail;
using namespace rc::test;

TEST_CASE("newgen::exec") {
    newprop(
        "yields the same result as execRaw but without recipe",
        [](const GenParams &params) {
            using Tuple = std::tuple<int, int, int>;

            const auto callable = [](const FixedCountdown<2> &a) {
                return std::make_tuple(
                    a.value,
                    *genFixedCountdown(2),
                    *genFixedCountdown(2));
            };

            const auto expected = newgen::map(
                execRaw(callable), [](const std::pair<Tuple, Recipe> &p) {
                    return p.first;
                })(params.random, params.size);

            const auto actual = newgen::exec(callable)(params.random,
                                                       params.size);

            RC_ASSERT(actual == expected);
        });

    SECTION("works with non-copyable types") {
        auto shrinkable = newgen::exec([=](NonCopyable nc) {
            return std::move(nc);
        })(Random(), 0);
        REQUIRE(isArbitraryPredictable(shrinkable.value()));
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2010, 2011 Esrille Inc.
 *
 * 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 "ElementImp.h"

#include <new>

#include "AttrImp.h"
#include "DocumentImp.h"
#include "MutationEventImp.h"
#include "css/CSSSerialize.h"
#include "html/HTMLTokenizer.h"

namespace org { namespace w3c { namespace dom { namespace bootstrap {

class AttrArray : public Object
{
    ElementImp* element;
public:
    virtual unsigned int getLength() {
        return element->attributes.size();
    }
    virtual void setLength(unsigned int length) {
    }
    virtual Attr getElement(unsigned int index) {
        if (element->attributes.size() <= index)
            return 0;
        return element->attributes[index];
    }
    virtual void setElement(unsigned int index, Attr value) {
    }
    // Object
    virtual Any message_(uint32_t selector, const char* id, int argc, Any* argv) {
        return ObjectArray<Attr>::dispatch(this, selector, id, argc, argv);
    }
    AttrArray(ElementImp* element) :
        Object(this),
        element(element) {
    }
};

void ElementImp::setAttributes(const std::deque<Attr>& attributes)
{
    if (this->attributes.empty()) {
        this->attributes = attributes;
        return;
    }
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        setAttributeNS(attr.getNamespaceURI(), attr.getName(), attr.getValue());
    }
}

ElementImp* ElementImp::getNextElement(ElementImp* root)
{
    NodeImp* n = this;
    for (auto i = n->firstChild; i; i = i->nextSibling) {
        if (i->getNodeType() == Node::ELEMENT_NODE)
            return dynamic_cast<ElementImp*>(i);
    }
    while (n != root) {
        while (n->nextSibling) {
            n = n->nextSibling;
            if (n->getNodeType() == Node::ELEMENT_NODE)
                return dynamic_cast<ElementImp*>(n);
        }
        n = n->parentNode;
    }
    return 0;
}

// Node

unsigned short ElementImp::getNodeType()
{
    return Node::ELEMENT_NODE;
}

Node ElementImp::cloneNode(bool deep)
{
    return new(std::nothrow) ElementImp(this, deep);
}

Nullable<std::u16string> ElementImp::getTextContent()
{
    std::u16string content;
    for (Node child = getFirstChild(); child; child = child.getNextSibling()) {
        if (child.getNodeType() == Node::COMMENT_NODE)
            continue;
        Nullable<std::u16string> text = child.getTextContent();
        if (text.hasValue())
            content += text.value();
    }
    return content;
}

void ElementImp::setTextContent(std::u16string textContent)
{
    while (hasChildNodes())
        removeChild(getFirstChild());
    if (0 < textContent.length()) {
        org::w3c::dom::Text text = ownerDocument->createTextNode(textContent);
        appendChild(text);
    }
}

// Element
Nullable<std::u16string> ElementImp::getNamespaceURI()
{
    return namespaceURI;
}

Nullable<std::u16string> ElementImp::getPrefix()
{
    return prefix;
}

std::u16string ElementImp::getLocalName()
{
    return localName;
}

std::u16string ElementImp::getTagName()
{
    if (0 < prefix.length())
        return prefix + u':' + localName;
    return localName;
}

dom::ObjectArray<Attr> ElementImp:: getAttributes()
{
    return new(std::nothrow) AttrArray(this);
}

Nullable<std::u16string> ElementImp::getAttribute(std::u16string name)
{
    // TODO: If the context node is in the HTML namespace and its ownerDocument is an HTML document
        toLower(name);
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getName() == name)
            return attr.getValue();
    }
    return Nullable<std::u16string>();
}

Nullable<std::u16string> ElementImp::getAttributeNS(std::u16string namespaceURI, std::u16string localName)
{
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getNamespaceURI().hasValue() && attr.getNamespaceURI().value() == namespaceURI && attr.getLocalName() == localName)
            return attr.getValue();
    }
    return Nullable<std::u16string>();
}

void ElementImp::setAttribute(std::u16string name, std::u16string value)
{
    // TODO: If qualifiedName does not match the Name production in XML, raise an INVALID_CHARACTER_ERR exception and terminate these steps.
    // TODO: If the context node is in the HTML namespace and its ownerDocument is an HTML document
        toLower(name);
    // TODO: If qualifiedName starts with "xmlns", raise a NAMESPACE_ERR and terminate these steps.
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getName() == name) {
            std::u16string prevValue = attr.getValue();
            attr.setValue(value);

            events::MutationEvent event = new(std::nothrow) MutationEventImp;
            event.initMutationEvent(u"DOMAttrModified",
                                    true, false, attr, prevValue, value, name, events::MutationEvent::MODIFICATION);
            this->dispatchEvent(event);
            return;
        }
    }
    Attr attr = new(std::nothrow) AttrImp(Nullable<std::u16string>(), Nullable<std::u16string>(), name, value);
    if (attr)
        attributes.push_back(attr);
}

void ElementImp::setAttributeNS(std::u16string namespaceURI, std::u16string qualifiedName, std::u16string value)
{
    // TODO:
    // TODO:
    Nullable<std::u16string> prefix;
    std::u16string localName;
    size_t pos = qualifiedName.find(u':');
    if (pos != std::u16string::npos) {
        prefix = qualifiedName.substr(0, pos);
        localName = qualifiedName.substr(pos + 1);
    } else
        localName = qualifiedName;
    if (prefix.hasValue()) {
        if (namespaceURI.length() == 0)
            throw DOMException(DOMException::NAMESPACE_ERR);
        if (prefix.value() == u"xml" && namespaceURI != u"http://www.w3.org/XML/1998/namespace")
            throw DOMException(DOMException::NAMESPACE_ERR);
    }
    if ((qualifiedName == u"xmlns" || prefix.hasValue() && prefix.value() == u"xmlns") &&
        namespaceURI != u"http://www.w3.org/2000/xmlns") {
        throw DOMException(DOMException::NAMESPACE_ERR);
    }
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getNamespaceURI().hasValue() && attr.getNamespaceURI().value() == namespaceURI && attr.getLocalName() == localName) {
            attr.setValue(value);
            // TODO: set prefix, too.
            return;
        }
    }
    Attr attr = new(std::nothrow) AttrImp(namespaceURI, prefix, localName, value);
    if (attr)
        attributes.push_back(attr);
}

void ElementImp::removeAttribute(std::u16string name)
{
    // TODO: Ask Anne if we don't have to call toLower()
    // TODO: If the context node is in the HTML namespace and its ownerDocument is an HTML document
        toLower(name);
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getName() == name)
            attributes.erase(i);
    }
}

void ElementImp::removeAttributeNS(std::u16string namespaceURI, std::u16string localName)
{
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getNamespaceURI().hasValue() && attr.getNamespaceURI().value() == namespaceURI && attr.getLocalName() == localName)
            attributes.erase(i);
    }
}

bool ElementImp::hasAttribute(std::u16string name)
{
    // TODO: If the context node is in the HTML namespace and its ownerDocument is an HTML document
        toLower(name);
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getName() == name)
            return true;
    }
    return false;
}

bool ElementImp::hasAttributeNS(std::u16string namespaceURI, std::u16string localName)
{
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getNamespaceURI().hasValue() && attr.getNamespaceURI().value() == namespaceURI && attr.getLocalName() == localName)
            return true;
    }
    return false;
}

html::HTMLCollection ElementImp::getChildren()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList ElementImp::getElementsByTagName(std::u16string qualifiedName)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList ElementImp::getElementsByTagNameNS(std::u16string _namespace, std::u16string localName)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList ElementImp::getElementsByClassName(std::u16string classNames)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

Element ElementImp::getFirstElementChild()
{
    for (NodeImp* n = this->firstChild; n; n = n->nextSibling) {
        if (dynamic_cast<ElementImp*>(n))
            return n;
    }
    return 0;
}

Element ElementImp::getLastElementChild()
{
    for (NodeImp* n = this->lastChild; n; n = n->previousSibling) {
        if (dynamic_cast<ElementImp*>(n))
            return n;
    }
    return 0;
}

Element ElementImp::getPreviousElementSibling()
{
    NodeImp* n = this;
    while (n = n->previousSibling) {
        if (dynamic_cast<ElementImp*>(n))
            return n;
    }
    return 0;
}

Element ElementImp::getNextElementSibling()
{
    NodeImp* n = this;
    while (n = n->nextSibling) {
        if (dynamic_cast<ElementImp*>(n))
            return n;
    }
    return 0;
}

unsigned int ElementImp::getChildElementCount()
{
    unsigned int count = 0;
    for (NodeImp* n = this->firstChild; n; n = n->nextSibling) {
        if (dynamic_cast<ElementImp*>(n))
            ++count;
    }
    return count;
}

views::ClientRectList ElementImp::getClientRects()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

views::ClientRect ElementImp::getBoundingClientRect()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void ElementImp::scrollIntoView(bool top)
{
    // TODO: implement me!
}

int ElementImp::getScrollTop()
{
    // TODO: implement me!
    return 0;
}

void ElementImp::setScrollTop(int scrollTop)
{
    // TODO: implement me!
}

int ElementImp::getScrollLeft()
{
    // TODO: implement me!
    return 0;
}

void ElementImp::setScrollLeft(int scrollLeft)
{
    // TODO: implement me!
}

int ElementImp::getScrollWidth()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getScrollHeight()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getClientTop()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getClientLeft()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getClientWidth()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getClientHeight()
{
    // TODO: implement me!
    return 0;
}

Element ElementImp::querySelector(std::u16string selectors)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList ElementImp::querySelectorAll(std::u16string selectors)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

ElementImp::ElementImp(ElementImp* org, bool deep) :
    ObjectMixin(org, deep) {
    namespaceURI = org->namespaceURI;
    prefix = org->prefix;
    localName = org->localName;
    for (auto i = org->attributes.begin(); i != org->attributes.end(); ++i) {
        if (Attr attr = new(std::nothrow) AttrImp(*dynamic_cast<AttrImp*>((*i).self())))
            attributes.push_back(attr);
    }
}

}}}}  // org::w3c::dom::bootstrap
<commit_msg>(ElementImp::removeAttribute, ElementImp::removeAttributeNS) : Fix bugs.<commit_after>/*
 * Copyright 2010, 2011 Esrille Inc.
 *
 * 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 "ElementImp.h"

#include <new>

#include "AttrImp.h"
#include "DocumentImp.h"
#include "MutationEventImp.h"
#include "css/CSSSerialize.h"
#include "html/HTMLTokenizer.h"

namespace org { namespace w3c { namespace dom { namespace bootstrap {

class AttrArray : public Object
{
    ElementImp* element;
public:
    virtual unsigned int getLength() {
        return element->attributes.size();
    }
    virtual void setLength(unsigned int length) {
    }
    virtual Attr getElement(unsigned int index) {
        if (element->attributes.size() <= index)
            return 0;
        return element->attributes[index];
    }
    virtual void setElement(unsigned int index, Attr value) {
    }
    // Object
    virtual Any message_(uint32_t selector, const char* id, int argc, Any* argv) {
        return ObjectArray<Attr>::dispatch(this, selector, id, argc, argv);
    }
    AttrArray(ElementImp* element) :
        Object(this),
        element(element) {
    }
};

void ElementImp::setAttributes(const std::deque<Attr>& attributes)
{
    if (this->attributes.empty()) {
        this->attributes = attributes;
        return;
    }
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        setAttributeNS(attr.getNamespaceURI(), attr.getName(), attr.getValue());
    }
}

ElementImp* ElementImp::getNextElement(ElementImp* root)
{
    NodeImp* n = this;
    for (auto i = n->firstChild; i; i = i->nextSibling) {
        if (i->getNodeType() == Node::ELEMENT_NODE)
            return dynamic_cast<ElementImp*>(i);
    }
    while (n != root) {
        while (n->nextSibling) {
            n = n->nextSibling;
            if (n->getNodeType() == Node::ELEMENT_NODE)
                return dynamic_cast<ElementImp*>(n);
        }
        n = n->parentNode;
    }
    return 0;
}

// Node

unsigned short ElementImp::getNodeType()
{
    return Node::ELEMENT_NODE;
}

Node ElementImp::cloneNode(bool deep)
{
    return new(std::nothrow) ElementImp(this, deep);
}

Nullable<std::u16string> ElementImp::getTextContent()
{
    std::u16string content;
    for (Node child = getFirstChild(); child; child = child.getNextSibling()) {
        if (child.getNodeType() == Node::COMMENT_NODE)
            continue;
        Nullable<std::u16string> text = child.getTextContent();
        if (text.hasValue())
            content += text.value();
    }
    return content;
}

void ElementImp::setTextContent(std::u16string textContent)
{
    while (hasChildNodes())
        removeChild(getFirstChild());
    if (0 < textContent.length()) {
        org::w3c::dom::Text text = ownerDocument->createTextNode(textContent);
        appendChild(text);
    }
}

// Element
Nullable<std::u16string> ElementImp::getNamespaceURI()
{
    return namespaceURI;
}

Nullable<std::u16string> ElementImp::getPrefix()
{
    return prefix;
}

std::u16string ElementImp::getLocalName()
{
    return localName;
}

std::u16string ElementImp::getTagName()
{
    if (0 < prefix.length())
        return prefix + u':' + localName;
    return localName;
}

dom::ObjectArray<Attr> ElementImp:: getAttributes()
{
    return new(std::nothrow) AttrArray(this);
}

Nullable<std::u16string> ElementImp::getAttribute(std::u16string name)
{
    // TODO: If the context node is in the HTML namespace and its ownerDocument is an HTML document
        toLower(name);
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getName() == name)
            return attr.getValue();
    }
    return Nullable<std::u16string>();
}

Nullable<std::u16string> ElementImp::getAttributeNS(std::u16string namespaceURI, std::u16string localName)
{
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getNamespaceURI().hasValue() && attr.getNamespaceURI().value() == namespaceURI && attr.getLocalName() == localName)
            return attr.getValue();
    }
    return Nullable<std::u16string>();
}

void ElementImp::setAttribute(std::u16string name, std::u16string value)
{
    // TODO: If qualifiedName does not match the Name production in XML, raise an INVALID_CHARACTER_ERR exception and terminate these steps.
    // TODO: If the context node is in the HTML namespace and its ownerDocument is an HTML document
        toLower(name);
    // TODO: If qualifiedName starts with "xmlns", raise a NAMESPACE_ERR and terminate these steps.
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getName() == name) {
            std::u16string prevValue = attr.getValue();
            attr.setValue(value);

            events::MutationEvent event = new(std::nothrow) MutationEventImp;
            event.initMutationEvent(u"DOMAttrModified",
                                    true, false, attr, prevValue, value, name, events::MutationEvent::MODIFICATION);
            this->dispatchEvent(event);
            return;
        }
    }
    Attr attr = new(std::nothrow) AttrImp(Nullable<std::u16string>(), Nullable<std::u16string>(), name, value);
    if (attr)
        attributes.push_back(attr);
}

void ElementImp::setAttributeNS(std::u16string namespaceURI, std::u16string qualifiedName, std::u16string value)
{
    // TODO:
    // TODO:
    Nullable<std::u16string> prefix;
    std::u16string localName;
    size_t pos = qualifiedName.find(u':');
    if (pos != std::u16string::npos) {
        prefix = qualifiedName.substr(0, pos);
        localName = qualifiedName.substr(pos + 1);
    } else
        localName = qualifiedName;
    if (prefix.hasValue()) {
        if (namespaceURI.length() == 0)
            throw DOMException(DOMException::NAMESPACE_ERR);
        if (prefix.value() == u"xml" && namespaceURI != u"http://www.w3.org/XML/1998/namespace")
            throw DOMException(DOMException::NAMESPACE_ERR);
    }
    if ((qualifiedName == u"xmlns" || prefix.hasValue() && prefix.value() == u"xmlns") &&
        namespaceURI != u"http://www.w3.org/2000/xmlns") {
        throw DOMException(DOMException::NAMESPACE_ERR);
    }
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getNamespaceURI().hasValue() && attr.getNamespaceURI().value() == namespaceURI && attr.getLocalName() == localName) {
            attr.setValue(value);
            // TODO: set prefix, too.
            return;
        }
    }
    Attr attr = new(std::nothrow) AttrImp(namespaceURI, prefix, localName, value);
    if (attr)
        attributes.push_back(attr);
}

void ElementImp::removeAttribute(std::u16string name)
{
    // TODO: If the context node is in the HTML namespace and its ownerDocument is an HTML document
        toLower(name);
    for (auto i = attributes.begin(); i != attributes.end();) {
        Attr attr = *i;
        if (attr.getName() == name)
            i = attributes.erase(i);
        else
            ++i;
    }
}

void ElementImp::removeAttributeNS(std::u16string namespaceURI, std::u16string localName)
{
    for (auto i = attributes.begin(); i != attributes.end();) {
        Attr attr = *i;
        if (attr.getNamespaceURI().hasValue() && attr.getNamespaceURI().value() == namespaceURI && attr.getLocalName() == localName)
            i = attributes.erase(i);
        else
            ++i;
    }
}

bool ElementImp::hasAttribute(std::u16string name)
{
    // TODO: If the context node is in the HTML namespace and its ownerDocument is an HTML document
        toLower(name);
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getName() == name)
            return true;
    }
    return false;
}

bool ElementImp::hasAttributeNS(std::u16string namespaceURI, std::u16string localName)
{
    for (auto i = attributes.begin(); i != attributes.end(); ++i) {
        Attr attr = *i;
        if (attr.getNamespaceURI().hasValue() && attr.getNamespaceURI().value() == namespaceURI && attr.getLocalName() == localName)
            return true;
    }
    return false;
}

html::HTMLCollection ElementImp::getChildren()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList ElementImp::getElementsByTagName(std::u16string qualifiedName)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList ElementImp::getElementsByTagNameNS(std::u16string _namespace, std::u16string localName)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList ElementImp::getElementsByClassName(std::u16string classNames)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

Element ElementImp::getFirstElementChild()
{
    for (NodeImp* n = this->firstChild; n; n = n->nextSibling) {
        if (dynamic_cast<ElementImp*>(n))
            return n;
    }
    return 0;
}

Element ElementImp::getLastElementChild()
{
    for (NodeImp* n = this->lastChild; n; n = n->previousSibling) {
        if (dynamic_cast<ElementImp*>(n))
            return n;
    }
    return 0;
}

Element ElementImp::getPreviousElementSibling()
{
    NodeImp* n = this;
    while (n = n->previousSibling) {
        if (dynamic_cast<ElementImp*>(n))
            return n;
    }
    return 0;
}

Element ElementImp::getNextElementSibling()
{
    NodeImp* n = this;
    while (n = n->nextSibling) {
        if (dynamic_cast<ElementImp*>(n))
            return n;
    }
    return 0;
}

unsigned int ElementImp::getChildElementCount()
{
    unsigned int count = 0;
    for (NodeImp* n = this->firstChild; n; n = n->nextSibling) {
        if (dynamic_cast<ElementImp*>(n))
            ++count;
    }
    return count;
}

views::ClientRectList ElementImp::getClientRects()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

views::ClientRect ElementImp::getBoundingClientRect()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void ElementImp::scrollIntoView(bool top)
{
    // TODO: implement me!
}

int ElementImp::getScrollTop()
{
    // TODO: implement me!
    return 0;
}

void ElementImp::setScrollTop(int scrollTop)
{
    // TODO: implement me!
}

int ElementImp::getScrollLeft()
{
    // TODO: implement me!
    return 0;
}

void ElementImp::setScrollLeft(int scrollLeft)
{
    // TODO: implement me!
}

int ElementImp::getScrollWidth()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getScrollHeight()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getClientTop()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getClientLeft()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getClientWidth()
{
    // TODO: implement me!
    return 0;
}

int ElementImp::getClientHeight()
{
    // TODO: implement me!
    return 0;
}

Element ElementImp::querySelector(std::u16string selectors)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList ElementImp::querySelectorAll(std::u16string selectors)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

ElementImp::ElementImp(ElementImp* org, bool deep) :
    ObjectMixin(org, deep) {
    namespaceURI = org->namespaceURI;
    prefix = org->prefix;
    localName = org->localName;
    for (auto i = org->attributes.begin(); i != org->attributes.end(); ++i) {
        if (Attr attr = new(std::nothrow) AttrImp(*dynamic_cast<AttrImp*>((*i).self())))
            attributes.push_back(attr);
    }
}

}}}}  // org::w3c::dom::bootstrap
<|endoftext|>