<commit_before>#include "SpriteSheet.h"
#include "Utilities/ResourceManager.h"
#include "TinyXML/tinyxml.h"
#include "Logging.h"

namespace Graphics
{

void SpriteSheet::MakeResident ()
{
	glGenTextures(1, &texID);
	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID);
	if (surface->format->BytesPerPixel == 3)
	{
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
					 surface->w, surface->h, 0,
					 GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);
	}
	else
	{
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
					 surface->w, surface->h, 0,
					 GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
	}
}

SpriteSheet::SpriteSheet ( const std::string& name )
: texID(0)
{
	std::string configPath, imagePath;
	if (name[0] == '+')
	{
		configPath = "";
		imagePath = "Images/" + name.substr(1, std::string::npos) + ".png";
	}
	else
	{
		configPath = "Sprites/" + name + ".xml";
		imagePath = "Sprites/" + name + ".png";
	}
	SDL_RWops* configRWOps = ResourceManager::OpenFile(configPath);
	SDL_RWops* imageRWOps = ResourceManager::OpenFile(imagePath);
	if (!imageRWOps)
	{
        // TODO: make this work gracefully
        LOG("Graphics::SpriteSheet", LOG_ERROR, "Failed to load image: %s", name.c_str());
		exit(1);
	}
	surface = IMG_LoadTyped_RW(imageRWOps, 1, const_cast<char*>("PNG"));
	if (configRWOps)
	{
		// load config
		size_t confLength;
		char* confData = (char*)ResourceManager::ReadFull(&confLength, configRWOps, 1);
		TiXmlDocument* xmlDoc = new TiXmlDocument(name + ".xml");
		confData = (char*)realloc(confData, confLength + 1);
		confData[confLength] = '\0';
		xmlDoc->Parse(confData);
		free(confData);
		if (xmlDoc->Error())
		{
            LOG("Graphics::SpriteSheet", LOG_ERROR, "XML error: %s", xmlDoc->ErrorDesc());
			exit(1);
		}
		TiXmlElement* root = xmlDoc->RootElement();
		assert(root);
		TiXmlElement* dimensions = root->FirstChild("dimensions")->ToElement();
		assert(dimensions);
		int rc;
		rc = dimensions->QueryIntAttribute("x", &sheetTilesX);
		assert(rc == TIXML_SUCCESS);
		rc = dimensions->QueryIntAttribute("y", &sheetTilesY);
		assert(rc == TIXML_SUCCESS);
		assert(sheetTilesX > 0);
		assert(sheetTilesY > 0);
		tileSizeX = surface->w / sheetTilesX;
		tileSizeY = surface->h / sheetTilesY;
		if (root->FirstChild("rotational"))
			rotational = true;
		else
			rotational = false;
		delete xmlDoc;
	}
	else
	{
		// assume it's just one sprite
		sheetTilesX = 1;
		sheetTilesY = 1;
		rotational = false;
		tileSizeX = surface->w;
		tileSizeY = surface->h;
	}
}

SpriteSheet::~SpriteSheet ()
{
	if (texID)
		glDeleteTextures(1, &texID);
	SDL_FreeSurface(surface);
}

void SpriteSheet::Draw ( int x, int y, const vec2& size )
{
	vec2 halfSize = size / 2.0f;
	if (texID)
		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID);
	else
		MakeResident();
	float vx = halfSize.X(), vy = halfSize.Y();
	GLfloat vertices[] = { -vx, -vy, vx, -vy, vx, vy, -vx, vy };
	float texBLX, texBLY, texWidth = tileSizeX, texHeight = tileSizeY;
	texBLX = (tileSizeX * x);
	texBLY = (tileSizeY * y);
	GLfloat texCoords[] = { texBLX, texBLY + texHeight,
	                        texBLX + texWidth, texBLY + texHeight,
							texBLX + texWidth, texBLY,
							texBLX, texBLY };
	glVertexPointer(2, GL_FLOAT, 0, vertices);
	glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
	glDrawArrays(GL_QUADS, 0, 4);
}

void SpriteSheet::DrawRotation ( const vec2& size, float angle )
{
	int numObjects = sheetTilesX * sheetTilesY;
	angle -= M_PI / 2.0;
	if (angle < 0.0)
		angle += 2.0*M_PI;
	// angle is now 0 = north, 2π = north, anticlockwise
	angle /= 2.0*M_PI;
	// angle is now 0=north, 1=north, anticlockwise
	angle = 1.0f - angle;
	int index = (int)((angle - 0.00001f) * numObjects) + 1;
	if (index == sheetTilesX * sheetTilesY)
		index = 0;
	int x = index % sheetTilesX;
	int y = (index - x) / sheetTilesX;
	Draw(x, y, size);
}

}
<commit_msg>Slightly adjusted the formula used to determine where the image used in rotational sprites changes.<commit_after>#include "SpriteSheet.h"
#include "Utilities/ResourceManager.h"
#include "TinyXML/tinyxml.h"
#include "Logging.h"

namespace Graphics
{

void SpriteSheet::MakeResident ()
{
	glGenTextures(1, &texID);
	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID);
	if (surface->format->BytesPerPixel == 3)
	{
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
					 surface->w, surface->h, 0,
					 GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);
	}
	else
	{
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
					 surface->w, surface->h, 0,
					 GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
	}
}

SpriteSheet::SpriteSheet ( const std::string& name )
: texID(0)
{
	std::string configPath, imagePath;
	if (name[0] == '+')
	{
		configPath = "";
		imagePath = "Images/" + name.substr(1, std::string::npos) + ".png";
	}
	else
	{
		configPath = "Sprites/" + name + ".xml";
		imagePath = "Sprites/" + name + ".png";
	}
	SDL_RWops* configRWOps = ResourceManager::OpenFile(configPath);
	SDL_RWops* imageRWOps = ResourceManager::OpenFile(imagePath);
	if (!imageRWOps)
	{
        // TODO: make this work gracefully
        LOG("Graphics::SpriteSheet", LOG_ERROR, "Failed to load image: %s", name.c_str());
		exit(1);
	}
	surface = IMG_LoadTyped_RW(imageRWOps, 1, const_cast<char*>("PNG"));
	if (configRWOps)
	{
		// load config
		size_t confLength;
		char* confData = (char*)ResourceManager::ReadFull(&confLength, configRWOps, 1);
		TiXmlDocument* xmlDoc = new TiXmlDocument(name + ".xml");
		confData = (char*)realloc(confData, confLength + 1);
		confData[confLength] = '\0';
		xmlDoc->Parse(confData);
		free(confData);
		if (xmlDoc->Error())
		{
            LOG("Graphics::SpriteSheet", LOG_ERROR, "XML error: %s", xmlDoc->ErrorDesc());
			exit(1);
		}
		TiXmlElement* root = xmlDoc->RootElement();
		assert(root);
		TiXmlElement* dimensions = root->FirstChild("dimensions")->ToElement();
		assert(dimensions);
		int rc;
		rc = dimensions->QueryIntAttribute("x", &sheetTilesX);
		assert(rc == TIXML_SUCCESS);
		rc = dimensions->QueryIntAttribute("y", &sheetTilesY);
		assert(rc == TIXML_SUCCESS);
		assert(sheetTilesX > 0);
		assert(sheetTilesY > 0);
		tileSizeX = surface->w / sheetTilesX;
		tileSizeY = surface->h / sheetTilesY;
		if (root->FirstChild("rotational"))
			rotational = true;
		else
			rotational = false;
		delete xmlDoc;
	}
	else
	{
		// assume it's just one sprite
		sheetTilesX = 1;
		sheetTilesY = 1;
		rotational = false;
		tileSizeX = surface->w;
		tileSizeY = surface->h;
	}
}

SpriteSheet::~SpriteSheet ()
{
	if (texID)
		glDeleteTextures(1, &texID);
	SDL_FreeSurface(surface);
}

void SpriteSheet::Draw ( int x, int y, const vec2& size )
{
	vec2 halfSize = size / 2.0f;
	if (texID)
		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID);
	else
		MakeResident();
	float vx = halfSize.X(), vy = halfSize.Y();
	GLfloat vertices[] = { -vx, -vy, vx, -vy, vx, vy, -vx, vy };
	float texBLX, texBLY, texWidth = tileSizeX, texHeight = tileSizeY;
	texBLX = (tileSizeX * x);
	texBLY = (tileSizeY * y);
	GLfloat texCoords[] = { texBLX, texBLY + texHeight,
	                        texBLX + texWidth, texBLY + texHeight,
							texBLX + texWidth, texBLY,
							texBLX, texBLY };
	glVertexPointer(2, GL_FLOAT, 0, vertices);
	glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
	glDrawArrays(GL_QUADS, 0, 4);
}

void SpriteSheet::DrawRotation ( const vec2& size, float angle )
{
	int numObjects = sheetTilesX * sheetTilesY;
	angle += (M_PI / float(numObjects));
	angle -= M_PI / 2.0;
	if (angle < 0.0)
		angle += 2.0*M_PI;
	// angle is now 0 = north, 2π = north, anticlockwise
	angle /= 2.0*M_PI;
	// angle is now 0=north, 1=north, anticlockwise
	angle = 1.0f - angle;
	int index = (int)((angle - 0.00001f) * numObjects) + 1;
	if (index == sheetTilesX * sheetTilesY)
		index = 0;
	int x = index % sheetTilesX;
	int y = (index - x) / sheetTilesX;
	Draw(x, y, size);
}

}
<|endoftext|>


<commit_before>#include <iostream>

#include "BinaryTree.hpp"

using namespace std;

int main(int argc, char **argv)
{
    Lista<int> pre, in, post;

    pre.insertar(10,1);
    pre.insertar(20,2);
    pre.insertar(40,3);
    pre.insertar(80,4);
    pre.insertar(50,5);
    pre.insertar(90,6);
    pre.insertar(30,7);
    pre.insertar(60,8);
    pre.insertar(70,9);
    pre.insertar(100,10);
    pre.insertar(110,11);
    pre.insertar(120,12);

    in.insertar(80,1);
    in.insertar(40,2);
    in.insertar(20,3);
    in.insertar(50,4);
    in.insertar(90,5);
    in.insertar(10,6);
    in.insertar(60,7);
    in.insertar(30,8);
    in.insertar(100,9);
    in.insertar(70,10);
    in.insertar(110,11);
    in.insertar(120,12);

    post.insertar(80,1);
    post.insertar(40,2);
    post.insertar(90,3);
    post.insertar(50,4);
    post.insertar(20,5);
    post.insertar(60,6);
    post.insertar(100,7);
    post.insertar(120,8);
    post.insertar(110,9);
    post.insertar(70,10);
    post.insertar(30,11);
    post.insertar(10,12);

    BinaryTree<int> tree(pre, in, preorden);
    cout << tree.isNull() << endl;

    BinaryTree<int> tree2;

    cout << tree2.isNull() << endl;

    tree2 = tree.getRight();
    cout << tree2.isNull() << endl;

    tree2.print(preorden);

    tree.destroy();
    tree2.destroy();

    tree2.print(preorden);
    cout << tree.isNull() << endl;
    cout << tree2.isNull() << endl;

    return 0;
}

<commit_msg>Testing BST<commit_after>#include <iostream>
#include "BinaryTree.hpp"
#include "BST.hpp"

using namespace std;

int main(int argc, char **argv)
{
    BST<int> arbol;

    arbol.insert(4);
    arbol.insert(2);
    arbol.insert(6);
    arbol.insert(1);
    arbol.insert(3);
    arbol.insert(5);

    arbol.print(preorden);

    return 0;
}

<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions 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 <memory>
#include <boost/thread.hpp>

#include "SurgSim/Blocks/BasicSceneElement.h"
#include "SurgSim/Blocks/TransferDeformableStateToVerticesBehavior.h"
#include "SurgSim/Framework/Behavior.h"
#include "SurgSim/Framework/BehaviorManager.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"
#include "SurgSim/Framework/SceneElement.h"
#include "SurgSim/Graphics/OsgCamera.h"
#include "SurgSim/Graphics/OsgManager.h"
#include "SurgSim/Graphics/OsgPointCloudRepresentation.h"
#include "SurgSim/Graphics/OsgView.h"
#include "SurgSim/Graphics/OsgViewElement.h"
#include "SurgSim/Graphics/PointCloudRepresentation.h"
#include "SurgSim/Math/Quaternion.h"
#include "SurgSim/Math/RigidTransform.h"
#include "SurgSim/Math/Vector.h"
#include "SurgSim/Physics/Fem1DRepresentation.h"
#include "SurgSim/Physics/FemElement1DBeam.h"
#include "SurgSim/Physics/PhysicsManager.h"

using SurgSim::Blocks::BasicSceneElement;
using SurgSim::Blocks::TransferDeformableStateToVerticesBehavior;
using SurgSim::Framework::Logger;
using SurgSim::Framework::SceneElement;
using SurgSim::Graphics::OsgPointCloudRepresentation;
using SurgSim::Math::Vector3d;
using SurgSim::Math::Vector4f;
using SurgSim::Physics::DeformableRepresentationState;
using SurgSim::Physics::Fem1DRepresentation;
using SurgSim::Physics::FemElement1DBeam;
using SurgSim::Physics::PhysicsManager;

///\file Example of how to put together a very simple demo of Fem1D

namespace
{

void loadModelFem1D(std::shared_ptr<Fem1DRepresentation> physicsRepresentation, unsigned int numNodes)
{
	std::shared_ptr<DeformableRepresentationState> restState = std::make_shared<DeformableRepresentationState>();
	restState->setNumDof(physicsRepresentation->getNumDofPerNode(), numNodes);

	// Sets the initial state (node positions and boundary conditions)
	SurgSim::Math::Vector& x = restState->getPositions();
	for (unsigned int nodeId = 0; nodeId < numNodes; nodeId++)
	{
		SurgSim::Math::getSubVector(x, nodeId, physicsRepresentation->getNumDofPerNode()).segment<3>(0)
			= Vector3d(static_cast<double>(nodeId) / static_cast<double>(numNodes), 0.0, 0.0);
	}

	restState->addBoundaryCondition(0 + 0);
	restState->addBoundaryCondition(0 + 1);
	restState->addBoundaryCondition(0 + 2);
	restState->addBoundaryCondition((numNodes - 1) * physicsRepresentation->getNumDofPerNode() + 0);
	restState->addBoundaryCondition((numNodes - 1) * physicsRepresentation->getNumDofPerNode() + 1);
	restState->addBoundaryCondition((numNodes - 1) * physicsRepresentation->getNumDofPerNode() + 2);

	physicsRepresentation->setInitialState(restState);

	// Adds all the FemElements
	for (unsigned int beamId = 0; beamId < numNodes - 1; beamId++)
	{
		std::array<unsigned int, 2> beamNodeIds = {{beamId, beamId + 1}};
		std::shared_ptr<FemElement1DBeam> beam = std::make_shared<FemElement1DBeam>(beamNodeIds, *restState);
		beam->setCrossSectionCircular(0.10);
		beam->setMassDensity(3000.0);
		beam->setPoissonRatio(0.45);
		beam->setYoungModulus(1e6);
		physicsRepresentation->addFemElement(beam);
	}
}

std::shared_ptr<SurgSim::Graphics::ViewElement> createView(const std::string& name, int x, int y, int width, int height)
{
	using SurgSim::Graphics::OsgViewElement;

	std::shared_ptr<OsgViewElement> viewElement = std::make_shared<OsgViewElement>(name);
	viewElement->getView()->setPosition(x, y);
	viewElement->getView()->setDimensions(width, height);

	return viewElement;
}

std::shared_ptr<SceneElement> createFem1D(const std::string& name,
										  const std::vector<SurgSim::Math::RigidTransform3d> gfxPoses,
										  SurgSim::Math::Vector4d color,
										  SurgSim::Math::IntegrationScheme integrationScheme)
{
	std::shared_ptr<Fem1DRepresentation> physicsRepresentation
		= std::make_shared<Fem1DRepresentation>(name + " Physics");

	// In this example, the physics representations are not transformed, only the graphics will be transformed
	loadModelFem1D(physicsRepresentation, 10);

	physicsRepresentation->setIntegrationScheme(integrationScheme);
	physicsRepresentation->setRayleighDampingMass(5e-2);
	physicsRepresentation->setRayleighDampingStiffness(5e-3);

	std::shared_ptr<BasicSceneElement> femSceneElement = std::make_shared<BasicSceneElement>(name);
	femSceneElement->addComponent(physicsRepresentation);

	unsigned int gfxObjectId = 0;
	for (std::vector<SurgSim::Math::RigidTransform3d>::const_iterator gfxPose = gfxPoses.begin();
		 gfxPose != gfxPoses.end(); ++gfxPose)
	{
		std::stringstream ss;
		ss << name + " Graphics object " << gfxObjectId;

		std::shared_ptr<SurgSim::Graphics::PointCloudRepresentation<void>> graphicsRepresentation
			= std::make_shared<OsgPointCloudRepresentation<void>>(ss.str());
		graphicsRepresentation->setInitialPose(*gfxPose);
		graphicsRepresentation->setColor(color);
		graphicsRepresentation->setPointSize(3.0f);
		graphicsRepresentation->setVisible(true);

		femSceneElement->addComponent(graphicsRepresentation);

		ss.clear();
		ss << "Physics to Graphics (" << gfxObjectId << ") deformable points";

		femSceneElement->addComponent(
			std::make_shared<TransferDeformableStateToVerticesBehavior<void>>(
				ss.str(), physicsRepresentation->getFinalState(), graphicsRepresentation->getVertices())
			);

		gfxObjectId++;
	}

	return femSceneElement;
}

} // anonymous namespace

int main(int argc, char* argv[])
{
	using SurgSim::Math::makeRigidTransform;
	using SurgSim::Math::Vector4d;

	std::shared_ptr<SurgSim::Graphics::OsgManager> graphicsManager = std::make_shared<SurgSim::Graphics::OsgManager>();
	std::shared_ptr<PhysicsManager> physicsManager = std::make_shared<PhysicsManager>();
	std::shared_ptr<SurgSim::Framework::BehaviorManager> behaviorManager
		= std::make_shared<SurgSim::Framework::BehaviorManager>();
	std::shared_ptr<SurgSim::Framework::Runtime> runtime = std::make_shared<SurgSim::Framework::Runtime>();

	runtime->addManager(physicsManager);
	runtime->addManager(graphicsManager);
	runtime->addManager(behaviorManager);

	std::shared_ptr<SurgSim::Graphics::OsgCamera> camera = graphicsManager->getDefaultCamera();
	std::shared_ptr<SurgSim::Framework::Scene> scene = runtime->getScene();

	SurgSim::Math::Quaterniond qIdentity = SurgSim::Math::Quaterniond::Identity();
	SurgSim::Math::Vector3d translate(0, 0, -3);
	SurgSim::Math::IntegrationScheme integrationScheme = SurgSim::Math::INTEGRATIONSCHEME_EXPLICIT_EULER;
	{
		std::vector<SurgSim::Math::RigidTransform3d> gfxPoses;

		gfxPoses.push_back(makeRigidTransform(qIdentity, translate + Vector3d(-3.0, 0.5, 0.0)));
		gfxPoses.push_back(makeRigidTransform(qIdentity, translate + Vector3d( 3.0, 0.5, 0.0)));
		scene->addSceneElement(createFem1D("Euler Explicit", gfxPoses, Vector4d(1, 0, 0, 1), integrationScheme));

		gfxPoses.clear();
		gfxPoses.push_back(makeRigidTransform(qIdentity, translate + Vector3d(-1.0, 0.5, 0.0)));
		gfxPoses.push_back(makeRigidTransform(qIdentity, translate + Vector3d( 3.0, 0.5, 0.0)));
		scene->addSceneElement(
			createFem1D("Modified Euler Explicit", gfxPoses, Vector4d(0, 1, 0, 1), integrationScheme));

		gfxPoses.clear();
		gfxPoses.push_back(makeRigidTransform(qIdentity, translate + Vector3d( 1.0, 0.5, 0.0)));
		gfxPoses.push_back(makeRigidTransform(qIdentity, translate + Vector3d( 3.0, 0.5, 0.0)));
		scene->addSceneElement(createFem1D("Euler Implicit", gfxPoses, Vector4d(0, 0, 1, 1), integrationScheme));
	}

	scene->addSceneElement(createView("view1", 0, 0, 1023, 768));

	camera->setInitialPose(SurgSim::Math::makeRigidTransform(qIdentity, Vector3d(0.0, 0.5, 5.0)));

	runtime->execute();

	return 0;
}
<commit_msg>Update fem1d example, various fixes<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions 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 <memory>
#include <boost/thread.hpp>

#include "SurgSim/Blocks/BasicSceneElement.h"
#include "SurgSim/Blocks/TransferDeformableStateToVerticesBehavior.h"
#include "SurgSim/Framework/Behavior.h"
#include "SurgSim/Framework/BehaviorManager.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"
#include "SurgSim/Framework/SceneElement.h"
#include "SurgSim/Graphics/OsgCamera.h"
#include "SurgSim/Graphics/OsgManager.h"
#include "SurgSim/Graphics/OsgPointCloudRepresentation.h"
#include "SurgSim/Graphics/OsgView.h"
#include "SurgSim/Graphics/OsgViewElement.h"
#include "SurgSim/Graphics/PointCloudRepresentation.h"
#include "SurgSim/Math/Quaternion.h"
#include "SurgSim/Math/RigidTransform.h"
#include "SurgSim/Math/Vector.h"
#include "SurgSim/Physics/Fem1DRepresentation.h"
#include "SurgSim/Physics/FemElement1DBeam.h"
#include "SurgSim/Physics/PhysicsManager.h"

using SurgSim::Blocks::BasicSceneElement;
using SurgSim::Blocks::TransferDeformableStateToVerticesBehavior;
using SurgSim::Framework::Logger;
using SurgSim::Framework::SceneElement;
using SurgSim::Graphics::OsgPointCloudRepresentation;
using SurgSim::Math::Vector3d;
using SurgSim::Math::Vector4f;
using SurgSim::Physics::DeformableRepresentationState;
using SurgSim::Physics::Fem1DRepresentation;
using SurgSim::Physics::FemElement1DBeam;
using SurgSim::Physics::PhysicsManager;

///\file Example of how to put together a very simple demo of Fem1D

namespace
{

void loadModelFem1D(std::shared_ptr<Fem1DRepresentation> physicsRepresentation, unsigned int numNodes)
{
	std::shared_ptr<DeformableRepresentationState> restState = std::make_shared<DeformableRepresentationState>();
	restState->setNumDof(physicsRepresentation->getNumDofPerNode(), numNodes);

	// Sets the initial state (node positions and boundary conditions)
	SurgSim::Math::Vector& x = restState->getPositions();
	for (unsigned int nodeId = 0; nodeId < numNodes; nodeId++)
	{
		SurgSim::Math::getSubVector(x, nodeId, physicsRepresentation->getNumDofPerNode()).segment<3>(0)
			= Vector3d(static_cast<double>(nodeId) / static_cast<double>(numNodes), 0.0, 0.0);
	}

	restState->addBoundaryCondition(0 + 0);
	restState->addBoundaryCondition(0 + 1);
	restState->addBoundaryCondition(0 + 2);
	restState->addBoundaryCondition((numNodes - 1) * physicsRepresentation->getNumDofPerNode() + 0);
	restState->addBoundaryCondition((numNodes - 1) * physicsRepresentation->getNumDofPerNode() + 1);
	restState->addBoundaryCondition((numNodes - 1) * physicsRepresentation->getNumDofPerNode() + 2);

	physicsRepresentation->setInitialState(restState);

	// Adds all the FemElements
	for (unsigned int beamId = 0; beamId < numNodes - 1; beamId++)
	{
		std::array<unsigned int, 2> beamNodeIds = {{beamId, beamId + 1}};
		std::shared_ptr<FemElement1DBeam> beam = std::make_shared<FemElement1DBeam>(beamNodeIds, *restState);
		beam->setCrossSectionCircular(0.10);
		beam->setMassDensity(3000.0);
		beam->setPoissonRatio(0.45);
		beam->setYoungModulus(1e6);
		physicsRepresentation->addFemElement(beam);
	}
}

std::shared_ptr<SurgSim::Graphics::ViewElement> createView(const std::string& name, int x, int y, int width, int height)
{
	using SurgSim::Graphics::OsgViewElement;

	std::shared_ptr<OsgViewElement> viewElement = std::make_shared<OsgViewElement>(name);
	viewElement->getView()->setPosition(x, y);
	viewElement->getView()->setDimensions(width, height);

	return viewElement;
}

// Generates a 1d fem comprised of adjacent elements along a straight line.  The number of fem elements is determined
// by loadModelFem1D.  The gfxPoses parameter can be used to create multiple identical fems with different intial
// locations.
std::shared_ptr<SceneElement> createFem1D(const std::string& name,
										  const std::vector<SurgSim::Math::RigidTransform3d> gfxPoses,
										  SurgSim::Math::Vector4d color,
										  SurgSim::Math::IntegrationScheme integrationScheme)
{
	std::shared_ptr<Fem1DRepresentation> physicsRepresentation
		= std::make_shared<Fem1DRepresentation>(name + " Physics");

	// In this example, the physics representations are not transformed, only the graphics will be transformed
	loadModelFem1D(physicsRepresentation, 10);

	physicsRepresentation->setIntegrationScheme(integrationScheme);
	physicsRepresentation->setRayleighDampingMass(5e-2);
	physicsRepresentation->setRayleighDampingStiffness(5e-3);

	std::shared_ptr<BasicSceneElement> femSceneElement = std::make_shared<BasicSceneElement>(name);
	femSceneElement->addComponent(physicsRepresentation);

	unsigned int gfxObjectId = 0;
	std::stringstream ss;
	for (std::vector<SurgSim::Math::RigidTransform3d>::const_iterator gfxPose = gfxPoses.begin();
		 gfxPose != gfxPoses.end(); ++gfxPose)
	{
		ss.clear();
		ss << name << " Graphics object " << gfxObjectId;

		std::shared_ptr<SurgSim::Graphics::PointCloudRepresentation<void>> graphicsRepresentation
			= std::make_shared<OsgPointCloudRepresentation<void>>(ss.str());
		graphicsRepresentation->setInitialPose(*gfxPose);
		graphicsRepresentation->setColor(color);
		graphicsRepresentation->setPointSize(3.0f);
		graphicsRepresentation->setVisible(true);

		femSceneElement->addComponent(graphicsRepresentation);

		ss.clear();
		ss << "Physics to Graphics (" << gfxObjectId << ") deformable points";

		femSceneElement->addComponent(
			std::make_shared<TransferDeformableStateToVerticesBehavior<void>>(
				ss.str(), physicsRepresentation->getFinalState(), graphicsRepresentation->getVertices())
			);

		gfxObjectId++;
	}

	return femSceneElement;
}

} // anonymous namespace

int main(int argc, char* argv[])
{
	using SurgSim::Math::makeRigidTransform;
	using SurgSim::Math::Vector4d;

	std::shared_ptr<SurgSim::Graphics::OsgManager> graphicsManager = std::make_shared<SurgSim::Graphics::OsgManager>();
	std::shared_ptr<PhysicsManager> physicsManager = std::make_shared<PhysicsManager>();
	std::shared_ptr<SurgSim::Framework::BehaviorManager> behaviorManager
		= std::make_shared<SurgSim::Framework::BehaviorManager>();
	std::shared_ptr<SurgSim::Framework::Runtime> runtime = std::make_shared<SurgSim::Framework::Runtime>();

	runtime->addManager(physicsManager);
	runtime->addManager(graphicsManager);
	runtime->addManager(behaviorManager);

	std::shared_ptr<SurgSim::Graphics::OsgCamera> camera = graphicsManager->getDefaultCamera();
	std::shared_ptr<SurgSim::Framework::Scene> scene = runtime->getScene();

	const SurgSim::Math::Quaterniond quaternionIdentity = SurgSim::Math::Quaterniond::Identity();
	SurgSim::Math::Vector3d translate(0, 0, -3);

	std::vector<SurgSim::Math::RigidTransform3d> gfxPoses;
	gfxPoses.push_back(makeRigidTransform(quaternionIdentity, translate + Vector3d(-3.5, 0.5, 0.0)));
	scene->addSceneElement(
		createFem1D("Euler Explicit", gfxPoses, Vector4d(1, 0, 0, 1), SurgSim::Math::INTEGRATIONSCHEME_EXPLICIT_EULER));

	gfxPoses.clear();
	gfxPoses.push_back(makeRigidTransform(quaternionIdentity, translate + Vector3d(-0.5, 0.5, 0.0)));
	scene->addSceneElement(createFem1D("Modified Euler Explicit", gfxPoses, Vector4d(0, 1, 0, 1),
									   SurgSim::Math::INTEGRATIONSCHEME_MODIFIED_EXPLICIT_EULER));

	gfxPoses.clear();
	gfxPoses.push_back(makeRigidTransform(quaternionIdentity, translate + Vector3d(2.5, 0.5, 0.0)));
	scene->addSceneElement(
		createFem1D("Euler Implicit", gfxPoses, Vector4d(0, 0, 1, 1), SurgSim::Math::INTEGRATIONSCHEME_IMPLICIT_EULER));

	scene->addSceneElement(createView("view1", 0, 0, 1023, 768));

	camera->setInitialPose(SurgSim::Math::makeRigidTransform(quaternionIdentity, Vector3d(0.0, 0.5, 5.0)));

	runtime->execute();

	return 0;
}
<|endoftext|>


<commit_before>/*
 *  FFissionCodec.cpp
 *
 *  Copyright (c) 2006  David Conrad
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation;
 *  version 2.1 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

extern "C" {
#include "avcodec.h"
}
#include "FFissionCodec.h"

extern "C" void initLib();

FFissionCodec::FFissionCodec(UInt32 inInputBufferByteSize) : ACSimpleCodec(inInputBufferByteSize)
{
	initLib();

	avContext = avcodec_alloc_context();
	avCodec = NULL;
}

FFissionCodec::~FFissionCodec()
{
	if (avContext) {
		if (avCodec) {
			avcodec_close(avContext);
		}

		av_free(avContext);
	}
}

void FFissionCodec::Initialize(const AudioStreamBasicDescription* inInputFormat,
							   const AudioStreamBasicDescription* inOutputFormat,
							   const void* inMagicCookie, UInt32 inMagicCookieByteSize)
{
	//	use the given arguments, if necessary
	if (inInputFormat != NULL)
	{
		SetCurrentInputFormat(*inInputFormat);
	}

	if (inOutputFormat != NULL)
	{
		SetCurrentOutputFormat(*inOutputFormat);
	}

	//	make sure the sample rate and number of channels match between the input format and the output format

	if ((mInputFormat.mSampleRate != mOutputFormat.mSampleRate) ||
		(mInputFormat.mChannelsPerFrame != mOutputFormat.mChannelsPerFrame))
	{
		CODEC_THROW(kAudioCodecUnsupportedFormatError);
	}

	ACSimpleCodec::Initialize(inInputFormat, inOutputFormat, inMagicCookie, inMagicCookieByteSize);
}

void FFissionCodec::GetPropertyInfo(AudioCodecPropertyID inPropertyID, UInt32& outPropertyDataSize, bool& outWritable) {
	switch(inPropertyID)
	{
		case kAudioCodecPropertyMaximumPacketByteSize:
			outPropertyDataSize = sizeof(UInt32);
			outWritable = false;
			break;

		case kAudioCodecPropertyHasVariablePacketByteSizes:
			outPropertyDataSize = sizeof(UInt32);
			outWritable = false;
			break;

		case kAudioCodecPropertyPacketFrameSize:
			outPropertyDataSize = sizeof(UInt32);
			outWritable = false;
			break;

		default:
			ACSimpleCodec::GetPropertyInfo(inPropertyID, outPropertyDataSize, outWritable);
			break;
	}
}

void FFissionCodec::GetProperty(AudioCodecPropertyID inPropertyID, UInt32& ioPropertyDataSize, void* outPropertyData)
{
	switch(inPropertyID) {
		case kAudioCodecPropertyManufacturerCFString:
			if (ioPropertyDataSize != sizeof(CFStringRef))
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			break;

		case kAudioCodecPropertyMaximumPacketByteSize:
		case kAudioCodecPropertyRequiresPacketDescription:
		case kAudioCodecPropertyHasVariablePacketByteSizes:
		case kAudioCodecPropertyPacketFrameSize:
			if(ioPropertyDataSize != sizeof(UInt32))
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			break;
	}

	switch (inPropertyID) {
		case kAudioCodecPropertyManufacturerCFString:
			CFStringRef name = CFCopyLocalizedStringFromTableInBundle(CFSTR("Perian Project"), CFSTR("CodecNames"), GetCodecBundle(), CFSTR(""));
			*(CFStringRef*)outPropertyData = name;
			break;

		case kAudioCodecPropertyMaximumPacketByteSize:
			if (avContext)
				*reinterpret_cast<UInt32*>(outPropertyData) = avContext->block_align;
			else
				*reinterpret_cast<UInt32*>(outPropertyData) = mInputFormat.mBytesPerPacket;
			break;

		case kAudioCodecPropertyRequiresPacketDescription:
			*reinterpret_cast<UInt32*>(outPropertyData) = false;
			break;

		case kAudioCodecPropertyHasVariablePacketByteSizes:
			*reinterpret_cast<UInt32*>(outPropertyData) = false;
			break;

		case kAudioCodecPropertyPacketFrameSize:
			if (avContext)
				*reinterpret_cast<UInt32*>(outPropertyData) = avContext->frame_size;
			else
				*reinterpret_cast<UInt32*>(outPropertyData) = mInputFormat.mFramesPerPacket;
			break;

		default:
			ACSimpleCodec::GetProperty(inPropertyID, ioPropertyDataSize, outPropertyData);
	}
}
<commit_msg>Avoid returning 0 for kAudioCodecPropertyPacketFrameSize as this can crash on Intel.<commit_after>/*
 *  FFissionCodec.cpp
 *
 *  Copyright (c) 2006  David Conrad
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation;
 *  version 2.1 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

extern "C" {
#include "avcodec.h"
}
#include "FFissionCodec.h"

extern "C" void initLib();

FFissionCodec::FFissionCodec(UInt32 inInputBufferByteSize) : ACSimpleCodec(inInputBufferByteSize)
{
	initLib();

	avContext = avcodec_alloc_context();
	avCodec = NULL;
}

FFissionCodec::~FFissionCodec()
{
	if (avContext) {
		if (avCodec) {
			avcodec_close(avContext);
		}

		av_free(avContext);
	}
}

void FFissionCodec::Initialize(const AudioStreamBasicDescription* inInputFormat,
							   const AudioStreamBasicDescription* inOutputFormat,
							   const void* inMagicCookie, UInt32 inMagicCookieByteSize)
{
	//	use the given arguments, if necessary
	if (inInputFormat != NULL)
	{
		SetCurrentInputFormat(*inInputFormat);
	}

	if (inOutputFormat != NULL)
	{
		SetCurrentOutputFormat(*inOutputFormat);
	}

	//	make sure the sample rate and number of channels match between the input format and the output format

	if ((mInputFormat.mSampleRate != mOutputFormat.mSampleRate) ||
		(mInputFormat.mChannelsPerFrame != mOutputFormat.mChannelsPerFrame))
	{
		CODEC_THROW(kAudioCodecUnsupportedFormatError);
	}

	ACSimpleCodec::Initialize(inInputFormat, inOutputFormat, inMagicCookie, inMagicCookieByteSize);
}

void FFissionCodec::GetPropertyInfo(AudioCodecPropertyID inPropertyID, UInt32& outPropertyDataSize, bool& outWritable) {
	switch(inPropertyID)
	{
		case kAudioCodecPropertyMaximumPacketByteSize:
			outPropertyDataSize = sizeof(UInt32);
			outWritable = false;
			break;

		case kAudioCodecPropertyHasVariablePacketByteSizes:
			outPropertyDataSize = sizeof(UInt32);
			outWritable = false;
			break;

		case kAudioCodecPropertyPacketFrameSize:
			outPropertyDataSize = sizeof(UInt32);
			outWritable = false;
			break;

		default:
			ACSimpleCodec::GetPropertyInfo(inPropertyID, outPropertyDataSize, outWritable);
			break;
	}
}

void FFissionCodec::GetProperty(AudioCodecPropertyID inPropertyID, UInt32& ioPropertyDataSize, void* outPropertyData)
{
	switch(inPropertyID) {
		case kAudioCodecPropertyManufacturerCFString:
			if (ioPropertyDataSize != sizeof(CFStringRef))
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			break;

		case kAudioCodecPropertyMaximumPacketByteSize:
		case kAudioCodecPropertyRequiresPacketDescription:
		case kAudioCodecPropertyHasVariablePacketByteSizes:
		case kAudioCodecPropertyPacketFrameSize:
			if(ioPropertyDataSize != sizeof(UInt32))
				CODEC_THROW(kAudioCodecBadPropertySizeError);
			break;
	}

	switch (inPropertyID) {
		case kAudioCodecPropertyManufacturerCFString:
			CFStringRef name = CFCopyLocalizedStringFromTableInBundle(CFSTR("Perian Project"), CFSTR("CodecNames"), GetCodecBundle(), CFSTR(""));
			*(CFStringRef*)outPropertyData = name;
			break;

		case kAudioCodecPropertyMaximumPacketByteSize:
			if (avContext)
				*reinterpret_cast<UInt32*>(outPropertyData) = avContext->block_align;
			else
				*reinterpret_cast<UInt32*>(outPropertyData) = mInputFormat.mBytesPerPacket;
			break;

		case kAudioCodecPropertyRequiresPacketDescription:
			*reinterpret_cast<UInt32*>(outPropertyData) = false;
			break;

		case kAudioCodecPropertyHasVariablePacketByteSizes:
			*reinterpret_cast<UInt32*>(outPropertyData) = false;
			break;

		case kAudioCodecPropertyPacketFrameSize:
			if (avContext && avContext->frame_size)
				*reinterpret_cast<UInt32*>(outPropertyData) = avContext->frame_size;
			else if (mInputFormat.mFramesPerPacket)
				*reinterpret_cast<UInt32*>(outPropertyData) = mInputFormat.mFramesPerPacket;
			else
				// not perfect but returning 0 can crash on intel
				*reinterpret_cast<UInt32*>(outPropertyData) = 1;
			break;

		default:
			ACSimpleCodec::GetProperty(inPropertyID, ioPropertyDataSize, outPropertyData);
	}
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>

int main()
{
    float fl,big;
    scanf("%f",&fl);
    big=fl;
    scanf("\n%f",&fl);
    if(big<fl)big=fl;
    scanf("\n%f",&fl);
    if(big<fl)big=fl;
    printf("%f.1",big);
    return 0;
}
<commit_msg>Update 02_BIGESTFLOAT_16TASK.C<commit_after>#include <stdio.h>
#include <stdlib.h>

int main()
{
    float fl,big;
    scanf("%f",&fl);
    big=fl;
    scanf("\n%f",&fl);
    if(big<fl)big=fl;
    scanf("\n%f",&fl);
    if(big<fl)big=fl;
    printf("%0.1f",big);
    return 0;
}
<|endoftext|>


<commit_before><commit_msg>HTCONDOR-1080: Better Error message logic<commit_after><|endoftext|>


<commit_before>#include <cstdint>
#include <iostream>

using std::cout;
/*
struct EightBools
{
  bool one;
  bool two;
  bool three;
  bool four;
  bool five;
  bool six;
  bool seven;
  bool eight;
};

struct DanglingEnd
{
  uint32_t first;
  uint8_t end;
};
struct Sandwich
{
  uint32_t first;
  uint8_t middle;
  uint32_t end;
};

*/
int main()
{
  cout << "data layout study start" << '\n';
  //cout << "size of eight bools = " << sizeof(EightBools) << '\n';
  //cout << "size of dangling end = " << sizeof(DanglingEnd) << '\n';
  //cout << "size of sandwich= " << sizeof(Sandwich) << '\n';
  cout << "data layout study end" << '\n';
  return EXIT_SUCCESS;
}

<commit_msg>updated output<commit_after>#include <cstdint>
#include <iostream>

using std::cout;

struct EightBools
{
  bool one;
  bool two;
  bool three;
  bool four;
  bool five;
  bool six;
  bool seven;
  bool eight;
};

struct DanglingEnd
{
  uint32_t first;
  uint8_t end;
};
struct Sandwich
{
  uint32_t first;
  uint8_t middle;
  uint32_t end;
};

int main()
{
  cout << "data layout study start" << '\n';
  cout << "size of eight bools = " << sizeof(EightBools) << '\n';
  cout << "size of dangling end = " << sizeof(DanglingEnd) << '\n';
  cout << "size of sandwich= " << sizeof(Sandwich) << '\n';
  cout << "data layout study end" << '\n';
  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before><commit_msg>src/File/AbcInput.hxx : Improved doc.<commit_after><|endoftext|>


<commit_before><commit_msg>simplify custom formatters even more<commit_after><|endoftext|>


<commit_before><commit_msg>For longer running sleeps, use check_until done to make quitting faster.<commit_after><|endoftext|>


<commit_before><commit_msg>applied C++ exception to string type check<commit_after><|endoftext|>


<commit_before>/*
    Binary search:
    A search algorithm that finds the position of a target value
    within a sorted array
*/

#include <iostream>
#include <vector>

using namespace std;

int binarySearch(const int value, const vector<int>& sortedVect, const int low, const int high) {
    int mid = (low + high) / 2;

    if (value == sortedVect[mid])
        return mid;
    else if (low <= high) {
        if (value < sortedVect[mid]) {
            // value must be between indices low and mid-1, if exists
            return binarySearch(value, sortedVect, low, mid-1);
        }
        else if (value > sortedVect[mid]) {
            // value must be between indices mid-1 and high, if exists
            return binarySearch(value, sortedVect, mid+1, high);
        }
    }

    return -1;
}

int main() {
    int value;
    cout << "Enter the value to search for : ";
    cin >> value;

    int size;
    cout << "Enter the input size : ";
    cin >> size;

    vector<int> inputVect(size);    // supposedly sorted values
    cout << "Enter " << size << " integers in ascending order :\n";
    for (int& val: inputVect)
        cin >> val;

    int index = binarySearch(value, inputVect, 0, size-1);
    cout << "\n";
    if (index != -1)
        cout << "Found " << value << " at position " << (index + 1) << "\n";
    else
        cout << "Either " << value << " is not present among the input values, or the values aren\'t sorted\n";

    return 0;
}
<commit_msg>Add time and space complexities for binary search<commit_after>/*
    Binary Search
    -----------
    A searching algorithm that finds the position of a target value
    within a sorted array.

    Time complexity
    ---------------
    O(log(N)), where N is the number of elements in the array.

    Space complexity
    ----------------
    O(1).
*/

#include <iostream>
#include <vector>

using namespace std;

int binarySearch(const int value, const vector<int>& sortedVect, const int low, const int high) {
    int mid = (low + high) / 2;

    if (value == sortedVect[mid])
        return mid;
    else if (low <= high) {
        if (value < sortedVect[mid]) {
            // value must be between indices low and mid-1, if exists
            return binarySearch(value, sortedVect, low, mid-1);
        }
        else if (value > sortedVect[mid]) {
            // value must be between indices mid-1 and high, if exists
            return binarySearch(value, sortedVect, mid+1, high);
        }
    }

    return -1;
}

int main() {
    int value;
    cout << "Enter the value to search for : ";
    cin >> value;

    int size;
    cout << "Enter the input size : ";
    cin >> size;

    vector<int> inputVect(size);    // supposedly sorted values
    cout << "Enter " << size << " integers in ascending order :\n";
    for (int& val: inputVect)
        cin >> val;

    int index = binarySearch(value, inputVect, 0, size-1);
    cout << "\n";
    if (index != -1)
        cout << "Found " << value << " at position " << (index + 1) << "\n";
    else
        cout << "Either " << value << " is not present among the input values, or the values aren\'t sorted\n";

    return 0;
}
<|endoftext|>


<commit_before>//
//  language_parser.cpp
//  TameParse
//
//  Created by Andrew Hunter on 19/09/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "util/stringreader.h"
#include "Language/language_parser.h"
#include "Language/process.h"

#include "tameparse_language.h"

using namespace util;
using namespace dfa;
using namespace language;

/// \brief Creates a new language object
language_parser::language_parser()
: m_FileDefinition(NULL, true) {
}

typedef tameparse_language::Parser_Language         Parser_Language;
typedef tameparse_language::list_of_TopLevel_Block  list_of_TopLevel_Block;
typedef tameparse_language::TopLevel_Block          ast_TopLevel_Block;
typedef tameparse_language::Language_Block          ast_Language_Block;
typedef tameparse_language::Language_Definition     ast_Language_Definition;

/// \brief Interprets a language unit
static language_unit* definition_for(const ast_Language_Definition* defn) {
    // TODO
    return NULL;
}

/// \brief Interprets a language block
static language_block* definition_for(const ast_Language_Block* language) {
    // Create the language block
    language_block* result = new language_block(language->identifier->content<wchar_t>(), language->pos(), language->final_pos());

    // Deal with the inherits block, if it exists
    if (language->optional_Language_Inherits->Language_Inherits) {
        // Add the first identifier
        result->add_inherits(language->optional_Language_Inherits->Language_Inherits->identifier->content<wchar_t>());

        // Iterate through the identifiers of the languages this inherits from
        for (tameparse_language::list_of__comma__identifier::iterator inherit =
             language->optional_Language_Inherits->Language_Inherits->list_of__comma__identifier->begin();
             inherit != language->optional_Language_Inherits->Language_Inherits->list_of__comma__identifier->end();
             inherit++) {
            // Add each one to the result
            result->add_inherits((*inherit)->identifier->content<wchar_t>());
        }
    }

    // Add the language definitions
    for (tameparse_language::list_of_Language_Definition::iterator langDefinition = language->list_of_Language_Definition->begin();
         langDefinition != language->list_of_Language_Definition->end();
         langDefinition++) {
        // Get the next definition
        language_unit* nextUnit = definition_for((*langDefinition)->Language_Definition);

        // Self-destruct if we get a failure here
        if (!nextUnit) {
            // Doh, bug
            delete result;
            return NULL;
        }

        // Add to the definition
        result->add_unit(nextUnit);
    }

    // Return the result
    return result;
}

/// \brief Interprets a top-level block
static toplevel_block* definition_for(const ast_TopLevel_Block* toplevel) {
    // Action depends on the type of block

    // Language block
    if (toplevel->Language_Block) {
        // Get the definition for this language block
        language_block* language = definition_for(toplevel->Language_Block);
        if (!language) {
            // Doh
            return NULL;
        }

        // Turn into a toplevel block
        return new toplevel_block(language);
    }

    // Import block
    else if (toplevel->Import_Block) {
        // Fairly simple to convert
        return new toplevel_block(new import_block(process::dequote_string(toplevel->Import_Block->string_2->content<wchar_t>()), toplevel->pos(), toplevel->final_pos()));
    }

    // Parser block
    else if (toplevel->Parser_Block) {

    }

    // Failed to parse: doh, bug
    return NULL;
}

/// \brief Turns a parser language object into a definition file object
static definition_file* definition_for(const Parser_Language* language) {
    // Create a new definition file
    definition_file* file = new definition_file();

    // Iterate through the top-level definitions
    for (list_of_TopLevel_Block::iterator topLevel = language->list_of_TopLevel_Block->begin(); topLevel != language->list_of_TopLevel_Block->end(); topLevel++) {
        // Get the definition for this toplevel block
        toplevel_block* newBlock = definition_for((*topLevel)->TopLevel_Block);

        // Blow up if the block turns out to be NULL
        if (!newBlock) {
            // Doh, bug
            delete file;
            return NULL;
        }

        // Add to the file
        file->add(newBlock);
    }

    // TODO
    return NULL;
}

/// \brief Turns a base definition into a definition file object
static definition_file* definition_for(const tameparse_language::epsilon* root) {
    // Pass the parser language straight through
    return definition_for(root->Parser_Language);
}

/// \brief Parses the language file specified in the given string and stores it in this object.
///
/// This will return true if the file parsed correctly. If this is the case, then the file_definition() function
/// will return the result. If there is any existing definition, this will be replaced by this call.
bool language_parser::parse(const std::wstring& language) {
    bool result = false;

    // Clear the definition
    m_FileDefinition = definition_file_container(NULL, true);

    // Create the parser for this language
    typedef tameparse_language::ast_parser_type::state  state;
    typedef tameparse_language::parser_actions          parser_actions;

    // Create a lexer for this string
    wstringreader reader(language);

    lexeme_stream* stream = tameparse_language::lexer.create_stream_from<wchar_t>(reader);

    // Create the parser
    // Currently using the 'raw' parser here (due to the state of the C++ generator at this point in time: I imagine it will have
    // a few more interesting/easy ways of creating parsers later on)
    state* parser_state = tameparse_language::ast_parser.create_parser(new parser_actions(stream));

    // Parse the language
    result = parser_state->parse();

    // Convert to a definition
    if (result) {
        // Fetch the root item (which will be an epsilon item at the moment due to the way the parser is built up)
        // The name of this item will probably change to something more sensible at some point (and I'll forget to remove this comment)
        const tameparse_language::epsilon* root = (const tameparse_language::epsilon*) parser_state->get_item().item();

        // Turn into a definition
        m_FileDefinition = definition_file_container(definition_for(root), true);
    }

    // Finished with the parser
    delete parser_state;
    delete stream;

    // Done
    return result;
}
<commit_msg>More work on making the parser produce lexemes<commit_after>//
//  language_parser.cpp
//  TameParse
//
//  Created by Andrew Hunter on 19/09/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "util/stringreader.h"
#include "Language/language_parser.h"
#include "Language/process.h"

#include "tameparse_language.h"

using namespace util;
using namespace dfa;
using namespace language;

/// \brief Creates a new language object
language_parser::language_parser()
: m_FileDefinition(NULL, true) {
}

typedef tameparse_language::Parser_Language             Parser_Language;
typedef tameparse_language::list_of_TopLevel_Block      list_of_TopLevel_Block;
typedef tameparse_language::TopLevel_Block              ast_TopLevel_Block;
typedef tameparse_language::Language_Block              ast_Language_Block;
typedef tameparse_language::Language_Definition         ast_Language_Definition;
typedef tameparse_language::list_of_Language_Definition list_of_Language_Definition;
typedef tameparse_language::list_of__comma__identifier  list_of__comma__identifier;
typedef tameparse_language::list_of_Lexeme_Definition   list_of_Lexeme_Definition;
typedef tameparse_language::list_of_Keyword_Definition  list_of_Keyword_Definition;
typedef tameparse_language::identifier                  identifier;
typedef tameparse_language::regex                       ast_regex;
typedef tameparse_language::string_2                    ast_string;
typedef tameparse_language::character                   ast_character;

/// \brief Interprets a keyword symbol definition block
static language_unit* definition_for(const list_of_Keyword_Definition* items, language_unit::unit_type type) {
    return NULL;
}

/// \brief Interprets a lexer symbol definition block
static language_unit* definition_for(const list_of_Lexeme_Definition* items, language_unit::unit_type type) {
    // Start building up the lexer block
    lexer_block* lexerBlock = new lexer_block(items->pos(), items->final_pos());

    // Iterate through the items
    for (list_of_Lexeme_Definition::iterator lexeme = items->begin(); lexeme != items->end(); lexeme++) {
        // Get the identifier for the new lexeme
        const identifier* lexemeId = (*lexeme)->Lexeme_Definition->identifier;

        // Lexeme should either be a string/character/regex or a reference
        if ((*lexeme)->Lexeme_Definition->one_of_regex_or_one_of_string_or_character) {
            // Get the three alternatives
            const ast_regex*        regex       = (*lexeme)->Lexeme_Definition->one_of_regex_or_one_of_string_or_character->regex;
            const ast_string*       string      = (*lexeme)->Lexeme_Definition->one_of_regex_or_one_of_string_or_character->string_2;
            const ast_character*    character   = (*lexeme)->Lexeme_Definition->one_of_regex_or_one_of_string_or_character->character;

            if (regex) {
                lexerBlock->add_definition(new lexeme_definition(lexeme_definition::regex, lexemeId->content<wchar_t>(), regex->content<wchar_t>(), (*lexeme)->pos(), (*lexeme)->final_pos()));
            } else if (string) {
                lexerBlock->add_definition(new lexeme_definition(lexeme_definition::string, lexemeId->content<wchar_t>(), string->content<wchar_t>(), (*lexeme)->pos(), (*lexeme)->final_pos()));
            } else if (character) {
                lexerBlock->add_definition(new lexeme_definition(lexeme_definition::character, lexemeId->content<wchar_t>(), character->content<wchar_t>(), (*lexeme)->pos(), (*lexeme)->final_pos()));
            } else {
                // Doh, bug: fail
                delete lexerBlock;
                return NULL;
            }
        } else if ((*lexeme)->Lexeme_Definition->identifier_2) {
            // Reference (IMPLEMENT ME)
            delete lexerBlock;
            return NULL;
        } else {
            // Doh, bug: fail
            delete lexerBlock;
            return NULL;
        }
    }

    return NULL;
}

/// \brief Interprets a language unit
static language_unit* definition_for(const ast_Language_Definition* defn) {
    // Action depends on the typeof node in this AST node

    // Most of the lexer type nodes are very similar, except for the node type
    if (defn->Lexer_Symbols_Definition) {
        return definition_for(defn->Lexer_Symbols_Definition->list_of_Lexeme_Definition, language_unit::unit_lexer_symbols);
    } else if (defn->Lexer_Definition) {
        bool isWeak = defn->Lexer_Definition->optional_weak->weak;

        return definition_for(defn->Lexer_Definition->list_of_Lexeme_Definition, isWeak?language_unit::unit_weak_lexer_definition:language_unit::unit_lexer_definition);
    } else if (defn->Ignore_Definition) {
        return definition_for(defn->Ignore_Definition->list_of_Keyword_Definition, language_unit::unit_ignore_definition);
    } else if (defn->Keywords_Definition) {
        bool isWeak = defn->Keywords_Definition->optional_weak->weak;

        return definition_for(defn->Keywords_Definition->list_of_Keyword_Definition, isWeak?language_unit::unit_weak_keywords_definition:language_unit::unit_keywords_definition);
    } else if (defn->Grammar_Definition) {

    }

    return NULL;
}

/// \brief Interprets a language block
static language_block* definition_for(const ast_Language_Block* language) {
    // Create the language block
    language_block* result = new language_block(language->identifier->content<wchar_t>(), language->pos(), language->final_pos());

    // Deal with the inherits block, if it exists
    if (language->optional_Language_Inherits->Language_Inherits) {
        // Add the first identifier
        result->add_inherits(language->optional_Language_Inherits->Language_Inherits->identifier->content<wchar_t>());

        // Iterate through the identifiers of the languages this inherits from
        for (list_of__comma__identifier::iterator inherit =
             language->optional_Language_Inherits->Language_Inherits->list_of__comma__identifier->begin();
             inherit != language->optional_Language_Inherits->Language_Inherits->list_of__comma__identifier->end();
             inherit++) {
            // Add each one to the result
            result->add_inherits((*inherit)->identifier->content<wchar_t>());
        }
    }

    // Add the language definitions
    for (list_of_Language_Definition::iterator langDefinition = language->list_of_Language_Definition->begin();
         langDefinition != language->list_of_Language_Definition->end();
         langDefinition++) {
        // Get the next definition
        language_unit* nextUnit = definition_for((*langDefinition)->Language_Definition);

        // Self-destruct if we get a failure here
        if (!nextUnit) {
            // Doh, bug
            delete result;
            return NULL;
        }

        // Add to the definition
        result->add_unit(nextUnit);
    }

    // Return the result
    return result;
}

/// \brief Interprets a top-level block
static toplevel_block* definition_for(const ast_TopLevel_Block* toplevel) {
    // Action depends on the type of block

    // Language block
    if (toplevel->Language_Block) {
        // Get the definition for this language block
        language_block* language = definition_for(toplevel->Language_Block);
        if (!language) {
            // Doh
            return NULL;
        }

        // Turn into a toplevel block
        return new toplevel_block(language);
    }

    // Import block
    else if (toplevel->Import_Block) {
        // Fairly simple to convert
        return new toplevel_block(new import_block(process::dequote_string(toplevel->Import_Block->string_2->content<wchar_t>()), toplevel->pos(), toplevel->final_pos()));
    }

    // Parser block
    else if (toplevel->Parser_Block) {

    }

    // Failed to parse: doh, bug
    return NULL;
}

/// \brief Turns a parser language object into a definition file object
static definition_file* definition_for(const Parser_Language* language) {
    // Create a new definition file
    definition_file* file = new definition_file();

    // Iterate through the top-level definitions
    for (list_of_TopLevel_Block::iterator topLevel = language->list_of_TopLevel_Block->begin(); topLevel != language->list_of_TopLevel_Block->end(); topLevel++) {
        // Get the definition for this toplevel block
        toplevel_block* newBlock = definition_for((*topLevel)->TopLevel_Block);

        // Blow up if the block turns out to be NULL
        if (!newBlock) {
            // Doh, bug
            delete file;
            return NULL;
        }

        // Add to the file
        file->add(newBlock);
    }

    // TODO
    return NULL;
}

/// \brief Turns a base definition into a definition file object
static definition_file* definition_for(const tameparse_language::epsilon* root) {
    // Pass the parser language straight through
    return definition_for(root->Parser_Language);
}

/// \brief Parses the language file specified in the given string and stores it in this object.
///
/// This will return true if the file parsed correctly. If this is the case, then the file_definition() function
/// will return the result. If there is any existing definition, this will be replaced by this call.
bool language_parser::parse(const std::wstring& language) {
    bool result = false;

    // Clear the definition
    m_FileDefinition = definition_file_container(NULL, true);

    // Create the parser for this language
    typedef tameparse_language::ast_parser_type::state  state;
    typedef tameparse_language::parser_actions          parser_actions;

    // Create a lexer for this string
    wstringreader reader(language);

    lexeme_stream* stream = tameparse_language::lexer.create_stream_from<wchar_t>(reader);

    // Create the parser
    // Currently using the 'raw' parser here (due to the state of the C++ generator at this point in time: I imagine it will have
    // a few more interesting/easy ways of creating parsers later on)
    state* parser_state = tameparse_language::ast_parser.create_parser(new parser_actions(stream));

    // Parse the language
    result = parser_state->parse();

    // Convert to a definition
    if (result) {
        // Fetch the root item (which will be an epsilon item at the moment due to the way the parser is built up)
        // The name of this item will probably change to something more sensible at some point (and I'll forget to remove this comment)
        const tameparse_language::epsilon* root = (const tameparse_language::epsilon*) parser_state->get_item().item();

        // Turn into a definition
        m_FileDefinition = definition_file_container(definition_for(root), true);
    }

    // Finished with the parser
    delete parser_state;
    delete stream;

    // Done
    return result;
}
<|endoftext|>


<commit_before><commit_msg>test: logalloc_test: test background reclaim<commit_after><|endoftext|>


<commit_before>
#include "compiler.h"

#include <ostream>
#include <map>
#include <vector>
#include <string>
#include <sstream>

#include <boost/assign/list_of.hpp>
#include <boost/filesystem.hpp>
#include <boost/regex.hpp>

#pragma warning(push)
#pragma warning(disable : 4267) // warning C4267: 'argument' : conversion from 'size_t' to 'unsigned int', possible loss of data
                                // triggered by boost wave...
// configure wave
#ifdef BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY
#undef BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY
#endif // BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY
#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1

#ifdef BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE
#undef BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE
#endif // BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE
#define BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE 1

#ifdef BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES
#undef BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES
#endif // BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES
#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 1

#ifdef BOOST_WAVE_SUPPORT_PRAGMA_ONCE
#undef BOOST_WAVE_SUPPORT_PRAGMA_ONCE
#endif // BOOST_WAVE_SUPPORT_PRAGMA_ONCE
#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 1

//#include <boost/wave.hpp>
//#include <boost/wave/preprocessing_hooks.hpp>
//#include <boost/wave/cpplexer/cpp_lex_token.hpp>
//#include <boost/wave/cpplexer/cpp_lex_iterator.hpp>

#pragma warning(pop)

#include <scm/core/numeric_types.h>
#include <scm/core/io/tools.h>
#include <scm/core/utilities/foreach.h>

#include <scm/gl/opengl.h>

namespace {
#if 0
template<typename input_token_type>
class glsl_preprocessing_hook : public boost::wave::context_policies::eat_whitespace<input_token_type>//boost::wave::context_policies::default_preprocessing_hooks
{
public:
    template <typename context_type, typename container_type>
    bool
    found_unknown_directive(context_type& ctx, const container_type& line, container_type& pending) {
        namespace wave = boost::wave;
        typedef typename container_type::const_iterator iterator_type;

        iterator_type   it = line.begin();
        wave::token_id  id = wave::util::impl::skip_whitespace(it, line.end());

        if (id != wave::T_IDENTIFIER) {
            return (false);
        }

        if (it->get_value() == "version") {

            std::string version_macro("__VERSION__=");
            std::string profile_macro;

            // retrieve version
            wave::token_id  version_id = wave::util::impl::skip_whitespace(++it, line.end());
            if (version_id == wave::T_PP_NUMBER) {
                version_macro += it->get_value().c_str();
            }
            else {
                return (false);
            }

            // retrieve profile name
            wave::token_id  profile_id = wave::util::impl::skip_whitespace(++it, line.end());
            if (profile_id == wave::T_IDENTIFIER) {
            }
            else {
                return (false);
            }

            ctx.add_macro_definition(version_macro, true);

            // pass the line on to the glsl compiler
            std::copy(line.begin(), line.end(), std::back_inserter(pending));

            return (true);
        }
        else if (it->get_value() == "extension") {
            std::copy(line.begin(), line.end(), std::back_inserter(pending));
            return (true);
        }

        return (false);
    }
    template <typename context_type, typename token_type, typename container_type>
    bool
    evaluated_conditional_expression(const context_type& ctx, const token_type& directive, const container_type& expression, bool expression_value) {
        namespace wave = boost::wave;
        typedef typename container_type::const_iterator iterator_type;

        for (iterator_type it = expression.begin(); it != expression.end(); ++it) {
            //wave::token_id  id = wave::util::impl::skip_whitespace(it, expression.end());

            if (*it == wave::T_IDENTIFIER) {
                if (it->get_value() == "GL_stuff") {
                    return (false);
                }
            }
        }
        return (false);
    }

}; // class glsl_preprocessing_hook
#endif
} // namespace detail

namespace scm {
namespace gl {

namespace detail {

static std::map<shader_compiler::shader_type, GLenum> gl_shader_types
    = boost::assign::map_list_of(shader_compiler::vertex_shader,   GL_VERTEX_SHADER)
                                (shader_compiler::geometry_shader, GL_GEOMETRY_SHADER)
                                (shader_compiler::fragment_shader, GL_FRAGMENT_SHADER);

static std::map<shader_compiler::shader_profile, std::string> shader_profile_strings
    = boost::assign::map_list_of(shader_compiler::opengl_core,          "core")
                                (shader_compiler::opengl_compatibility, "compatibility");

class line_string
{
public:
    line_string(scm::size_t n, const std::string& f) : _number(n), _file_name(f) {}
    std::ostream& operator()(std::ostream& os) const {
        os << "#line " << _number << " \"" << _file_name << "\"" << std::endl;
        return (os);
    }
private:
    scm::size_t         _number;
    const std::string&  _file_name;
};

std::ostream& operator<<(std::ostream& os, const line_string& ln) {
    return (ln(os));
}

} // namespace detail

shader_compiler::shader_compiler()
  : _max_include_recursion_depth(20),
    _default_glsl_version(150),
    _default_glsl_profile(opengl_compatibility)
{
}

shader_compiler::~shader_compiler()
{
}

void
shader_compiler::add_include_path(const std::string& p)
{
    using namespace boost::filesystem;

    path    new_path(p, native);

    if (exists(new_path)) {
        if (!is_directory(new_path)) {
            new_path = new_path.parent_path();
        }
        _default_include_paths.push_back(new_path.string());
    }
}

void
shader_compiler::add_macro_definition(const macro_definition& d)
{
    _default_defines.push_back(d);
}

shader_obj_ptr
shader_compiler::compile(const shader_type           t,
                         const std::string&          shader_file,
                         const macro_definition_list&          defines,
                         const include_path_list&    includes,
                               std::ostream&         log_stream /*= std::cout*/)
{
    using namespace boost::filesystem;

    path            file_path(shader_file, native);
    std::string     file_name(file_path.filename());

    if (!exists(file_path) || is_directory(file_path)) {
        log_stream << "shader_compiler::compile() <error>: "
                   << shader_file << " does not exist or is a directory" << std::endl;
        return (shader_obj_ptr());
    }

    // generate final includes and defines
    include_path_list   combined_includes(includes);        // custom includes take priority, first in list searched first
    combined_includes.insert(combined_includes.end(), _default_include_paths.begin(), _default_include_paths.end());

    macro_definition_list         combined_defines(_default_defines); // custom defines take priority, last in list inserted last into code
    combined_defines.insert(combined_defines.end(), defines.begin(), defines.end());

    // read source file
    std::string source_string;

    if (!scm::io::read_text_file(shader_file, source_string)) {
        log_stream << "shader_compiler::compile() <error>: "
                   << "unable to read file: " << shader_file << std::endl;
        return (shader_obj_ptr());
    }
#if 0
    namespace wave = boost::wave;

    typedef wave::cpplexer::lex_token<> token_type;
    typedef wave::cpplexer::lex_iterator<token_type> lex_iterator_type;

    typedef wave::context<std::string::iterator, lex_iterator_type,
                          wave::iteration_context_policies::load_file_to_string,
                          glsl_preprocessing_hook<lex_iterator_type::token_type> > context_type;

    wave::util::file_position_type current_position;

    context_type ctx(source_string.begin(), source_string.end(), shader_file.c_str());

    ctx.set_language(wave::enable_single_line(ctx.get_language(),             true));
    ctx.set_language(wave::enable_no_character_validation(ctx.get_language(), false));
    ctx.set_language(wave::enable_insert_whitespace(ctx.get_language(),       false));
    ctx.set_language(wave::enable_preserve_comments(ctx.get_language(),       false));
    ctx.set_language(wave::enable_emit_line_directives(ctx.get_language(),    true));
    ctx.set_language(wave::enable_include_guard_detection(ctx.get_language(), true));
    ctx.set_language(wave::enable_emit_pragma_directives(ctx.get_language(),  true));

    context_type::iterator_type first = ctx.begin();
    context_type::iterator_type last = ctx.end();

    while (first != last) {
        try {
            current_position = (*first).get_position();
            std::cout << (*first).get_value() << std::flush;
            ++first;
        }
        catch (wave::cpp_exception const& e) {
        // some preprocessing error
            std::cout
                << e.file_name() << "(" << e.line_no() << "): "
                << e.description() << std::endl;
            if (!e.is_recoverable())
                return (shader_obj_ptr());
        }
        catch (std::exception const& e) {
        // use last recognized token to retrieve the error position
            std::cout
                << current_position.get_file()
                << "(" << current_position.get_line() << "): "
                << "exception caught: " << e.what()
                << std::endl;
            //return (shader_obj_ptr());
        }
        catch (...) {
        // use last recognized token to retrieve the error position
            std::cout
                << current_position.get_file()
                << "(" << current_position.get_line() << "): "
                << "unexpected exception caught." << std::endl;
            //return (shader_obj_ptr());
        }
    }

    // comment line (//|/*...*/)                 1
    boost::regex    comment_line_open_regex("\\s*(//|/\\*.*)?");
    boost::regex    comment_line_close_regex(".*\\*/\\s*");
    // #version xxx xxxxxxx(//|/*...)                       1       2    3                4
    boost::regex    version_line_regex("\\s*#\\s*version\\s+(\\d{3})(\\s+([a-zA-Z]*))?\\s*(//|/\\*.*)?");
    // #include (<|")...("|>)(//|/*...)                     1     2   3          4
    boost::regex    include_line_regex("\\s*#\\s*include\\s+([\"<)(.*)([\">])\\s*(//|/\\*.*)?");

    std::istringstream  in_stream(source_string);
    std::stringstream   out_stream;
    std::string         in_line;
    scm::size_t         line_number = 1;
#endif
    //out_stream << std::setprecision(6);

#if 0
    bool version_line_found = false;
    bool multi_line_comment = false;
    while (std::getline(in_stream, in_line)) {
        if (multi_line_comment) {
            if (boost::regex_match(in_line, comment_line_close_regex)) {
                out_stream << in_line << std::endl;
                multi_line_comment = false;
            }
        }
        else if (!version_line_found) {
            boost::smatch m;
            if (boost::regex_match(in_line, m, version_line_regex)) {
                out_stream << in_line << std::endl;
                version_line_found = true;
                if (m[4] == "/*") {
                    multi_line_comment = true;
                }
            }
            else if (boost::regex_match(in_line, m, comment_line_open_regex)) {
                out_stream << in_line << std::endl;
                if (m[1] == "/*") {
                    multi_line_comment = true;
                }
            }
            else {
                // this was not a version line and not a comment
                // so we insert the default version string
                out_stream << "#version "
                           << _default_glsl_version << " "
                           << detail::shader_profile_strings[_default_glsl_profile] << std::endl;
                out_stream << detail::line_string(line_number, file_name);
                version_line_found = true;
            }
        }
        ++line_number;
    }
#endif

#if 0 // test
    std::vector<std::string> a;

    a.push_back("#version 150");
    a.push_back("#version 150 core");
    a.push_back("#version 150 core//plaaah");
    a.push_back("#version 150 core //plaaah");
    a.push_back("#version 150 core/*plaaah");
    a.push_back("#version 150 core /*plaaah");
    a.push_back(" # version  150   ");
    a.push_back("  #  version    150    core   ");
    a.push_back("   #   version   150     core//  plaaah  ");
    a.push_back("    #    version     150     core     //    plaaah    ");
    a.push_back("    #    version     150     core/*   plaaah   ");
    a.push_back("    #    version     150     core     /*    plaaah    ");

    foreach(const std::string& s, a) {
        boost::smatch m;
        if (boost::regex_search(s, m, version_regex)) {
            out_stream << m[0] << std::endl;
            out_stream << m[1] << " " << m[2] << " " << m[3] << " " << m[4] << " " << m[5] << " " << m[6] << " " << m[7] << std::endl;
        } else {
            out_stream << "error matching: " << s << std::endl;
        }
    }
#endif

    return (shader_obj_ptr());
}

} // namespace gl
} // namespace scm
<commit_msg>minor<commit_after>
#include "compiler.h"

#include <ostream>
#include <map>
#include <vector>
#include <string>
#include <sstream>

#include <boost/assign/list_of.hpp>
#include <boost/filesystem.hpp>
#include <boost/regex.hpp>

#pragma warning(push)
#pragma warning(disable : 4267) // warning C4267: 'argument' : conversion from 'size_t' to 'unsigned int', possible loss of data
                                // triggered by boost wave...
// configure wave
#ifdef BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY
#undef BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY
#endif // BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY
#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1

#ifdef BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE
#undef BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE
#endif // BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE
#define BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE 1

#ifdef BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES
#undef BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES
#endif // BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES
#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 1

#ifdef BOOST_WAVE_SUPPORT_PRAGMA_ONCE
#undef BOOST_WAVE_SUPPORT_PRAGMA_ONCE
#endif // BOOST_WAVE_SUPPORT_PRAGMA_ONCE
#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 1

//#include <boost/wave.hpp>
//#include <boost/wave/preprocessing_hooks.hpp>
//#include <boost/wave/cpplexer/cpp_lex_token.hpp>
//#include <boost/wave/cpplexer/cpp_lex_iterator.hpp>

#pragma warning(pop)

#include <scm/core/numeric_types.h>
#include <scm/core/io/tools.h>
#include <scm/core/utilities/foreach.h>

#include <scm/gl/opengl.h>

namespace {
#if 0
template<typename input_token_type>
class glsl_preprocessing_hook : public boost::wave::context_policies::eat_whitespace<input_token_type>//boost::wave::context_policies::default_preprocessing_hooks
{
public:
    template <typename context_type, typename container_type>
    bool
    found_unknown_directive(context_type& ctx, const container_type& line, container_type& pending) {
        namespace wave = boost::wave;
        typedef typename container_type::const_iterator iterator_type;

        iterator_type   it = line.begin();
        wave::token_id  id = wave::util::impl::skip_whitespace(it, line.end());

        if (id != wave::T_IDENTIFIER) {
            return (false);
        }

        if (it->get_value() == "version") {

            std::string version_macro("__VERSION__=");
            std::string profile_macro;

            // retrieve version
            wave::token_id  version_id = wave::util::impl::skip_whitespace(++it, line.end());
            if (version_id == wave::T_PP_NUMBER) {
                version_macro += it->get_value().c_str();
            }
            else {
                return (false);
            }

            // retrieve profile name
            wave::token_id  profile_id = wave::util::impl::skip_whitespace(++it, line.end());
            if (profile_id == wave::T_IDENTIFIER) {
            }
            else {
                return (false);
            }

            ctx.add_macro_definition(version_macro, true);

            // pass the line on to the glsl compiler
            std::copy(line.begin(), line.end(), std::back_inserter(pending));

            return (true);
        }
        else if (it->get_value() == "extension") {
            std::copy(line.begin(), line.end(), std::back_inserter(pending));
            return (true);
        }

        return (false);
    }
    template <typename context_type, typename token_type, typename container_type>
    bool
    evaluated_conditional_expression(const context_type& ctx, const token_type& directive, const container_type& expression, bool expression_value) {
        namespace wave = boost::wave;
        typedef typename container_type::const_iterator iterator_type;

        for (iterator_type it = expression.begin(); it != expression.end(); ++it) {
            //wave::token_id  id = wave::util::impl::skip_whitespace(it, expression.end());

            if (*it == wave::T_IDENTIFIER) {
                if (it->get_value() == "GL_stuff") {
                    return (false);
                }
            }
        }
        return (false);
    }

}; // class glsl_preprocessing_hook
#endif
} // namespace detail

namespace scm {
namespace gl {

namespace detail {

//static std::map<shader_compiler::shader_type, GLenum> gl_shader_types
//    = boost::assign::map_list_of(shader_compiler::vertex_shader,   GL_VERTEX_SHADER)
//                                (shader_compiler::geometry_shader, GL_GEOMETRY_SHADER)
//                                (shader_compiler::fragment_shader, GL_FRAGMENT_SHADER);
//
//static std::map<shader_compiler::shader_profile, std::string> shader_profile_strings
//    = boost::assign::map_list_of(shader_compiler::opengl_core,          "core")
//                                (shader_compiler::opengl_compatibility, "compatibility");

class line_string
{
public:
    line_string(scm::size_t n, const std::string& f) : _number(n), _file_name(f) {}
    std::ostream& operator()(std::ostream& os) const {
        os << "#line " << _number << " \"" << _file_name << "\"" << std::endl;
        return (os);
    }
private:
    scm::size_t         _number;
    const std::string&  _file_name;
};

std::ostream& operator<<(std::ostream& os, const line_string& ln) {
    return (ln(os));
}

} // namespace detail

shader_compiler::shader_compiler()
  : _max_include_recursion_depth(20),
    _default_glsl_version(150),
    _default_glsl_profile(opengl_compatibility)
{
}

shader_compiler::~shader_compiler()
{
}

void
shader_compiler::add_include_path(const std::string& p)
{
    using namespace boost::filesystem;

    path    new_path(p, native);

    if (exists(new_path)) {
        if (!is_directory(new_path)) {
            new_path = new_path.parent_path();
        }
        _default_include_paths.push_back(new_path.string());
    }
}

void
shader_compiler::add_macro_definition(const macro_definition& d)
{
    _default_defines.push_back(d);
}

shader_obj_ptr
shader_compiler::compile(const shader_type           t,
                         const std::string&          shader_file,
                         const macro_definition_list&          defines,
                         const include_path_list&    includes,
                               std::ostream&         log_stream /*= std::cout*/)
{
    using namespace boost::filesystem;

    path            file_path(shader_file, native);
    std::string     file_name(file_path.filename());

    if (!exists(file_path) || is_directory(file_path)) {
        log_stream << "shader_compiler::compile() <error>: "
                   << shader_file << " does not exist or is a directory" << std::endl;
        return (shader_obj_ptr());
    }

    // generate final includes and defines
    include_path_list   combined_includes(includes);        // custom includes take priority, first in list searched first
    combined_includes.insert(combined_includes.end(), _default_include_paths.begin(), _default_include_paths.end());

    macro_definition_list         combined_defines(_default_defines); // custom defines take priority, last in list inserted last into code
    combined_defines.insert(combined_defines.end(), defines.begin(), defines.end());

    // read source file
    std::string source_string;

    if (!scm::io::read_text_file(shader_file, source_string)) {
        log_stream << "shader_compiler::compile() <error>: "
                   << "unable to read file: " << shader_file << std::endl;
        return (shader_obj_ptr());
    }
#if 0
    namespace wave = boost::wave;

    typedef wave::cpplexer::lex_token<> token_type;
    typedef wave::cpplexer::lex_iterator<token_type> lex_iterator_type;

    typedef wave::context<std::string::iterator, lex_iterator_type,
                          wave::iteration_context_policies::load_file_to_string,
                          glsl_preprocessing_hook<lex_iterator_type::token_type> > context_type;

    wave::util::file_position_type current_position;

    context_type ctx(source_string.begin(), source_string.end(), shader_file.c_str());

    ctx.set_language(wave::enable_single_line(ctx.get_language(),             true));
    ctx.set_language(wave::enable_no_character_validation(ctx.get_language(), false));
    ctx.set_language(wave::enable_insert_whitespace(ctx.get_language(),       false));
    ctx.set_language(wave::enable_preserve_comments(ctx.get_language(),       false));
    ctx.set_language(wave::enable_emit_line_directives(ctx.get_language(),    true));
    ctx.set_language(wave::enable_include_guard_detection(ctx.get_language(), true));
    ctx.set_language(wave::enable_emit_pragma_directives(ctx.get_language(),  true));

    context_type::iterator_type first = ctx.begin();
    context_type::iterator_type last = ctx.end();

    while (first != last) {
        try {
            current_position = (*first).get_position();
            std::cout << (*first).get_value() << std::flush;
            ++first;
        }
        catch (wave::cpp_exception const& e) {
        // some preprocessing error
            std::cout
                << e.file_name() << "(" << e.line_no() << "): "
                << e.description() << std::endl;
            if (!e.is_recoverable())
                return (shader_obj_ptr());
        }
        catch (std::exception const& e) {
        // use last recognized token to retrieve the error position
            std::cout
                << current_position.get_file()
                << "(" << current_position.get_line() << "): "
                << "exception caught: " << e.what()
                << std::endl;
            //return (shader_obj_ptr());
        }
        catch (...) {
        // use last recognized token to retrieve the error position
            std::cout
                << current_position.get_file()
                << "(" << current_position.get_line() << "): "
                << "unexpected exception caught." << std::endl;
            //return (shader_obj_ptr());
        }
    }

    // comment line (//|/*...*/)                 1
    boost::regex    comment_line_open_regex("\\s*(//|/\\*.*)?");
    boost::regex    comment_line_close_regex(".*\\*/\\s*");
    // #version xxx xxxxxxx(//|/*...)                       1       2    3                4
    boost::regex    version_line_regex("\\s*#\\s*version\\s+(\\d{3})(\\s+([a-zA-Z]*))?\\s*(//|/\\*.*)?");
    // #include (<|")...("|>)(//|/*...)                     1     2   3          4
    boost::regex    include_line_regex("\\s*#\\s*include\\s+([\"<)(.*)([\">])\\s*(//|/\\*.*)?");

    std::istringstream  in_stream(source_string);
    std::stringstream   out_stream;
    std::string         in_line;
    scm::size_t         line_number = 1;
#endif
    //out_stream << std::setprecision(6);

#if 0
    bool version_line_found = false;
    bool multi_line_comment = false;
    while (std::getline(in_stream, in_line)) {
        if (multi_line_comment) {
            if (boost::regex_match(in_line, comment_line_close_regex)) {
                out_stream << in_line << std::endl;
                multi_line_comment = false;
            }
        }
        else if (!version_line_found) {
            boost::smatch m;
            if (boost::regex_match(in_line, m, version_line_regex)) {
                out_stream << in_line << std::endl;
                version_line_found = true;
                if (m[4] == "/*") {
                    multi_line_comment = true;
                }
            }
            else if (boost::regex_match(in_line, m, comment_line_open_regex)) {
                out_stream << in_line << std::endl;
                if (m[1] == "/*") {
                    multi_line_comment = true;
                }
            }
            else {
                // this was not a version line and not a comment
                // so we insert the default version string
                out_stream << "#version "
                           << _default_glsl_version << " "
                           << detail::shader_profile_strings[_default_glsl_profile] << std::endl;
                out_stream << detail::line_string(line_number, file_name);
                version_line_found = true;
            }
        }
        ++line_number;
    }
#endif

#if 0 // test
    std::vector<std::string> a;

    a.push_back("#version 150");
    a.push_back("#version 150 core");
    a.push_back("#version 150 core//plaaah");
    a.push_back("#version 150 core //plaaah");
    a.push_back("#version 150 core/*plaaah");
    a.push_back("#version 150 core /*plaaah");
    a.push_back(" # version  150   ");
    a.push_back("  #  version    150    core   ");
    a.push_back("   #   version   150     core//  plaaah  ");
    a.push_back("    #    version     150     core     //    plaaah    ");
    a.push_back("    #    version     150     core/*   plaaah   ");
    a.push_back("    #    version     150     core     /*    plaaah    ");

    foreach(const std::string& s, a) {
        boost::smatch m;
        if (boost::regex_search(s, m, version_regex)) {
            out_stream << m[0] << std::endl;
            out_stream << m[1] << " " << m[2] << " " << m[3] << " " << m[4] << " " << m[5] << " " << m[6] << " " << m[7] << std::endl;
        } else {
            out_stream << "error matching: " << s << std::endl;
        }
    }
#endif

    return (shader_obj_ptr());
}

} // namespace gl
} // namespace scm
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_test.h"

#include "base/file_path.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"

class NewTabUITest : public UITest {
 public:
  NewTabUITest() {
    dom_automation_enabled_ = true;
    // Set home page to the empty string so that we can set the home page using
    // preferences.
    homepage_ = L"";

    // Setup the DEFAULT_THEME profile (has fake history entries).
    set_template_user_data(UITest::ComputeTypicalUserDataSource(
        UITest::DEFAULT_THEME));
  }
};

// TODO(aa): http://crbug.com/33451
#if !defined(OS_MACOSX)
TEST_F(NewTabUITest, NTPHasThumbnails) {
  // Switch to the "new tab" tab, which should be any new tab after the
  // first (the first is about:blank).
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  int tab_count = -1;
  ASSERT_TRUE(window->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up a new tab page.
  window->RunCommand(IDC_NEW_TAB);
  ASSERT_TRUE(window->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  // Blank thumbnails on the NTP have the class 'filler' applied to the div.
  // If all the thumbnails load, there should be no div's with 'filler'.
  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  int filler_thumbnails_count = -1;
  const int kWaitDuration = 100;
  int wait_time = action_max_timeout_ms();
  while (wait_time > 0) {
    ASSERT_TRUE(tab->ExecuteAndExtractInt(L"",
        L"window.domAutomationController.send("
        L"document.getElementsByClassName('filler').length)",
        &filler_thumbnails_count));
    if (filler_thumbnails_count == 0)
      break;
    PlatformThread::Sleep(kWaitDuration);
    wait_time -= kWaitDuration;
  }
  EXPECT_EQ(0, filler_thumbnails_count);
}
#endif

TEST_F(NewTabUITest, ChromeInternalLoadsNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  int tab_count = -1;
  ASSERT_TRUE(window->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Go to the "new tab page" using its old url, rather than chrome://newtab.
  scoped_refptr<TabProxy> tab = window->GetTab(0);
  tab->NavigateToURLAsync(GURL("chrome-internal:"));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  // Ensure there are some thumbnails loaded in the page.
  int thumbnails_count = -1;
  ASSERT_TRUE(tab->ExecuteAndExtractInt(L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('thumbnail-container').length)",
      &thumbnails_count));
  EXPECT_GT(thumbnails_count, 0);
}

TEST_F(NewTabUITest, UpdateUserPrefsVersion) {
  PrefService prefs((FilePath()));

  // Does the migration
  NewTabUI::RegisterUserPrefs(&prefs);

  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs.GetInteger(prefs::kNTPPrefVersion));

  // Reset the version
  prefs.ClearPref(prefs::kNTPPrefVersion);
  ASSERT_EQ(0, prefs.GetInteger(prefs::kNTPPrefVersion));

  bool migrated = NewTabUI::UpdateUserPrefsVersion(&prefs);
  ASSERT_TRUE(migrated);
  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs.GetInteger(prefs::kNTPPrefVersion));

  migrated = NewTabUI::UpdateUserPrefsVersion(&prefs);
  ASSERT_FALSE(migrated);
}

TEST_F(NewTabUITest, HomePageLink) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  ASSERT_TRUE(
      browser->SetBooleanPreference(prefs::kHomePageIsNewTabPage, false));

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up a new tab page.
  browser->RunCommand(IDC_NEW_TAB);
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();

  // TODO(arv): Extract common patterns for doing js testing.

  // Fire click. Because tip service is turned off for testing, we first
  // force the "make this my home page" tip to appear.
  // TODO(arv): Find screen position of element and use a lower level click
  // emulation.
  bool result;
  ASSERT_TRUE(tab->ExecuteAndExtractBool(L"",
    L"window.domAutomationController.send("
    L"(function() {"
    L"  tipCache = [{\"set_homepage_tip\":\"Make this the home page\"}];"
    L"  renderTip();"
    L"  var e = document.createEvent('Event');"
    L"  e.initEvent('click', true, true);"
    L"  var el = document.querySelector('#tip-line > button');"
    L"  el.dispatchEvent(e);"
    L"  return true;"
    L"})()"
    L")",
    &result));
  ASSERT_TRUE(result);

  // Make sure text of "set as home page" tip has been removed.
  std::wstring tip_text_content;
  ASSERT_TRUE(tab->ExecuteAndExtractString(L"",
    L"window.domAutomationController.send("
    L"(function() {"
    L"  var el = document.querySelector('#tip-line');"
    L"  return el.textContent;"
    L"})()"
    L")",
    &tip_text_content));
  ASSERT_EQ(L"", tip_text_content);

  // Make sure that the notification is visible
  bool has_class;
  ASSERT_TRUE(tab->ExecuteAndExtractBool(L"",
    L"window.domAutomationController.send("
    L"(function() {"
    L"  var el = document.querySelector('#notification');"
    L"  return hasClass(el, 'show');"
    L"})()"
    L")",
    &has_class));
  ASSERT_TRUE(has_class);

  bool is_home_page;
  ASSERT_TRUE(browser->GetBooleanPreference(prefs::kHomePageIsNewTabPage,
              &is_home_page));
  ASSERT_TRUE(is_home_page);
}
<commit_msg>Temporaily disable crashing NewTabUITest<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_test.h"

#include "base/file_path.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"

class NewTabUITest : public UITest {
 public:
  NewTabUITest() {
    dom_automation_enabled_ = true;
    // Set home page to the empty string so that we can set the home page using
    // preferences.
    homepage_ = L"";

    // Setup the DEFAULT_THEME profile (has fake history entries).
    set_template_user_data(UITest::ComputeTypicalUserDataSource(
        UITest::DEFAULT_THEME));
  }
};

// TODO(aa): http://crbug.com/33451
#if !defined(OS_MACOSX)
TEST_F(NewTabUITest, NTPHasThumbnails) {
  // Switch to the "new tab" tab, which should be any new tab after the
  // first (the first is about:blank).
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  int tab_count = -1;
  ASSERT_TRUE(window->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up a new tab page.
  window->RunCommand(IDC_NEW_TAB);
  ASSERT_TRUE(window->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  // Blank thumbnails on the NTP have the class 'filler' applied to the div.
  // If all the thumbnails load, there should be no div's with 'filler'.
  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  int filler_thumbnails_count = -1;
  const int kWaitDuration = 100;
  int wait_time = action_max_timeout_ms();
  while (wait_time > 0) {
    ASSERT_TRUE(tab->ExecuteAndExtractInt(L"",
        L"window.domAutomationController.send("
        L"document.getElementsByClassName('filler').length)",
        &filler_thumbnails_count));
    if (filler_thumbnails_count == 0)
      break;
    PlatformThread::Sleep(kWaitDuration);
    wait_time -= kWaitDuration;
  }
  EXPECT_EQ(0, filler_thumbnails_count);
}

TEST_F(NewTabUITest, ChromeInternalLoadsNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  int tab_count = -1;
  ASSERT_TRUE(window->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Go to the "new tab page" using its old url, rather than chrome://newtab.
  scoped_refptr<TabProxy> tab = window->GetTab(0);
  tab->NavigateToURLAsync(GURL("chrome-internal:"));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  // Ensure there are some thumbnails loaded in the page.
  int thumbnails_count = -1;
  ASSERT_TRUE(tab->ExecuteAndExtractInt(L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('thumbnail-container').length)",
      &thumbnails_count));
  EXPECT_GT(thumbnails_count, 0);
}
#endif

TEST_F(NewTabUITest, UpdateUserPrefsVersion) {
  PrefService prefs((FilePath()));

  // Does the migration
  NewTabUI::RegisterUserPrefs(&prefs);

  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs.GetInteger(prefs::kNTPPrefVersion));

  // Reset the version
  prefs.ClearPref(prefs::kNTPPrefVersion);
  ASSERT_EQ(0, prefs.GetInteger(prefs::kNTPPrefVersion));

  bool migrated = NewTabUI::UpdateUserPrefsVersion(&prefs);
  ASSERT_TRUE(migrated);
  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs.GetInteger(prefs::kNTPPrefVersion));

  migrated = NewTabUI::UpdateUserPrefsVersion(&prefs);
  ASSERT_FALSE(migrated);
}

TEST_F(NewTabUITest, HomePageLink) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  ASSERT_TRUE(
      browser->SetBooleanPreference(prefs::kHomePageIsNewTabPage, false));

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up a new tab page.
  browser->RunCommand(IDC_NEW_TAB);
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();

  // TODO(arv): Extract common patterns for doing js testing.

  // Fire click. Because tip service is turned off for testing, we first
  // force the "make this my home page" tip to appear.
  // TODO(arv): Find screen position of element and use a lower level click
  // emulation.
  bool result;
  ASSERT_TRUE(tab->ExecuteAndExtractBool(L"",
    L"window.domAutomationController.send("
    L"(function() {"
    L"  tipCache = [{\"set_homepage_tip\":\"Make this the home page\"}];"
    L"  renderTip();"
    L"  var e = document.createEvent('Event');"
    L"  e.initEvent('click', true, true);"
    L"  var el = document.querySelector('#tip-line > button');"
    L"  el.dispatchEvent(e);"
    L"  return true;"
    L"})()"
    L")",
    &result));
  ASSERT_TRUE(result);

  // Make sure text of "set as home page" tip has been removed.
  std::wstring tip_text_content;
  ASSERT_TRUE(tab->ExecuteAndExtractString(L"",
    L"window.domAutomationController.send("
    L"(function() {"
    L"  var el = document.querySelector('#tip-line');"
    L"  return el.textContent;"
    L"})()"
    L")",
    &tip_text_content));
  ASSERT_EQ(L"", tip_text_content);

  // Make sure that the notification is visible
  bool has_class;
  ASSERT_TRUE(tab->ExecuteAndExtractBool(L"",
    L"window.domAutomationController.send("
    L"(function() {"
    L"  var el = document.querySelector('#notification');"
    L"  return hasClass(el, 'show');"
    L"})()"
    L")",
    &has_class));
  ASSERT_TRUE(has_class);

  bool is_home_page;
  ASSERT_TRUE(browser->GetBooleanPreference(prefs::kHomePageIsNewTabPage,
              &is_home_page));
  ASSERT_TRUE(is_home_page);
}
<|endoftext|>