<commit_before>//
// SceneOSG.cpp
//
// Implementation of vtScene for the OSG library
//
// Copyright (c) 2001-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "ProjectedShadows.h"

#include <osg/LightSource>
#include <osg/PolygonMode>
#include <osg/Switch>
#include <osg/Fog>
#include <osgDB/Registry>
#include <time.h>		// clock() & CLOCKS_PER_SEC

#ifdef __FreeBSD__
#  include <sys/types.h>
#  include <sys/time.h>
#  include <sys/resource.h>
#endif

#include <iostream>
#include "vtdata/vtLog.h"

using namespace osg;

///////////////////////////////////////////////////////////////
// Trap for OSG messages
//

class OsgMsgTrap : public std::streambuf
{
public:
	inline virtual int_type overflow(int_type c = std::streambuf::traits_type::eof())
	{
		if (c == std::streambuf::traits_type::eof()) return std::streambuf::traits_type::not_eof(c);
		g_Log._Log((char) c);
		return c;
	}
} g_Trap;

///////////////////////////////////////////////////////////////

// There is always and only one global vtScene object
vtScene g_Scene;

vtScene::vtScene() : vtSceneBase()
{
	m_bInitialized = false;
	m_bWireframe = false;
	m_bWinInfo = false;
}

vtScene::~vtScene()
{
	// Do not release camera, that is left for the application.
}

vtScene *vtGetScene()
{
	return &g_Scene;
}

float vtGetTime()
{
	return g_Scene.GetTime();
}

float vtGetFrameTime()
{
	return g_Scene.GetFrameTime();
}

void vtScene::SetBgColor(RGBf color)
{
	Vec4 color2;
	v2s(color, color2);
	m_pOsgSceneView->setClearColor(color2);
}

bool vtScene::Init()
{
	// Redirect cout messages (where OSG sends its messages) to our own log
	std::cout.rdbuf(&g_Trap);
	std::cerr.rdbuf(&g_Trap);

	SetCamera(new vtCamera());

	m_pOsgSceneView = new osgUtil::SceneView();
	m_pOsgSceneView->setDefaults();

	// OSG 0.9.0 and newer
	m_pOsgSceneView->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);

	m_pOsgSceneView->setLightingMode(osgUtil::SceneView::NO_SCENEVIEW_LIGHT);

	// OSG 0.9.2 and newer: turn off "small feature culling"
	m_pOsgSceneView->setCullingMode( m_pOsgSceneView->getCullingMode() & ~osg::CullStack::SMALL_FEATURE_CULLING);

	m_bInitialized = true;

	_initialTick = _timer.tick();
	_frameTick = _initialTick;

	return true;
}

void vtScene::Shutdown()
{
	vtNode::ClearOsgModelCache();
	osgDB::Registry::instance()->clearObjectCache();
}

void vtScene::DoUpdate()
{
	if (!m_bInitialized)
		return;

	_lastFrameTick = _frameTick;
	_frameTick = _timer.tick();

	DoEngines();

	// As of OSG 0.9.5, we need to store our own camera params and recreate
	//  the projection matrix each frame.
	float aspect;
	if (m_WindowSize.x == 0 || m_WindowSize.y == 0)		// safety
		aspect = 1.0;
	else
		aspect = (float) m_WindowSize.x / m_WindowSize.y;

	if (m_pCamera->IsOrtho())
	{
		// Arguments are left, right, bottom, top, zNear, zFar
		float w2 = m_pCamera->GetWidth() /2;
		float h2 = w2 / aspect;
		m_pOsgSceneView->setProjectionMatrixAsOrtho(-w2, w2, -h2, h2,
			m_pCamera->GetHither(), m_pCamera->GetYon());
	}
	else
	{
		float fov_x = m_pCamera->GetFOV();
		float a = tan (fov_x/2);
		float b = a / aspect;
		float fov_y_div2 = atan(b);
		float fov_y_deg = RadiansToDegrees(fov_y_div2 * 2);

		m_pOsgSceneView->setProjectionMatrixAsPerspective(fov_y_deg,
			aspect, m_pCamera->GetHither(), m_pCamera->GetYon());
	}

	// And apply the rotation and translation of the camera itself
	osg::Matrix &mat2 = m_pCamera->m_pTransform->getMatrix();
	osg::Matrix imat;
	imat.invert(mat2);
	m_pOsgSceneView->setViewMatrix(imat);

	CalcCullPlanes();

	m_pOsgSceneView->setViewport(0, 0, m_WindowSize.x, m_WindowSize.y);
	m_pOsgSceneView->cull();
	m_pOsgSceneView->draw();
}

void vtScene::SetRoot(vtGroup *pRoot)
{
	if (pRoot)
		m_pOsgSceneRoot = pRoot->GetOsgGroup();
	else
		m_pOsgSceneRoot = NULL;
	if (m_pOsgSceneView != NULL)
		m_pOsgSceneView->setSceneData(m_pOsgSceneRoot.get());
	m_pRoot = pRoot;
}

/**
 * Convert window coordinates (in pixels) to a ray from the camera
 * in world coordinates.
 */
bool vtScene::CameraRay(const IPoint2 &win, FPoint3 &pos, FPoint3 &dir)
{
	Vec3 near_point, far_point, diff;

	// call the handy OSG function
	m_pOsgSceneView->projectWindowXYIntoObject(win.x, m_WindowSize.y-win.y, near_point, far_point);

	diff = far_point - near_point;
	diff.normalize();

	s2v(near_point, pos);
	s2v(diff, dir);

	return true;
}

// Debugging helper
void LogCullPlanes(FPlane *planes)
{
	for (int i = 0; i < 4; i++)
		VTLOG(" plane %d: %.3f %.3f %.3f %.3f\n", i, planes[i].x, planes[i].y, planes[i].z, planes[i].w);
	VTLOG("\n");
}

void vtScene::CalcCullPlanes()
{
#if 0
	// Non-API-Specific code - will work correctly as long as the Camera
	// methods are fully functional.
	FMatrix4 mat;
	m_pCamera->GetTransform1(mat);

	assert(( m_WindowSize.x > 0 ) && ( m_WindowSize.y > 0 ));

	double fov = m_pCamera->GetFOV();

	double aspect = (float)m_WindowSize.y / m_WindowSize.x;
	double hither = m_pCamera->GetHither();

	double a = hither * tan(fov / 2);
	double b = a * aspect;

	FPoint3 vec_l(-a, 0, -hither);
	FPoint3 vec_r(a, 0, -hither);
	FPoint3 vec_t(0, b, -hither);
	FPoint3 vec_b(0, -b, -hither);

	vec_l.Normalize();
	vec_r.Normalize();
	vec_t.Normalize();
	vec_b.Normalize();

	FPoint3 up(0.0f, 1.0f, 0.0f);
	FPoint3 right(1.0f, 0.0f, 0.0f);

	FPoint3 temp;

	FPoint3 center;
	FPoint3 norm_l, norm_r, norm_t, norm_b;

	temp = up.Cross(vec_l);
	mat.TransformVector(temp, norm_l);

	temp = vec_r.Cross(up);
	mat.TransformVector(temp, norm_r);

	temp = right.Cross(vec_t);
	mat.TransformVector(temp, norm_t);

	temp = vec_b.Cross(right);
	mat.TransformVector(temp, norm_b);

	mat.Transform(FPoint3(0.0f, 0.0f, 0.0f), center);

	// set up m_cullPlanes in world coordinates!
	m_cullPlanes[0].Set(center, norm_l);
	m_cullPlanes[1].Set(center, norm_r);
	m_cullPlanes[2].Set(center, norm_t);
	m_cullPlanes[3].Set(center, norm_b);
#else
	// Get the view frustum clipping planes directly from OSG

	// OSG 0.8.44
//	const ClippingVolume &clipvol = pCam->m_pOsgCamera->getClippingVolume();
	// OSG 0.8.45
//	const ClippingVolume &clipvol = hack_global_state->getClippingVolume();
	// OSG 0.9.0
	// clipvol1 is the global camera frustum (in world coordinates)
//	const Polytope &clipvol1 = pCam->m_pOsgCamera->getViewFrustum();
	// OSG 0.9.6
	// clipvol2 is the camera's frustum after it's been transformed to the
	//		local coordinates.
//	const Polytope &clipvol2 = hack_global_state->getViewFrustum();
//	const Polytope::PlaneList &planes = clipvol2.getPlaneList();
	// Actually no - we can't get the planes from the state, because
	//  the state includes the funny modelview matrix used to scale
	//  the heightfield.  We must get it from the 'scene' instead.

	osg::Matrixd &_projection = m_pOsgSceneView->getProjectionMatrix();
	osg::Matrixd &_modelView = m_pOsgSceneView->getViewMatrix();

	Polytope tope;
	tope.setToUnitFrustum();
	tope.transformProvidingInverse((_modelView)*(_projection));

	const Polytope::PlaneList &planes = tope.getPlaneList();

	int i = 0;
	for (Polytope::PlaneList::const_iterator itr=planes.begin();
		itr!=planes.end(); ++itr)
	{
		// make a copy of the clipping plane
		Plane plane = *itr;

		// extract the OSG plane to our own structure
		Vec4 pvec = plane.asVec4();
		m_cullPlanes[i++].Set(-pvec.x(), -pvec.y(), -pvec.z(), -pvec.w());
	}
#endif

	// For debugging
//	LogCullPlanes(m_cullPlanes);
}

void vtScene::DrawFrameRateChart()
{
	static float fps[100];
	static int s = 0;
	fps[s] = GetFrameRate();

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

//	glMatrixMode(GL_PROJECTION);
//	glLoadIdentity();

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 1.0f, 0.0f);

	glBegin(GL_LINE_STRIP);
	for (int i = 1; i <= 100; i++)
	{
		glVertex3f(-1.0 + i/200.0f, -1.0f + fps[(s+i)%100]/200.0f, 0.0f);
	}
	glEnd();

	s++;
	if (s == 100) s = 0;
}

void vtScene::SetGlobalWireframe(bool bWire)
{
	m_bWireframe = bWire;

	// Set the scene's global PolygonMode attribute, which will affect all
	// other materials in the scene, except those which explicitly override
	// the attribute themselves.
	StateSet *global_state = m_pOsgSceneView->getGlobalStateSet();
	PolygonMode *npm = new PolygonMode();
	if (m_bWireframe)
		npm->setMode(PolygonMode::FRONT_AND_BACK, PolygonMode::LINE);
	else
		npm->setMode(PolygonMode::FRONT_AND_BACK, PolygonMode::FILL);
	global_state->setAttributeAndModes(npm, StateAttribute::ON);
}

bool vtScene::GetGlobalWireframe()
{
	return m_bWireframe;
}

void printnode(osg::Node *node, int tab) {
	for (int i = 0; i < tab*2; i++) {
	   osg::notify(osg::WARN) << " ";
	}
	osg::notify(osg::WARN) << node->className() << " - " << node->getName() << " @ " << node << std::endl;
	osg::Group *group = node->asGroup();
	if (group) {
		for (int i = 0; i < group->getNumChildren(); i++) {
			printnode(group->getChild(i), tab+1);
		}
	}
}

void vtScene::ShadowVisibleNode(vtNode *node, bool bVis)
{
	if (!bVis) {
		m_pShadowVisitor->shadow_ignore_nodes->Append(node->GetOsgNode());
	}
	else {
		int i = m_pShadowVisitor->shadow_ignore_nodes->Find(node->GetOsgNode());
		if (i != -1) {
			m_pShadowVisitor->shadow_ignore_nodes->RemoveAt(i);
		}
	}
	m_pShadowVisitor->RecomputeShadows();
}

void vtScene::SetShadowedNode(vtTransform *pLight, vtNode *pShadowNode,
							  vtTransform *pTransform, int iRez)
{
	if (!m_pShadowVisitor.valid())
		m_pShadowVisitor = new CreateProjectedShadowTextureCullCallback(pShadowNode->GetOsgNode(), iRez);
	else
		m_pShadowVisitor->SetShadower(pShadowNode->GetOsgNode());
		m_pShadowVisitor->SetInitialLightPosition(v2s(-(pLight->GetDirection()) * 10000));
		pTransform->GetOsgNode()->setCullCallback(m_pShadowVisitor.get());
		m_pShadowVisitor->SetEnabled(true);

		osg::Node *node = pShadowNode->GetOsgNode();

#ifdef _DEBUG
	{
		osg::Group *pGroup = (osg::Group*)pTransform->GetOsgNode();
		osg::Geode *pGeode = (osg::Geode*)pGroup->getChild(0);
		osg::Drawable* pDrawable = pGeode->getDrawable(0);
		pDrawable->setDrawCallback(new MyDrawCallback);
	}
#endif
}

void vtScene::UnsetShadowedNode(vtTransform *pTransform)
{
	pTransform->GetOsgNode()->setCullCallback(NULL);
#ifdef _DEBUG
	{
		osg::Group *pGroup = (osg::Group*)pTransform->GetOsgNode();
		osg::Geode *pGeode = (osg::Geode*)pGroup->getChild(0);
		osg::Drawable* pDrawable = pGeode->getDrawable(0);
		pDrawable->setDrawCallback(NULL);
	}
#endif
}

void vtScene::UpdateShadowLightDirection(vtTransform *pLight)
{
	if (m_pShadowVisitor.valid())
	{
		m_pShadowVisitor.get()->SetLightPosition(v2s(-(pLight->GetDirection()) * 10000));
	}
}

////////////////////////////////////////

<commit_msg>fix warning<commit_after>//
// SceneOSG.cpp
//
// Implementation of vtScene for the OSG library
//
// Copyright (c) 2001-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "ProjectedShadows.h"

#include <osg/LightSource>
#include <osg/PolygonMode>
#include <osg/Switch>
#include <osg/Fog>
#include <osgDB/Registry>
#include <time.h>		// clock() & CLOCKS_PER_SEC

#ifdef __FreeBSD__
#  include <sys/types.h>
#  include <sys/time.h>
#  include <sys/resource.h>
#endif

#include <iostream>
#include "vtdata/vtLog.h"

using namespace osg;

///////////////////////////////////////////////////////////////
// Trap for OSG messages
//

class OsgMsgTrap : public std::streambuf
{
public:
	inline virtual int_type overflow(int_type c = std::streambuf::traits_type::eof())
	{
		if (c == std::streambuf::traits_type::eof()) return std::streambuf::traits_type::not_eof(c);
		g_Log._Log((char) c);
		return c;
	}
} g_Trap;

///////////////////////////////////////////////////////////////

// There is always and only one global vtScene object
vtScene g_Scene;

vtScene::vtScene() : vtSceneBase()
{
	m_bInitialized = false;
	m_bWireframe = false;
	m_bWinInfo = false;
}

vtScene::~vtScene()
{
	// Do not release camera, that is left for the application.
}

vtScene *vtGetScene()
{
	return &g_Scene;
}

float vtGetTime()
{
	return g_Scene.GetTime();
}

float vtGetFrameTime()
{
	return g_Scene.GetFrameTime();
}

void vtScene::SetBgColor(RGBf color)
{
	Vec4 color2;
	v2s(color, color2);
	m_pOsgSceneView->setClearColor(color2);
}

bool vtScene::Init()
{
	// Redirect cout messages (where OSG sends its messages) to our own log
	std::cout.rdbuf(&g_Trap);
	std::cerr.rdbuf(&g_Trap);

	SetCamera(new vtCamera());

	m_pOsgSceneView = new osgUtil::SceneView();
	m_pOsgSceneView->setDefaults();

	// OSG 0.9.0 and newer
	m_pOsgSceneView->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);

	m_pOsgSceneView->setLightingMode(osgUtil::SceneView::NO_SCENEVIEW_LIGHT);

	// OSG 0.9.2 and newer: turn off "small feature culling"
	m_pOsgSceneView->setCullingMode( m_pOsgSceneView->getCullingMode() & ~osg::CullStack::SMALL_FEATURE_CULLING);

	m_bInitialized = true;

	_initialTick = _timer.tick();
	_frameTick = _initialTick;

	return true;
}

void vtScene::Shutdown()
{
	vtNode::ClearOsgModelCache();
	osgDB::Registry::instance()->clearObjectCache();
}

void vtScene::DoUpdate()
{
	if (!m_bInitialized)
		return;

	_lastFrameTick = _frameTick;
	_frameTick = _timer.tick();

	DoEngines();

	// As of OSG 0.9.5, we need to store our own camera params and recreate
	//  the projection matrix each frame.
	float aspect;
	if (m_WindowSize.x == 0 || m_WindowSize.y == 0)		// safety
		aspect = 1.0;
	else
		aspect = (float) m_WindowSize.x / m_WindowSize.y;

	if (m_pCamera->IsOrtho())
	{
		// Arguments are left, right, bottom, top, zNear, zFar
		float w2 = m_pCamera->GetWidth() /2;
		float h2 = w2 / aspect;
		m_pOsgSceneView->setProjectionMatrixAsOrtho(-w2, w2, -h2, h2,
			m_pCamera->GetHither(), m_pCamera->GetYon());
	}
	else
	{
		float fov_x = m_pCamera->GetFOV();
		float a = tan (fov_x/2);
		float b = a / aspect;
		float fov_y_div2 = atan(b);
		float fov_y_deg = RadiansToDegrees(fov_y_div2 * 2);

		m_pOsgSceneView->setProjectionMatrixAsPerspective(fov_y_deg,
			aspect, m_pCamera->GetHither(), m_pCamera->GetYon());
	}

	// And apply the rotation and translation of the camera itself
	osg::Matrix &mat2 = m_pCamera->m_pTransform->getMatrix();
	osg::Matrix imat;
	imat.invert(mat2);
	m_pOsgSceneView->setViewMatrix(imat);

	CalcCullPlanes();

	m_pOsgSceneView->setViewport(0, 0, m_WindowSize.x, m_WindowSize.y);
	m_pOsgSceneView->cull();
	m_pOsgSceneView->draw();
}

void vtScene::SetRoot(vtGroup *pRoot)
{
	if (pRoot)
		m_pOsgSceneRoot = pRoot->GetOsgGroup();
	else
		m_pOsgSceneRoot = NULL;
	if (m_pOsgSceneView != NULL)
		m_pOsgSceneView->setSceneData(m_pOsgSceneRoot.get());
	m_pRoot = pRoot;
}

/**
 * Convert window coordinates (in pixels) to a ray from the camera
 * in world coordinates.
 */
bool vtScene::CameraRay(const IPoint2 &win, FPoint3 &pos, FPoint3 &dir)
{
	Vec3 near_point, far_point, diff;

	// call the handy OSG function
	m_pOsgSceneView->projectWindowXYIntoObject(win.x, m_WindowSize.y-win.y, near_point, far_point);

	diff = far_point - near_point;
	diff.normalize();

	s2v(near_point, pos);
	s2v(diff, dir);

	return true;
}

// Debugging helper
void LogCullPlanes(FPlane *planes)
{
	for (int i = 0; i < 4; i++)
		VTLOG(" plane %d: %.3f %.3f %.3f %.3f\n", i, planes[i].x, planes[i].y, planes[i].z, planes[i].w);
	VTLOG("\n");
}

void vtScene::CalcCullPlanes()
{
#if 0
	// Non-API-Specific code - will work correctly as long as the Camera
	// methods are fully functional.
	FMatrix4 mat;
	m_pCamera->GetTransform1(mat);

	assert(( m_WindowSize.x > 0 ) && ( m_WindowSize.y > 0 ));

	double fov = m_pCamera->GetFOV();

	double aspect = (float)m_WindowSize.y / m_WindowSize.x;
	double hither = m_pCamera->GetHither();

	double a = hither * tan(fov / 2);
	double b = a * aspect;

	FPoint3 vec_l(-a, 0, -hither);
	FPoint3 vec_r(a, 0, -hither);
	FPoint3 vec_t(0, b, -hither);
	FPoint3 vec_b(0, -b, -hither);

	vec_l.Normalize();
	vec_r.Normalize();
	vec_t.Normalize();
	vec_b.Normalize();

	FPoint3 up(0.0f, 1.0f, 0.0f);
	FPoint3 right(1.0f, 0.0f, 0.0f);

	FPoint3 temp;

	FPoint3 center;
	FPoint3 norm_l, norm_r, norm_t, norm_b;

	temp = up.Cross(vec_l);
	mat.TransformVector(temp, norm_l);

	temp = vec_r.Cross(up);
	mat.TransformVector(temp, norm_r);

	temp = right.Cross(vec_t);
	mat.TransformVector(temp, norm_t);

	temp = vec_b.Cross(right);
	mat.TransformVector(temp, norm_b);

	mat.Transform(FPoint3(0.0f, 0.0f, 0.0f), center);

	// set up m_cullPlanes in world coordinates!
	m_cullPlanes[0].Set(center, norm_l);
	m_cullPlanes[1].Set(center, norm_r);
	m_cullPlanes[2].Set(center, norm_t);
	m_cullPlanes[3].Set(center, norm_b);
#else
	// Get the view frustum clipping planes directly from OSG

	// OSG 0.8.44
//	const ClippingVolume &clipvol = pCam->m_pOsgCamera->getClippingVolume();
	// OSG 0.8.45
//	const ClippingVolume &clipvol = hack_global_state->getClippingVolume();
	// OSG 0.9.0
	// clipvol1 is the global camera frustum (in world coordinates)
//	const Polytope &clipvol1 = pCam->m_pOsgCamera->getViewFrustum();
	// OSG 0.9.6
	// clipvol2 is the camera's frustum after it's been transformed to the
	//		local coordinates.
//	const Polytope &clipvol2 = hack_global_state->getViewFrustum();
//	const Polytope::PlaneList &planes = clipvol2.getPlaneList();
	// Actually no - we can't get the planes from the state, because
	//  the state includes the funny modelview matrix used to scale
	//  the heightfield.  We must get it from the 'scene' instead.

	osg::Matrixd &_projection = m_pOsgSceneView->getProjectionMatrix();
	osg::Matrixd &_modelView = m_pOsgSceneView->getViewMatrix();

	Polytope tope;
	tope.setToUnitFrustum();
	tope.transformProvidingInverse((_modelView)*(_projection));

	const Polytope::PlaneList &planes = tope.getPlaneList();

	int i = 0;
	for (Polytope::PlaneList::const_iterator itr=planes.begin();
		itr!=planes.end(); ++itr)
	{
		// make a copy of the clipping plane
		Plane plane = *itr;

		// extract the OSG plane to our own structure
		Vec4 pvec = plane.asVec4();
		m_cullPlanes[i++].Set(-pvec.x(), -pvec.y(), -pvec.z(), -pvec.w());
	}
#endif

	// For debugging
//	LogCullPlanes(m_cullPlanes);
}

void vtScene::DrawFrameRateChart()
{
	static float fps[100];
	static int s = 0;
	fps[s] = GetFrameRate();

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

//	glMatrixMode(GL_PROJECTION);
//	glLoadIdentity();

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 1.0f, 0.0f);

	glBegin(GL_LINE_STRIP);
	for (int i = 1; i <= 100; i++)
	{
		glVertex3f(-1.0 + i/200.0f, -1.0f + fps[(s+i)%100]/200.0f, 0.0f);
	}
	glEnd();

	s++;
	if (s == 100) s = 0;
}

void vtScene::SetGlobalWireframe(bool bWire)
{
	m_bWireframe = bWire;

	// Set the scene's global PolygonMode attribute, which will affect all
	// other materials in the scene, except those which explicitly override
	// the attribute themselves.
	StateSet *global_state = m_pOsgSceneView->getGlobalStateSet();
	PolygonMode *npm = new PolygonMode();
	if (m_bWireframe)
		npm->setMode(PolygonMode::FRONT_AND_BACK, PolygonMode::LINE);
	else
		npm->setMode(PolygonMode::FRONT_AND_BACK, PolygonMode::FILL);
	global_state->setAttributeAndModes(npm, StateAttribute::ON);
}

bool vtScene::GetGlobalWireframe()
{
	return m_bWireframe;
}

void printnode(osg::Node *node, int tab) {
	for (int i = 0; i < tab*2; i++) {
	   osg::notify(osg::WARN) << " ";
	}
	osg::notify(osg::WARN) << node->className() << " - " << node->getName() << " @ " << node << std::endl;
	osg::Group *group = node->asGroup();
	if (group) {
		for (unsigned int i = 0; i < group->getNumChildren(); i++) {
			printnode(group->getChild(i), tab+1);
		}
	}
}

void vtScene::ShadowVisibleNode(vtNode *node, bool bVis)
{
	if (!bVis) {
		m_pShadowVisitor->shadow_ignore_nodes->Append(node->GetOsgNode());
	}
	else {
		int i = m_pShadowVisitor->shadow_ignore_nodes->Find(node->GetOsgNode());
		if (i != -1) {
			m_pShadowVisitor->shadow_ignore_nodes->RemoveAt(i);
		}
	}
	m_pShadowVisitor->RecomputeShadows();
}

void vtScene::SetShadowedNode(vtTransform *pLight, vtNode *pShadowNode,
							  vtTransform *pTransform, int iRez)
{
	if (!m_pShadowVisitor.valid())
		m_pShadowVisitor = new CreateProjectedShadowTextureCullCallback(pShadowNode->GetOsgNode(), iRez);
	else
		m_pShadowVisitor->SetShadower(pShadowNode->GetOsgNode());
		m_pShadowVisitor->SetInitialLightPosition(v2s(-(pLight->GetDirection()) * 10000));
		pTransform->GetOsgNode()->setCullCallback(m_pShadowVisitor.get());
		m_pShadowVisitor->SetEnabled(true);

		osg::Node *node = pShadowNode->GetOsgNode();

#ifdef _DEBUG
	{
		osg::Group *pGroup = (osg::Group*)pTransform->GetOsgNode();
		osg::Geode *pGeode = (osg::Geode*)pGroup->getChild(0);
		osg::Drawable* pDrawable = pGeode->getDrawable(0);
		pDrawable->setDrawCallback(new MyDrawCallback);
	}
#endif
}

void vtScene::UnsetShadowedNode(vtTransform *pTransform)
{
	pTransform->GetOsgNode()->setCullCallback(NULL);
#ifdef _DEBUG
	{
		osg::Group *pGroup = (osg::Group*)pTransform->GetOsgNode();
		osg::Geode *pGeode = (osg::Geode*)pGroup->getChild(0);
		osg::Drawable* pDrawable = pGeode->getDrawable(0);
		pDrawable->setDrawCallback(NULL);
	}
#endif
}

void vtScene::UpdateShadowLightDirection(vtTransform *pLight)
{
	if (m_pShadowVisitor.valid())
	{
		m_pShadowVisitor.get()->SetLightPosition(v2s(-(pLight->GetDirection()) * 10000));
	}
}

////////////////////////////////////////

<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision: 13308 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkProperty.h"

#include <mitkPicFileReader.h>
#include <mitkImage.h>
#include <mitkDataTree.h>
//#include <mitkImageMapper2D.h>
#include <mitkLevelWindow.h>
#include <mitkLevelWindowProperty.h>

#include <mitkVtkPropRenderer.h>
#include <vtkMitkRenderProp.h>
#include <mitkVtkLayerController.h>
#include <mitkNativeRenderWindowInteractor.h>

#include <fstream>
int mitkVtkPropRendererTest(int argc, char* argv[])
{
  //Read pic-Image from file
  std::cout << "Reading image: ";
	mitk::PicFileReader::Pointer reader = mitk::PicFileReader::New();
  reader->SetFileName(argv[1]);
  reader->Update();
  std::cout<<"[PASSED]"<<std::endl;

  mitk::Image::Pointer image = reader->GetOutput();

  std::cout << "Creating node: ";
  mitk::DataTreeNode::Pointer node = mitk::DataTreeNode::New();
  node->SetData(image);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating tree: ";
  mitk::DataTree* tree;
  (tree=mitk::DataTree::New())->Register(); //@FIXME: da DataTreeIteratorClone keinen Smartpointer auf DataTree hlt, wird tree sonst gelscht.
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating iterator on tree: ";
  mitk::DataTreePreOrderIterator it(tree);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Adding node via iterator: ";
  it.Add(node);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Adding level-window property: ";
  mitk::LevelWindowProperty::Pointer levWinProp = new mitk::LevelWindowProperty();
  mitk::LevelWindow levelwindow;
  levelwindow.SetAuto( image );
  levWinProp->SetLevelWindow( levelwindow );
  node->GetPropertyList()->SetProperty( "levelwindow", levWinProp );
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating a vtk sphere: ";
  vtkSphereSource *sphere = vtkSphereSource::New();
  sphere->SetRadius(1.0);
  sphere->SetThetaResolution(18);
  sphere->SetPhiResolution(18);

  vtkPolyDataMapper *map = vtkPolyDataMapper::New();
  map->SetInput(sphere->GetOutput());

  vtkActor *aSphere = vtkActor::New();
  aSphere->SetMapper(map);
  aSphere->GetProperty()->SetColor(0,0,1); // sphere color blue
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating a renderer for the sphere: ";
  vtkRenderer *sphereRenderer = vtkRenderer::New();
  sphereRenderer->AddActor(aSphere);
  //sphereRenderer->SetBackground(1,1,1); // Background color white
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating vtkRenderWindow and VtkPropRenderer: ";
  vtkRenderWindow *renderWindow = vtkRenderWindow::New();
  mitk::VtkPropRenderer *propRenderer = new mitk::VtkPropRenderer( "the renderer", renderWindow );
  //propRenderer->SetMapperID(2);
  std::cout<<"[PASSED]"<<std::endl;

  //renderWindow->AddRenderer(sphereRenderer);
  //renderWindow->SetErase(0);

  std::cout << "BaseRenderer::SetData(iterator): ";
  propRenderer->SetData(&it);
  std::cout<<"[PASSED]"<<std::endl;

  //std::cout << "Testing if an mitk::ImageMapper2D was created: ";
  //if(dynamic_cast<mitk::ImageMapper2D*>(node->GetMapper(1))==NULL)
  //{
  //  std::cout<<"[FAILED]"<<std::endl;
  //  return EXIT_FAILURE;
  //}
  //std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating vtkMitkRenderProp and connecting it to the VtkPropRenderer: ";
  vtkMitkRenderProp* renderProp = vtkMitkRenderProp::New();
  renderProp->SetPropRenderer(propRenderer);
  propRenderer->GetVtkRenderer()->AddViewProp(renderProp);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Inserting the sphere into the foreground of the VtkLayerController: ";
  mitk::VtkLayerController::GetInstance(renderWindow)->InsertForegroundRenderer(sphereRenderer,true);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Do the rendering: ";
  renderWindow->Render();
  std::cout<<"[PASSED]"<<std::endl;

  // mouse interaction for debugging
  //vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  //iren->SetRenderWindow(renderWindow);
  //iren->Start();

  renderWindow->Delete();
  tree = NULL; // As the tree has been registered explicitely, destroy it again.

  std::cout<<"[TEST DONE]"<<std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>FIX: run test only on pic images<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision: 13308 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkProperty.h"

#include <mitkPicFileReader.h>
#include <mitkImage.h>
#include <mitkDataTree.h>
//#include <mitkImageMapper2D.h>
#include <mitkLevelWindow.h>
#include <mitkLevelWindowProperty.h>

#include <mitkVtkPropRenderer.h>
#include <vtkMitkRenderProp.h>
#include <mitkVtkLayerController.h>
#include <mitkNativeRenderWindowInteractor.h>

#include <itksys/SystemTools.hxx>

#include <fstream>
int mitkVtkPropRendererTest(int argc, char* argv[])
{
  //independently read header of pic file
  ipPicDescriptor *picheader=NULL;
  if(argc>=1)
  {
    if(itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameExtension(argv[1])).find(".pic")!=std::string::npos)
      picheader = ipPicGetHeader(argv[1], NULL);
  }
  if(picheader==NULL)
  {
    std::cout<<"file not found/not a pic-file - test not applied [PASSED]"<<std::endl;
    std::cout<<"[TEST DONE]"<<std::endl;
    return EXIT_SUCCESS;
  }
  ipPicGetTags(argv[1], picheader);

  //Read pic-Image from file
  std::cout << "Reading image: ";
	mitk::PicFileReader::Pointer reader = mitk::PicFileReader::New();
  reader->SetFileName(argv[1]);
  reader->Update();
  std::cout<<"[PASSED]"<<std::endl;

  mitk::Image::Pointer image = reader->GetOutput();

  std::cout << "Creating node: ";
  mitk::DataTreeNode::Pointer node = mitk::DataTreeNode::New();
  node->SetData(image);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating tree: ";
  mitk::DataTree* tree;
  (tree=mitk::DataTree::New())->Register(); //@FIXME: da DataTreeIteratorClone keinen Smartpointer auf DataTree hlt, wird tree sonst gelscht.
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating iterator on tree: ";
  mitk::DataTreePreOrderIterator it(tree);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Adding node via iterator: ";
  it.Add(node);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Adding level-window property: ";
  mitk::LevelWindowProperty::Pointer levWinProp = new mitk::LevelWindowProperty();
  mitk::LevelWindow levelwindow;
  levelwindow.SetAuto( image );
  levWinProp->SetLevelWindow( levelwindow );
  node->GetPropertyList()->SetProperty( "levelwindow", levWinProp );
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating a vtk sphere: ";
  vtkSphereSource *sphere = vtkSphereSource::New();
  sphere->SetRadius(1.0);
  sphere->SetThetaResolution(18);
  sphere->SetPhiResolution(18);

  vtkPolyDataMapper *map = vtkPolyDataMapper::New();
  map->SetInput(sphere->GetOutput());

  vtkActor *aSphere = vtkActor::New();
  aSphere->SetMapper(map);
  aSphere->GetProperty()->SetColor(0,0,1); // sphere color blue
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating a renderer for the sphere: ";
  vtkRenderer *sphereRenderer = vtkRenderer::New();
  sphereRenderer->AddActor(aSphere);
  //sphereRenderer->SetBackground(1,1,1); // Background color white
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating vtkRenderWindow and VtkPropRenderer: ";
  vtkRenderWindow *renderWindow = vtkRenderWindow::New();
  mitk::VtkPropRenderer *propRenderer = new mitk::VtkPropRenderer( "the renderer", renderWindow );
  //propRenderer->SetMapperID(2);
  std::cout<<"[PASSED]"<<std::endl;

  //renderWindow->AddRenderer(sphereRenderer);
  //renderWindow->SetErase(0);

  std::cout << "BaseRenderer::SetData(iterator): ";
  propRenderer->SetData(&it);
  std::cout<<"[PASSED]"<<std::endl;

  //std::cout << "Testing if an mitk::ImageMapper2D was created: ";
  //if(dynamic_cast<mitk::ImageMapper2D*>(node->GetMapper(1))==NULL)
  //{
  //  std::cout<<"[FAILED]"<<std::endl;
  //  return EXIT_FAILURE;
  //}
  //std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Creating vtkMitkRenderProp and connecting it to the VtkPropRenderer: ";
  vtkMitkRenderProp* renderProp = vtkMitkRenderProp::New();
  renderProp->SetPropRenderer(propRenderer);
  propRenderer->GetVtkRenderer()->AddViewProp(renderProp);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Inserting the sphere into the foreground of the VtkLayerController: ";
  mitk::VtkLayerController::GetInstance(renderWindow)->InsertForegroundRenderer(sphereRenderer,true);
  std::cout<<"[PASSED]"<<std::endl;

  std::cout << "Do the rendering: ";
  renderWindow->Render();
  std::cout<<"[PASSED]"<<std::endl;

  // mouse interaction for debugging
  //vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  //iren->SetRenderWindow(renderWindow);
  //iren->Start();

  renderWindow->Delete();
  tree = NULL; // As the tree has been registered explicitely, destroy it again.

  std::cout<<"[TEST DONE]"<<std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <webkit2/webkit-web-extension.h>
#include <JavaScriptCore/JavaScript.h>
#include <string.h>
#include <soup.h>
#include "utils.h"

static WebKitWebExtension* extension;

static guint idLogHandler = 0;
static guint idSendRequestHandler = 0;
static guint idPageCreatedHandler = 0;
static gboolean DEBUG = FALSE;

static gchar* JSValueToStr(JSGlobalContextRef context, JSValueRef val) {
	JSStringRef js_str_value = JSValueToStringCopy(context, val, NULL);
	gsize str_length = JSStringGetMaximumUTF8CStringSize(js_str_value);
	gchar* str_value = (gchar*)g_malloc(str_length);
	JSStringGetUTF8CString(js_str_value, str_value, str_length);
	JSStringRelease(js_str_value);
	return str_value;
}

static gboolean web_page_send_request(WebKitWebPage* page, WebKitURIRequest* request, WebKitURIResponse* redirected_response, gpointer data) {
	gchar* cstamp = (gchar*)data;
	const char* uri = webkit_uri_request_get_uri(request);

	// always allow blank and never report it
	if (uri == NULL || g_strcmp0(uri, "") == 0 || g_strcmp0(uri, "about:blank") == 0) return FALSE;

	JSValueRef result;
	JSValueRef exception;
	gboolean hasHandler = FALSE;
	JSGlobalContextRef jsContext = webkit_frame_get_javascript_context_for_script_world(
		webkit_web_page_get_main_frame(page),
		webkit_script_world_get_default()
	);

	const char* funcStr = g_strconcat("window.request_", cstamp, NULL);

	JSStringRef funcScript = JSStringCreateWithUTF8CString(g_strconcat("!!(", funcStr, ")", NULL));
	exception = NULL;
	result = JSEvaluateScript(
		jsContext,
		funcScript,
		NULL, // JSObjectRef thisObject
		NULL, // JSStringRef sourceURL
		0, // int startingLineNumber
		&exception  // JSValueRef* exception
	);
	if (exception != NULL) {
		gchar* exceptionStr = JSValueToStr(jsContext, exception);
		g_warning("%s, while checking availability of filter function handler", exceptionStr);
		g_free(exceptionStr);
	}
	if (JSValueIsBoolean(jsContext, result)) {
		hasHandler = JSValueToBoolean(jsContext, result);
	} else {
		g_warning("Invalid value returned while checking availability of filter function handler");
	}

	if (hasHandler == FALSE) {
		g_message("No filter handler available to check %s", uri);
		return FALSE;
	}

	const gchar* redirect = "";

	if (redirected_response != NULL) {
		g_message("request %s is redirected to %s", uri, webkit_uri_response_get_uri(redirected_response));
		redirect = webkit_uri_response_get_uri(redirected_response);
	}

	const gchar* scriptStr = g_strconcat(funcStr, "(\"", uri, "\", \"", redirect, "\")", NULL);
	JSStringRef script = JSStringCreateWithUTF8CString(scriptStr);
	exception = NULL;
	result = JSEvaluateScript(
		jsContext,
		script,
		NULL, // JSObjectRef thisObject
		NULL, // JSStringRef sourceURL
		0, // int startingLineNumber
		&exception  // JSValueRef* exception
	);

	if (exception != NULL) {
		gchar* exceptionStr = JSValueToStr(jsContext, exception);
		g_warning("%s, while running filter function handler", exceptionStr);
		g_free(exceptionStr);
	}

	if (JSValueIsBoolean(jsContext, result)) {
		if (JSValueToBoolean(jsContext, result)) {
			// go through
			g_message("accept %s", uri);
		} else {
			g_message("reject %s", uri);
			webkit_uri_request_set_uri(request, g_strconcat("#", uri, NULL));
		}
	} else if (JSValueIsString(jsContext, result)) {
		gchar* str_value = JSValueToStr(jsContext, result);
		g_message("rewrite %s to %s", uri, str_value);
		webkit_uri_request_set_uri(request, str_value);
		g_free(str_value);
	} else {
		// no return value - meaning ignore the request
		g_message("ignore %s", uri);
	}

	return FALSE;
}

static void web_page_created_callback(WebKitWebExtension* ext, WebKitWebPage* web_page, gpointer data) {
	g_message("page created");
	if (idSendRequestHandler > 0) {
		g_signal_handler_disconnect(web_page, idSendRequestHandler);
		idSendRequestHandler = 0;
	}
	idSendRequestHandler = g_signal_connect(web_page, "send-request", G_CALLBACK(web_page_send_request), data);
}

static void ttyLog(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
	if ((log_level & G_LOG_LEVEL_WARNING) == 0 && DEBUG == FALSE) return;
	FILE* ftty = fopen("/dev/tty", "a");
	if (ftty == NULL) {
		return;
	}
	fprintf(ftty, "%s\n", message);
	fclose(ftty);
}

extern "C" {
	G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension* ext, const GVariant* constData) {
		const gchar* envDebug = g_getenv("DEBUG");
		if (envDebug != NULL) {
			gchar** envStrv = g_strsplit(envDebug, ",", -1);
			if (g_strv_contains(envStrv, "webkitgtk:extension")) {
				DEBUG = TRUE;
			}
			g_strfreev(envStrv);
		}

		extension = ext;
		idLogHandler = g_log_set_handler(
			NULL,
			G_LOG_LEVEL_MASK,
			ttyLog,
			NULL
		);
		gchar* cstamp;
		g_variant_get((GVariant*)constData, "(s)", &cstamp);
		idPageCreatedHandler = g_signal_connect(extension, "page-created", G_CALLBACK(web_page_created_callback), cstamp);
	}
}

static void __attribute__((destructor))
webkit_web_extension_destroy (void) {
	g_message("extension destroyed");
	g_log_remove_handler(NULL, idLogHandler);

	if (idPageCreatedHandler > 0) {
		g_signal_handler_disconnect(extension, idPageCreatedHandler);
		idPageCreatedHandler = 0;
	}
	g_object_unref(extension);
	extension = NULL;
}
<commit_msg>Improve debug message<commit_after>#include <webkit2/webkit-web-extension.h>
#include <JavaScriptCore/JavaScript.h>
#include <string.h>
#include <soup.h>
#include "utils.h"

static WebKitWebExtension* extension;

static guint idLogHandler = 0;
static guint idSendRequestHandler = 0;
static guint idPageCreatedHandler = 0;
static gboolean DEBUG = FALSE;

static gchar* JSValueToStr(JSGlobalContextRef context, JSValueRef val) {
	JSStringRef js_str_value = JSValueToStringCopy(context, val, NULL);
	gsize str_length = JSStringGetMaximumUTF8CStringSize(js_str_value);
	gchar* str_value = (gchar*)g_malloc(str_length);
	JSStringGetUTF8CString(js_str_value, str_value, str_length);
	JSStringRelease(js_str_value);
	return str_value;
}

static gboolean web_page_send_request(WebKitWebPage* page, WebKitURIRequest* request, WebKitURIResponse* redirected_response, gpointer data) {
	gchar* cstamp = (gchar*)data;
	const char* uri = webkit_uri_request_get_uri(request);

	// always allow blank and never report it
	if (uri == NULL || g_strcmp0(uri, "") == 0 || g_strcmp0(uri, "about:blank") == 0) return FALSE;

	JSValueRef result;
	JSValueRef exception;
	gboolean hasHandler = FALSE;
	JSGlobalContextRef jsContext = webkit_frame_get_javascript_context_for_script_world(
		webkit_web_page_get_main_frame(page),
		webkit_script_world_get_default()
	);

	const char* funcStr = g_strconcat("window.request_", cstamp, NULL);

	JSStringRef funcScript = JSStringCreateWithUTF8CString(g_strconcat("!!(", funcStr, ")", NULL));
	exception = NULL;
	result = JSEvaluateScript(
		jsContext,
		funcScript,
		NULL, // JSObjectRef thisObject
		NULL, // JSStringRef sourceURL
		0, // int startingLineNumber
		&exception  // JSValueRef* exception
	);
	if (exception != NULL) {
		gchar* exceptionStr = JSValueToStr(jsContext, exception);
		g_warning("%s, while checking availability of filter function handler", exceptionStr);
		g_free(exceptionStr);
	}
	if (JSValueIsBoolean(jsContext, result)) {
		hasHandler = JSValueToBoolean(jsContext, result);
	} else {
		g_warning("Invalid value returned while checking availability of filter function handler");
	}

	if (hasHandler == FALSE) {
		g_message("No filter handler %s available to check %s", funcStr, uri);
		return FALSE;
	}

	const gchar* redirect = "";

	if (redirected_response != NULL) {
		g_message("request %s is redirected to %s", uri, webkit_uri_response_get_uri(redirected_response));
		redirect = webkit_uri_response_get_uri(redirected_response);
	}

	const gchar* scriptStr = g_strconcat(funcStr, "(\"", uri, "\", \"", redirect, "\")", NULL);
	JSStringRef script = JSStringCreateWithUTF8CString(scriptStr);
	exception = NULL;
	result = JSEvaluateScript(
		jsContext,
		script,
		NULL, // JSObjectRef thisObject
		NULL, // JSStringRef sourceURL
		0, // int startingLineNumber
		&exception  // JSValueRef* exception
	);

	if (exception != NULL) {
		gchar* exceptionStr = JSValueToStr(jsContext, exception);
		g_warning("%s, while running filter function handler", exceptionStr);
		g_free(exceptionStr);
	}

	if (JSValueIsBoolean(jsContext, result)) {
		if (JSValueToBoolean(jsContext, result)) {
			// go through
			g_message("accept %s", uri);
		} else {
			g_message("reject %s", uri);
			webkit_uri_request_set_uri(request, g_strconcat("#", uri, NULL));
		}
	} else if (JSValueIsString(jsContext, result)) {
		gchar* str_value = JSValueToStr(jsContext, result);
		g_message("rewrite %s to %s", uri, str_value);
		webkit_uri_request_set_uri(request, str_value);
		g_free(str_value);
	} else {
		// no return value - meaning ignore the request
		g_message("ignore %s", uri);
	}

	return FALSE;
}

static void web_page_created_callback(WebKitWebExtension* ext, WebKitWebPage* web_page, gpointer data) {
	g_message("page created");
	if (idSendRequestHandler > 0) {
		g_signal_handler_disconnect(web_page, idSendRequestHandler);
		idSendRequestHandler = 0;
	}
	idSendRequestHandler = g_signal_connect(web_page, "send-request", G_CALLBACK(web_page_send_request), data);
}

static void ttyLog(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
	if ((log_level & G_LOG_LEVEL_WARNING) == 0 && DEBUG == FALSE) return;
	FILE* ftty = fopen("/dev/tty", "a");
	if (ftty == NULL) {
		return;
	}
	fprintf(ftty, "%s\n", message);
	fclose(ftty);
}

extern "C" {
	G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension* ext, const GVariant* constData) {
		const gchar* envDebug = g_getenv("DEBUG");
		if (envDebug != NULL) {
			gchar** envStrv = g_strsplit(envDebug, ",", -1);
			if (g_strv_contains(envStrv, "webkitgtk:extension")) {
				DEBUG = TRUE;
			}
			g_strfreev(envStrv);
		}

		extension = ext;
		idLogHandler = g_log_set_handler(
			NULL,
			G_LOG_LEVEL_MASK,
			ttyLog,
			NULL
		);
		gchar* cstamp;
		g_variant_get((GVariant*)constData, "(s)", &cstamp);
		idPageCreatedHandler = g_signal_connect(extension, "page-created", G_CALLBACK(web_page_created_callback), cstamp);
	}
}

static void __attribute__((destructor))
webkit_web_extension_destroy (void) {
	g_message("extension destroyed");
	g_log_remove_handler(NULL, idLogHandler);

	if (idPageCreatedHandler > 0) {
		g_signal_handler_disconnect(extension, idPageCreatedHandler);
		idPageCreatedHandler = 0;
	}
	g_object_unref(extension);
	extension = NULL;
}
<|endoftext|>


<commit_before>//
//  CodeGeneratorCPP.cpp
//  Protocol
//
//  Created by Wahid Tanner on 10/17/14.
//

#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/fstream.hpp>

#include "CodeGeneratorCPP.h"

using namespace std;
using namespace boost;
using namespace MuddledManaged;

const std::string Protocol::CodeGeneratorCPP::mHeaderFileExtension = ".protocol.h";
const std::string Protocol::CodeGeneratorCPP::mSourceFileExtension = ".protocol.cpp";
const std::string Protocol::CodeGeneratorCPP::mHeaderFileProlog =
"// This file was generated from the Protocol compiler.\n"
"// You should not edit this file directly.\n";
const std::string Protocol::CodeGeneratorCPP::mSourceFileProlog =
"// This file was generated from the Protocol compiler.\n"
"// You should not edit this file directly.\n";

Protocol::CodeGeneratorCPP::CodeGeneratorCPP ()
{ }

void Protocol::CodeGeneratorCPP::generateCode (const string & outputFolder, const ProtoModel & model)
{
    filesystem::path outputPath(outputFolder);
    filesystem::path modelPath(model.fileName());
    filesystem::path headerPath(outputPath / filesystem::change_extension(modelPath, mHeaderFileExtension));
    filesystem::path sourcePath(outputPath / filesystem::change_extension(modelPath, mSourceFileExtension));

    filesystem::create_directory(outputFolder);
    filesystem::ofstream headerFile(headerPath);
    filesystem::ofstream sourceFile(sourcePath);

    headerFile << mHeaderFileProlog << endl;
    sourceFile << mSourceFileProlog << endl;

    sourceFile.close();
    headerFile.close();
}
<commit_msg>Ensure files are opened and truncated and removed explicit close call.<commit_after>//
//  CodeGeneratorCPP.cpp
//  Protocol
//
//  Created by Wahid Tanner on 10/17/14.
//

#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/fstream.hpp>

#include "CodeGeneratorCPP.h"

using namespace std;
using namespace boost;
using namespace MuddledManaged;

const std::string Protocol::CodeGeneratorCPP::mHeaderFileExtension = ".protocol.h";
const std::string Protocol::CodeGeneratorCPP::mSourceFileExtension = ".protocol.cpp";
const std::string Protocol::CodeGeneratorCPP::mHeaderFileProlog =
"// This file was generated from the Protocol compiler.\n"
"// You should not edit this file directly.\n";
const std::string Protocol::CodeGeneratorCPP::mSourceFileProlog =
"// This file was generated from the Protocol compiler.\n"
"// You should not edit this file directly.\n";

Protocol::CodeGeneratorCPP::CodeGeneratorCPP ()
{ }

void Protocol::CodeGeneratorCPP::generateCode (const string & outputFolder, const ProtoModel & model)
{
    filesystem::path outputPath(outputFolder);
    filesystem::path modelPath(model.fileName());
    filesystem::path headerPath(outputPath / filesystem::change_extension(modelPath, mHeaderFileExtension));
    filesystem::path sourcePath(outputPath / filesystem::change_extension(modelPath, mSourceFileExtension));

    filesystem::create_directory(outputFolder);
    filesystem::ofstream headerFile(headerPath, ios::out | ios::trunc);
    filesystem::ofstream sourceFile(sourcePath, ios::out | ios::trunc);

    headerFile << mHeaderFileProlog << endl;
    sourceFile << mSourceFileProlog << endl;
}
<|endoftext|>


<commit_before>/*
 * HashingOverlapper.cpp
 *
 *  Created on: 31.01.2013
 *      Author: Christian Staudt (christian.staudt@kit.edu)
 */

#include "HashingOverlapper.h"

namespace NetworKit {

HashingOverlapper::HashingOverlapper() {
	// TODO Auto-generated constructor stub

}

HashingOverlapper::~HashingOverlapper() {
	// TODO Auto-generated destructor stub
}

Clustering HashingOverlapper::run(Graph& G,
		std::vector<Clustering>& clusterings) {

	DEBUG("Starting hashing overlapper");

	// hash function sdbm
	auto sdbm = [](int64_t cid) {
		unsigned char* str = (unsigned char*) &cid;
		unsigned long h = 0;
		int c;
		while ((c = *str++)) {
			h = c + (h << 6) + (h << 16) - h;
		}
		return h;
	};

	auto djb2 = [](int64_t cid) {
		unsigned char* str = (unsigned char*) &cid;
		unsigned long hash = 5381;
		int c;
		while ((c = *str++)) {
			hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
		}
		return hash;
	};

	count n = G.numberOfNodes();
	Clustering core(n);

	// select hash function
	auto hash = djb2;

	core.setAll(0);
	for (index c = 0; c < clusterings.size(); ++c) {
		Clustering& zeta = clusterings[c];
		zeta.parallelForEntries([&](node v, cluster clv) {
			core[v] += (hash((c+2) * clv) & 0xffff);
		});
	}
	core.compact();

	return core;
}

} /* namespace NetworKit */
<commit_msg>modified hashing scheme for two clusterings<commit_after>/*
 * HashingOverlapper.cpp
 *
 *  Created on: 31.01.2013
 *      Author: Christian Staudt (christian.staudt@kit.edu)
 */

#include "HashingOverlapper.h"

namespace NetworKit {

HashingOverlapper::HashingOverlapper() {
	// TODO Auto-generated constructor stub

}

HashingOverlapper::~HashingOverlapper() {
	// TODO Auto-generated destructor stub
}

Clustering HashingOverlapper::run(Graph& G,
		std::vector<Clustering>& clusterings) {

	DEBUG("Starting hashing overlapper");

	// hash function sdbm
	auto sdbm = [](int64_t cid) {
		unsigned char* str = (unsigned char*) &cid;
		unsigned long h = 0;
		int c;
		while ((c = *str++)) {
			h = c + (h << 6) + (h << 16) - h;
		}
		return h;
	};

	auto djb2 = [](int64_t cid) {
		unsigned char* str = (unsigned char*) &cid;
		unsigned long hash = 5381;
		int c;
		while ((c = *str++)) {
			hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
		}
		return hash;
	};

	count n = G.numberOfNodes();
	Clustering core(n);

	// select hash function
	auto hash = djb2;

	core.setAll(0);
	const count numC = clusterings.size();
	const count upperId = clusterings.back().upperBound();
	if (numC > 2) {
		for (index c = 0; c < numC; ++c) {
			Clustering& zeta = clusterings[c];
			zeta.parallelForEntries([&](node v, cluster clv) {
				core[v] += (hash((c+2) * clv) & 0xffff);
			});
		}
	}
	else {
		Clustering& first = clusterings[0];
		Clustering& second = clusterings[1];

		// Assumption: second has at least as many nodes as first
		G.parallelForNodes([&](node v) {
			if (v >= first.numberOfEntries()) {
				core[v] = none;
			}
			else {
				if (first[v] == none || second[v] == none) {
					core[v] = none;
				}
				else {
					count key = ((first[v] & 0xffff) << 16) | (second[v] & 0xffff);
					core[v] = hash(key);
				}
			}
		});
	}

	core.compact();

	return core;
}

} /* namespace NetworKit */
<|endoftext|>


<commit_before>/* Copyright (c) 2013-2022 Jeffrey Pfau
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/ */
#include "ForwarderView.h"

#include <QMessageBox>
#include <QResizeEvent>

#include "ForwarderGenerator.h"
#include "GBAApp.h"
#include "utils.h"

using namespace QGBA;

ForwarderView::ForwarderView(QWidget* parent)
	: QDialog(parent)
{
	m_ui.setupUi(this);

	connectBrowseButton(m_ui.romBrowse, m_ui.romFilename, tr("Select ROM file"), false, romFilters());
	connectBrowseButton(m_ui.outputBrowse, m_ui.outputFilename, tr("Select output filename"), true);
	connectBrowseButton(m_ui.baseBrowse, m_ui.baseFilename, tr("Select base file"));

	connect(m_ui.romFilename, &QLineEdit::textChanged, this, &ForwarderView::validate);
	connect(m_ui.outputFilename, &QLineEdit::textChanged, this, &ForwarderView::validate);
	connect(m_ui.baseFilename, &QLineEdit::textChanged, this, &ForwarderView::validate);
	connect(m_ui.title, &QLineEdit::textChanged, this, &ForwarderView::validate);
	connect(m_ui.baseType, qOverload<int>(&QComboBox::currentIndexChanged), this, &ForwarderView::validate);

	connect(m_ui.imageSelect, qOverload<int>(&QComboBox::currentIndexChanged), this, &ForwarderView::setActiveImage);
	connect(m_ui.imageBrowse, &QAbstractButton::clicked, this, &ForwarderView::selectImage);

	connect(&m_controller, &ForwarderController::buildComplete, this, &QDialog::accept);
	connect(&m_controller, &ForwarderController::buildFailed, this, [this]() {
		QMessageBox* error = new QMessageBox(QMessageBox::Critical, tr("Build failed"),
		                                     tr("Failed to build forwarder"),
		                                     QMessageBox::Ok, this, Qt::Sheet);
		error->setAttribute(Qt::WA_DeleteOnClose);
		error->show();
	});

	connect(m_ui.system3DS, &QAbstractButton::clicked, this, [this]() {
		setSystem(ForwarderGenerator::System::N3DS);
	});
	connect(m_ui.systemVita, &QAbstractButton::clicked, this, [this]() {
		setSystem(ForwarderGenerator::System::VITA);
	});

	m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
	connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, [this]() {
		m_controller.generator()->setRom(m_ui.romFilename->text());
		m_controller.startBuild(m_ui.outputFilename->text());
	});
}

void ForwarderView::build() {
	if (!m_controller.generator()) {
		return;
	}
	m_controller.generator()->setTitle(m_ui.title->text());
	m_controller.generator()->setRom(m_ui.romFilename->text());
	m_controller.startBuild(m_ui.outputFilename->text());
}

void ForwarderView::validate() {
	bool valid = true;
	if (m_ui.romFilename->text().isEmpty()) {
		valid = false;
	} else if (!QFileInfo(m_ui.romFilename->text()).exists()) {
		valid = false;
	}
	if (m_ui.outputFilename->text().isEmpty()) {
		valid = false;
	}
	if (m_ui.title->text().isEmpty()) {
		valid = false;
	}
	if (!m_ui.system->checkedButton()) {
		valid = false;
	}
	if (m_ui.baseType->currentIndex() != 1) {
		valid = false;
	}
	m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
}

void ForwarderView::setSystem(ForwarderGenerator::System system) {
	m_controller.setGenerator(ForwarderGenerator::createForSystem(system));
	auto types = m_controller.generator()->imageTypes();
	m_images.clear();
	m_images.resize(types.count());
	m_ui.imageSelect->clear();
	for (const auto& pair : types) {
		m_ui.imageSelect->addItem(pair.first);
	}
	m_ui.imageSelect->setEnabled(true);
	m_ui.imagePreview->setEnabled(true);
	m_ui.imageBrowse->setEnabled(true);
	m_ui.imagesLabel->setEnabled(true);
	m_ui.preferredLabel->setEnabled(true);
	m_ui.preferredWidth->setEnabled(true);
	m_ui.preferredX->setEnabled(true);
	m_ui.preferredHeight->setEnabled(true);
}

void ForwarderView::connectBrowseButton(QAbstractButton* button, QLineEdit* lineEdit, const QString& title, bool save, const QString& filter) {
	connect(button, &QAbstractButton::clicked, lineEdit, [this, lineEdit, save, title, filter]() {
		QString filename;
		if (save) {
			filename = GBAApp::app()->getSaveFileName(this, title, filter);
		} else {
			filename = GBAApp::app()->getOpenFileName(this, title, filter);
		}
		if (filename.isEmpty()) {
			return;
		}
		lineEdit->setText(filename);
	});
}

void ForwarderView::selectImage() {
	QString filename = GBAApp::app()->getOpenFileName(this, tr("Select an image"), {});
	if (filename.isEmpty()) {
		return;
	}

	QImage image(filename);
	if (image.isNull()) {
		return;
	}
	image = image.scaled(m_activeSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

	m_ui.imagePreview->setPixmap(QPixmap::fromImage(image));
	m_ui.useDefaultImage->setChecked(false);
	m_controller.generator()->setImage(m_currentImage, image);
}

void ForwarderView::setActiveImage(int index) {
	if (index < 0) {
		m_currentImage = -1;
		m_activeSize = QSize();
		return;
	}
	if (!m_controller.generator()) {
		return;
	}
	auto types = m_controller.generator()->imageTypes();
	if (index >= types.count()) {
		return;
	}
	m_currentImage = index;
	m_activeSize = types[index].second;
	m_ui.preferredWidth->setText(QString::number(m_activeSize.width()));
	m_ui.preferredHeight->setText(QString::number(m_activeSize.height()));
	m_ui.imagePreview->setMaximumSize(m_activeSize);
	m_ui.imagePreview->setPixmap(QPixmap::fromImage(m_controller.generator()->image(index)));
}
<commit_msg>Qt: I wrote a function for this...<commit_after>/* Copyright (c) 2013-2022 Jeffrey Pfau
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/ */
#include "ForwarderView.h"

#include <QMessageBox>
#include <QResizeEvent>

#include "ForwarderGenerator.h"
#include "GBAApp.h"
#include "utils.h"

using namespace QGBA;

ForwarderView::ForwarderView(QWidget* parent)
	: QDialog(parent)
{
	m_ui.setupUi(this);

	connectBrowseButton(m_ui.romBrowse, m_ui.romFilename, tr("Select ROM file"), false, romFilters());
	connectBrowseButton(m_ui.outputBrowse, m_ui.outputFilename, tr("Select output filename"), true);
	connectBrowseButton(m_ui.baseBrowse, m_ui.baseFilename, tr("Select base file"));

	connect(m_ui.romFilename, &QLineEdit::textChanged, this, &ForwarderView::validate);
	connect(m_ui.outputFilename, &QLineEdit::textChanged, this, &ForwarderView::validate);
	connect(m_ui.baseFilename, &QLineEdit::textChanged, this, &ForwarderView::validate);
	connect(m_ui.title, &QLineEdit::textChanged, this, &ForwarderView::validate);
	connect(m_ui.baseType, qOverload<int>(&QComboBox::currentIndexChanged), this, &ForwarderView::validate);

	connect(m_ui.imageSelect, qOverload<int>(&QComboBox::currentIndexChanged), this, &ForwarderView::setActiveImage);
	connect(m_ui.imageBrowse, &QAbstractButton::clicked, this, &ForwarderView::selectImage);

	connect(&m_controller, &ForwarderController::buildComplete, this, &QDialog::accept);
	connect(&m_controller, &ForwarderController::buildFailed, this, [this]() {
		QMessageBox* error = new QMessageBox(QMessageBox::Critical, tr("Build failed"),
		                                     tr("Failed to build forwarder"),
		                                     QMessageBox::Ok, this, Qt::Sheet);
		error->setAttribute(Qt::WA_DeleteOnClose);
		error->show();
	});

	connect(m_ui.system3DS, &QAbstractButton::clicked, this, [this]() {
		setSystem(ForwarderGenerator::System::N3DS);
	});
	connect(m_ui.systemVita, &QAbstractButton::clicked, this, [this]() {
		setSystem(ForwarderGenerator::System::VITA);
	});

	m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
	connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &ForwarderView::build);
}

void ForwarderView::build() {
	if (!m_controller.generator()) {
		return;
	}
	m_controller.generator()->setTitle(m_ui.title->text());
	m_controller.generator()->setRom(m_ui.romFilename->text());
	m_controller.startBuild(m_ui.outputFilename->text());
}

void ForwarderView::validate() {
	bool valid = true;
	if (m_ui.romFilename->text().isEmpty()) {
		valid = false;
	} else if (!QFileInfo(m_ui.romFilename->text()).exists()) {
		valid = false;
	}
	if (m_ui.outputFilename->text().isEmpty()) {
		valid = false;
	}
	if (m_ui.title->text().isEmpty()) {
		valid = false;
	}
	if (!m_ui.system->checkedButton()) {
		valid = false;
	}
	if (m_ui.baseType->currentIndex() != 1) {
		valid = false;
	}
	m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
}

void ForwarderView::setSystem(ForwarderGenerator::System system) {
	m_controller.setGenerator(ForwarderGenerator::createForSystem(system));
	auto types = m_controller.generator()->imageTypes();
	m_images.clear();
	m_images.resize(types.count());
	m_ui.imageSelect->clear();
	for (const auto& pair : types) {
		m_ui.imageSelect->addItem(pair.first);
	}
	m_ui.imageSelect->setEnabled(true);
	m_ui.imagePreview->setEnabled(true);
	m_ui.imageBrowse->setEnabled(true);
	m_ui.imagesLabel->setEnabled(true);
	m_ui.preferredLabel->setEnabled(true);
	m_ui.preferredWidth->setEnabled(true);
	m_ui.preferredX->setEnabled(true);
	m_ui.preferredHeight->setEnabled(true);
}

void ForwarderView::connectBrowseButton(QAbstractButton* button, QLineEdit* lineEdit, const QString& title, bool save, const QString& filter) {
	connect(button, &QAbstractButton::clicked, lineEdit, [this, lineEdit, save, title, filter]() {
		QString filename;
		if (save) {
			filename = GBAApp::app()->getSaveFileName(this, title, filter);
		} else {
			filename = GBAApp::app()->getOpenFileName(this, title, filter);
		}
		if (filename.isEmpty()) {
			return;
		}
		lineEdit->setText(filename);
	});
}

void ForwarderView::selectImage() {
	QString filename = GBAApp::app()->getOpenFileName(this, tr("Select an image"), {});
	if (filename.isEmpty()) {
		return;
	}

	QImage image(filename);
	if (image.isNull()) {
		return;
	}
	image = image.scaled(m_activeSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

	m_ui.imagePreview->setPixmap(QPixmap::fromImage(image));
	m_ui.useDefaultImage->setChecked(false);
	m_controller.generator()->setImage(m_currentImage, image);
}

void ForwarderView::setActiveImage(int index) {
	if (index < 0) {
		m_currentImage = -1;
		m_activeSize = QSize();
		return;
	}
	if (!m_controller.generator()) {
		return;
	}
	auto types = m_controller.generator()->imageTypes();
	if (index >= types.count()) {
		return;
	}
	m_currentImage = index;
	m_activeSize = types[index].second;
	m_ui.preferredWidth->setText(QString::number(m_activeSize.width()));
	m_ui.preferredHeight->setText(QString::number(m_activeSize.height()));
	m_ui.imagePreview->setMaximumSize(m_activeSize);
	m_ui.imagePreview->setPixmap(QPixmap::fromImage(m_controller.generator()->image(index)));
}
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/lite/micro/examples/hello_world/output_handler.h"

#include "am_bsp.h"  // NOLINT

/*
This function uses the device's LEDs to visually indicate the current y value.
The y value is in the range -1 <= y <= 1. The LEDs (red, green, blue,
and yellow) are physically lined up in the following order:

                         [ R G B Y ]

The following table represents how we will light the LEDs for different values:

| Range            | LEDs lit    |
| 0.75 <= y <= 1   | [ 0 0 1 1 ] |
| 0 < y < 0.75     | [ 0 0 1 0 ] |
| y = 0            | [ 0 0 0 0 ] |
| -0.75 < y < 0    | [ 0 1 0 0 ] |
| -1 <= y <= 0.75  | [ 1 1 0 0 ] |

*/
void HandleOutput(tflite::ErrorReporter* error_reporter, float x_value,
                  float y_value) {
  // The first time this method runs, set up our LEDs correctly
  static bool is_initialized = false;
  if (!is_initialized) {
    // Setup LED's as outputs
#ifdef AM_BSP_NUM_LEDS
    am_devices_led_array_init(am_bsp_psLEDs, AM_BSP_NUM_LEDS);
    am_devices_led_array_out(am_bsp_psLEDs, AM_BSP_NUM_LEDS, 0x00000000);
#endif
    is_initialized = true;
  }

  // Set the LEDs to represent negative values
  if (y_value < 0) {
    // Clear unnecessary LEDs
    am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_GREEN);
    am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_YELLOW);
    // The blue LED is lit for all negative values
    am_devices_led_on(am_bsp_psLEDs, AM_BSP_LED_BLUE);
    // The red LED is lit in only some cases
    if (y_value <= -0.75) {
      am_devices_led_on(am_bsp_psLEDs, AM_BSP_LED_RED);
    } else {
      am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_RED);
    }
    // Set the LEDs to represent positive values
  } else if (y_value > 0) {
    // Clear unnecessary LEDs
    am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_RED);
    am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_BLUE);
    // The green LED is lit for all positive values
    am_devices_led_on(am_bsp_psLEDs, AM_BSP_LED_GREEN);
    // The yellow LED is lit in only some cases
    if (y_value >= 0.75) {
      am_devices_led_on(am_bsp_psLEDs, AM_BSP_LED_YELLOW);
    } else {
      am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_YELLOW);
    }
  }
  // Log the current X and Y values
  TF_LITE_REPORT_ERROR(error_reporter, "x_value: %f, y_value: %f\n", x_value,
                       y_value);
}
<commit_msg>Update output_handler.cc<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/lite/micro/examples/hello_world/output_handler.h"

#include "am_bsp.h"  // NOLINT

/*
This function uses the device's LEDs to visually indicate the current y value.
The y value is in the range -1 <= y <= 1. The LEDs (red, green, blue,
and yellow) are physically lined up in the following order:

                         [ R B G Y ]

The following table represents how we will light the LEDs for different values:

| Range            | LEDs lit    |
| 0.75 <= y <= 1   | [ 0 0 1 1 ] |
| 0 < y < 0.75     | [ 0 0 1 0 ] |
| y = 0            | [ 0 0 0 0 ] |
| -0.75 < y < 0    | [ 0 1 0 0 ] |
| -1 <= y <= 0.75  | [ 1 1 0 0 ] |

*/
void HandleOutput(tflite::ErrorReporter* error_reporter, float x_value,
                  float y_value) {
  // The first time this method runs, set up our LEDs correctly
  static bool is_initialized = false;
  if (!is_initialized) {
    // Setup LED's as outputs
#ifdef AM_BSP_NUM_LEDS
    am_devices_led_array_init(am_bsp_psLEDs, AM_BSP_NUM_LEDS);
    am_devices_led_array_out(am_bsp_psLEDs, AM_BSP_NUM_LEDS, 0x00000000);
#endif
    is_initialized = true;
  }

  // Set the LEDs to represent negative values
  if (y_value < 0) {
    // Clear unnecessary LEDs
    am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_GREEN);
    am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_YELLOW);
    // The blue LED is lit for all negative values
    am_devices_led_on(am_bsp_psLEDs, AM_BSP_LED_BLUE);
    // The red LED is lit in only some cases
    if (y_value <= -0.75) {
      am_devices_led_on(am_bsp_psLEDs, AM_BSP_LED_RED);
    } else {
      am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_RED);
    }
    // Set the LEDs to represent positive values
  } else if (y_value > 0) {
    // Clear unnecessary LEDs
    am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_RED);
    am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_BLUE);
    // The green LED is lit for all positive values
    am_devices_led_on(am_bsp_psLEDs, AM_BSP_LED_GREEN);
    // The yellow LED is lit in only some cases
    if (y_value >= 0.75) {
      am_devices_led_on(am_bsp_psLEDs, AM_BSP_LED_YELLOW);
    } else {
      am_devices_led_off(am_bsp_psLEDs, AM_BSP_LED_YELLOW);
    }
  }
  // Log the current X and Y values
  TF_LITE_REPORT_ERROR(error_reporter, "x_value: %f, y_value: %f\n", x_value,
                       y_value);
}
<|endoftext|>


<commit_before>/*
  The MIT License (MIT)

  Copyright(C) 2014 Naoya Murakami <naoya@createfield.com>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

#include <string.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <stdexcept>
#include <vector>

#include <unicode/normlzr.h>
#include <mecab.h>
#include <re2/re2.h>
#include <wn.h>

#include <google/gflags.h>

DEFINE_string(input, "", "Input file path");
DEFINE_string(pre_filter,
              "(<[^>]*>)|\\\\n|\\\\r|\\\\t|([\\\\,.;:&^/\\-\\#'\"\\(\\)\\[\\]{}])",
              "Regular expresion pattern to input string");
DEFINE_bool(no_normalize, false, "Don't use NFKC normalize");
DEFINE_bool(no_tokenize, false, "Don't use tokenize");
DEFINE_string(mecab_dic, "", "Specifying mecab dictionary path");
DEFINE_bool(use_baseform, false, "Use baseform by MeCab dictionary");
DEFINE_string(token_filter, "", "Regular expresion pattern to token string");
DEFINE_bool(use_wordnet, false, "Use baseform by WordNet");
DEFINE_bool(cut_prolong, false, "Cut prolong if token have over 3 characters");
DEFINE_bool(h, false, "Help message");

#define MECAB_LIMIT 900000

using namespace std;

string
normalize(const string str)
{
  icu::UnicodeString src;
  icu::UnicodeString dest;
  src = str.c_str();
  UErrorCode status;
  status = U_ZERO_ERROR;
  Normalizer::normalize(src, UNORM_NFKC, 0, dest, status);
  if(U_FAILURE(status)) {
    throw runtime_error("Unicode normalization failed");
  }
  string result;
  dest.toUTF8String(result);
  transform(result.begin(), result.end(), result.begin(), ::tolower);
  return result;
}

static char *
right_trim(char *s, char del) {
  int i;
  int count = 0;
  if ( s == NULL ) {
    return NULL;
  }
  i = strlen(s);
  while ( --i >= 0 && s[i] == del ) count++;
  if (i == 0) {
    s[i] = '\0';
  } else {
    s[i+1] = '\0';
  }
  return s;
}

/* utf8_fix_pos
   utf8文字列じゃなければ、3バイト以内にutf8があるか判定する
*/
unsigned int
utf8_fix_pos(const string str, unsigned int start, unsigned int end)
{
  unsigned int pos;
  unsigned char lead;
  int char_size;

  for (pos = end; pos > start && pos > end - 3; pos--) {
    lead = str[pos];
    if (lead < 0x80) {
      char_size = 1;
    } else if (lead < 0xE0) {
      char_size = 2;
    } else if (lead < 0xF0) {
      char_size = 3;
    } else {
      char_size = 4;
    }
    if(char_size == 1 || char_size == 3){
       return pos;
    }
  }
  return end;
}

/* range_rfind_punct
  utf8文字列の範囲内を末尾から区切り文字、半角スペース、改行コード、
  日本語区切り文字を探す。
  見つかればその位置。見つからなければ、末尾の位置。
*/

int
range_rfind_punct(const string str, unsigned int start, unsigned int end)
{
  unsigned int pos;
  unsigned char lead;
  int char_size;

  for (pos = end; pos > start; pos -= char_size) {
    lead = str[pos];
    if (lead < 0x80) {
      char_size = 1;
    } else if (lead < 0xE0) {
      char_size = 2;
    } else if (lead < 0xF0) {
      char_size = 3;
    } else {
      char_size = 4;
    }

    if ((lead >= 0x20 && lead < 0x2f) ||
        (lead >= 0x3a && lead <= 0x40) ||
        (lead >= 0x5b && lead <= 0x60) ||
        (lead >= 0x7b && lead <= 0x7d) ||
        (lead >= 0x0a && lead <= 0x0d) ||
        str.substr(pos, char_size) == "。" ||
        str.substr(pos, char_size) == "、" ||
        str.substr(pos, char_size) == "「" ||
        str.substr(pos, char_size) == "」" ||
        str.substr(pos, char_size) == "・"
       ) {
       return pos;
    }
  }

  lead = str[end];
  if (lead < 0x80) {
    char_size = 1;
  } else if (lead < 0xE0) {
    char_size = 2;
  } else if (lead < 0xF0) {
    char_size = 3;
  } else {
    char_size = 4;
  }
  if(char_size == 2 || char_size == 4){
    pos = utf8_fix_pos(str, start, end);
    return pos;
  }
  return end;
}

string
tokenize(const string str, const string mecab_dic, bool baseform)
{
  mecab_t *mecab = NULL;
  string mecab_option;

  if(baseform){
    mecab_option = "-F%f[6]\\s -E\\n";
  } else {
    mecab_option = "-Owakati";
  }
  if(mecab_dic.length() > 0){
    mecab_option += " -d " + mecab_dic;
  }

  mecab = mecab_new2(mecab_option.c_str());

  string result;
  if(str.length() < MECAB_LIMIT) {
    result = mecab_sparse_tostr2(mecab, str.c_str(), str.length());
    result = right_trim((char *)result.c_str(), '\n');
  } else {
    unsigned int punct_pos = 0;
    unsigned int start = 0;
    unsigned int end = MECAB_LIMIT;
    unsigned int split_len;
    while(end < str.length()){
      punct_pos = range_rfind_punct(str, start, end);
      split_len = punct_pos - start;
      result += mecab_sparse_tostr2(mecab, str.c_str() + start, split_len);
      result = right_trim((char *)result.c_str(), '\n');
      start = punct_pos;
      end = start + MECAB_LIMIT;
    }
    split_len = str.length() - start;
    result += mecab_sparse_tostr2(mecab, str.c_str() + start, split_len);
  }
  mecab_destroy(mecab);
  return result;
}

string
string_filter(string str, const char *pattern)
{
  if(strcmp(pattern, "") != 0){
    re2::RE2::GlobalReplace(&str, pattern, "");
  }
  return str;
}

vector<string>
split(const string &str, char delim){
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos){
    res.push_back(string(str, current, found - current));
    current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

string
token_filter(const string str, const char *pattern, bool wordnet, bool prolong)
{
  vector<string> result_array;
  result_array = split(str, ' ');
  string result;
  for(unsigned int i = 0; i < result_array.size(); ++i )
  {
    char *buf;
    buf = (char *)result_array[i].c_str();
    if(wordnet){
      int pos;
      char *morph;
      if (wninit() == -1){
        return str;
      }
      //pos 1:NOUN 2:VERB 3:ADJECTIVE 4:ADVERB 5:ADJECTIVE_SATELITE
      for(pos = 5; pos >= 1; pos--){
        morph = morphstr(buf, pos);
        if(morph){
          buf = morph;
          break;
        }
      }
    }
    bool ret = false;
    string string_buf = buf;

    if(prolong) {
      if(string_buf.length() >= 12 ){
        string tail_buf = string_buf.substr(string_buf.length()-3, 3);
        if(tail_buf == "ー" || tail_buf == "ｰ"){
          string_buf = string_buf.substr(0, string_buf.length()-3);
        }
      }
    }

    if(strcmp(pattern, "") != 0){
      ret = re2::RE2::GlobalReplace(&string_buf, pattern, "");
    }

    result += string_buf;
    if(i < result_array.size() && ret == false){
      result += " ";
    }
  }
  return result;
}

int
string-splitter(string str)
{
  str = string_filter(str, FLAGS_pre_filter.c_str());
  if (!FLAGS_no_normalize) {
    str = normalize(str);
  }
  if (!FLAGS_no_tokenize) {
    str = tokenize(str, FLAGS_mecab_dic, FLAGS_use_baseform);
  }
  str = token_filter(str, FLAGS_token_filter.c_str(), FLAGS_use_wordnet, FLAGS_cut_prolong);

  cout << str.c_str() << endl;
  return 0;
}

int
main(int argc,char **argv)
{
  google::ParseCommandLineFlags(&argc, &argv, true);

  if(FLAGS_h == true){
    printf("  --iuput : Input file path\n");
    printf("  --pre_filter : Regular expresion pattern to input string\n");
    printf("  --no_normalize : Don't use NFKC normalize\n");
    printf("  --no_tokenize : Don't use tokenize\n");
    printf("  --mecab_dic : Specifying mecab dictionary path\n");
    printf("  --use_baseform : Convert baseform by MeCab dictionary\n");
    printf("  --token_filter : Regular expresion pattern to token string\n");
    printf("  --use_wordndet : Convert baseform by WordNet\n");
    printf("  --cut_prolong : Cut prolong if token have over 3 characters\n");
    exit(0);
  }

  string str;
  if(FLAGS_input == ""){
    while(getline(cin, str)){
      if(str == "EOS"){
        break;
      }
      string-splitter(str);
    }
  } else {
    ifstream ifs(FLAGS_input.c_str());
    if(ifs.fail()) {
      cerr << "File do not exist.\n";
      exit(0);
    }
    while(getline(ifs, str)){
      string-splitter(str);
    }
  }

  return 0;
}
<commit_msg>fix function includes hyphen<commit_after>/*
  The MIT License (MIT)

  Copyright(C) 2014 Naoya Murakami <naoya@createfield.com>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

#include <string.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <stdexcept>
#include <vector>

#include <unicode/normlzr.h>
#include <mecab.h>
#include <re2/re2.h>
#include <wn.h>

#include <google/gflags.h>

DEFINE_string(input, "", "Input file path");
DEFINE_string(pre_filter,
              "(<[^>]*>)|\\\\n|\\\\r|\\\\t|([\\\\,.;:&^/\\-\\#'\"\\(\\)\\[\\]{}])",
              "Regular expresion pattern to input string");
DEFINE_bool(no_normalize, false, "Don't use NFKC normalize");
DEFINE_bool(no_tokenize, false, "Don't use tokenize");
DEFINE_string(mecab_dic, "", "Specifying mecab dictionary path");
DEFINE_bool(use_baseform, false, "Use baseform by MeCab dictionary");
DEFINE_string(token_filter, "", "Regular expresion pattern to token string");
DEFINE_bool(use_wordnet, false, "Use baseform by WordNet");
DEFINE_bool(cut_prolong, false, "Cut prolong if token have over 3 characters");
DEFINE_bool(h, false, "Help message");

#define MECAB_LIMIT 900000

using namespace std;

string
normalize(const string str)
{
  icu::UnicodeString src;
  icu::UnicodeString dest;
  src = str.c_str();
  UErrorCode status;
  status = U_ZERO_ERROR;
  Normalizer::normalize(src, UNORM_NFKC, 0, dest, status);
  if(U_FAILURE(status)) {
    throw runtime_error("Unicode normalization failed");
  }
  string result;
  dest.toUTF8String(result);
  transform(result.begin(), result.end(), result.begin(), ::tolower);
  return result;
}

static char *
right_trim(char *s, char del) {
  int i;
  int count = 0;
  if ( s == NULL ) {
    return NULL;
  }
  i = strlen(s);
  while ( --i >= 0 && s[i] == del ) count++;
  if (i == 0) {
    s[i] = '\0';
  } else {
    s[i+1] = '\0';
  }
  return s;
}

/* utf8_fix_pos
   utf8文字列じゃなければ、3バイト以内にutf8があるか判定する
*/
unsigned int
utf8_fix_pos(const string str, unsigned int start, unsigned int end)
{
  unsigned int pos;
  unsigned char lead;
  int char_size;

  for (pos = end; pos > start && pos > end - 3; pos--) {
    lead = str[pos];
    if (lead < 0x80) {
      char_size = 1;
    } else if (lead < 0xE0) {
      char_size = 2;
    } else if (lead < 0xF0) {
      char_size = 3;
    } else {
      char_size = 4;
    }
    if(char_size == 1 || char_size == 3){
       return pos;
    }
  }
  return end;
}

/* range_rfind_punct
  utf8文字列の範囲内を末尾から区切り文字、半角スペース、改行コード、
  日本語区切り文字を探す。
  見つかればその位置。見つからなければ、末尾の位置。
*/

int
range_rfind_punct(const string str, unsigned int start, unsigned int end)
{
  unsigned int pos;
  unsigned char lead;
  int char_size;

  for (pos = end; pos > start; pos -= char_size) {
    lead = str[pos];
    if (lead < 0x80) {
      char_size = 1;
    } else if (lead < 0xE0) {
      char_size = 2;
    } else if (lead < 0xF0) {
      char_size = 3;
    } else {
      char_size = 4;
    }

    if ((lead >= 0x20 && lead < 0x2f) ||
        (lead >= 0x3a && lead <= 0x40) ||
        (lead >= 0x5b && lead <= 0x60) ||
        (lead >= 0x7b && lead <= 0x7d) ||
        (lead >= 0x0a && lead <= 0x0d) ||
        str.substr(pos, char_size) == "。" ||
        str.substr(pos, char_size) == "、" ||
        str.substr(pos, char_size) == "「" ||
        str.substr(pos, char_size) == "」" ||
        str.substr(pos, char_size) == "・"
       ) {
       return pos;
    }
  }

  lead = str[end];
  if (lead < 0x80) {
    char_size = 1;
  } else if (lead < 0xE0) {
    char_size = 2;
  } else if (lead < 0xF0) {
    char_size = 3;
  } else {
    char_size = 4;
  }
  if(char_size == 2 || char_size == 4){
    pos = utf8_fix_pos(str, start, end);
    return pos;
  }
  return end;
}

string
tokenize(const string str, const string mecab_dic, bool baseform)
{
  mecab_t *mecab = NULL;
  string mecab_option;

  if(baseform){
    mecab_option = "-F%f[6]\\s -E\\n";
  } else {
    mecab_option = "-Owakati";
  }
  if(mecab_dic.length() > 0){
    mecab_option += " -d " + mecab_dic;
  }

  mecab = mecab_new2(mecab_option.c_str());

  string result;
  if(str.length() < MECAB_LIMIT) {
    result = mecab_sparse_tostr2(mecab, str.c_str(), str.length());
    result = right_trim((char *)result.c_str(), '\n');
  } else {
    unsigned int punct_pos = 0;
    unsigned int start = 0;
    unsigned int end = MECAB_LIMIT;
    unsigned int split_len;
    while(end < str.length()){
      punct_pos = range_rfind_punct(str, start, end);
      split_len = punct_pos - start;
      result += mecab_sparse_tostr2(mecab, str.c_str() + start, split_len);
      result = right_trim((char *)result.c_str(), '\n');
      start = punct_pos;
      end = start + MECAB_LIMIT;
    }
    split_len = str.length() - start;
    result += mecab_sparse_tostr2(mecab, str.c_str() + start, split_len);
  }
  mecab_destroy(mecab);
  return result;
}

string
string_filter(string str, const char *pattern)
{
  if(strcmp(pattern, "") != 0){
    re2::RE2::GlobalReplace(&str, pattern, "");
  }
  return str;
}

vector<string>
split(const string &str, char delim){
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos){
    res.push_back(string(str, current, found - current));
    current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

string
token_filter(const string str, const char *pattern, bool wordnet, bool prolong)
{
  vector<string> result_array;
  result_array = split(str, ' ');
  string result;
  for(unsigned int i = 0; i < result_array.size(); ++i )
  {
    char *buf;
    buf = (char *)result_array[i].c_str();
    if(wordnet){
      int pos;
      char *morph;
      if (wninit() == -1){
        return str;
      }
      //pos 1:NOUN 2:VERB 3:ADJECTIVE 4:ADVERB 5:ADJECTIVE_SATELITE
      for(pos = 5; pos >= 1; pos--){
        morph = morphstr(buf, pos);
        if(morph){
          buf = morph;
          break;
        }
      }
    }
    bool ret = false;
    string string_buf = buf;

    if(prolong) {
      if(string_buf.length() >= 12 ){
        string tail_buf = string_buf.substr(string_buf.length()-3, 3);
        if(tail_buf == "ー" || tail_buf == "ｰ"){
          string_buf = string_buf.substr(0, string_buf.length()-3);
        }
      }
    }

    if(strcmp(pattern, "") != 0){
      ret = re2::RE2::GlobalReplace(&string_buf, pattern, "");
    }

    result += string_buf;
    if(i < result_array.size() && ret == false){
      result += " ";
    }
  }
  return result;
}

int
string_splitter(string str)
{
  str = string_filter(str, FLAGS_pre_filter.c_str());
  if (!FLAGS_no_normalize) {
    str = normalize(str);
  }
  if (!FLAGS_no_tokenize) {
    str = tokenize(str, FLAGS_mecab_dic, FLAGS_use_baseform);
  }
  str = token_filter(str, FLAGS_token_filter.c_str(), FLAGS_use_wordnet, FLAGS_cut_prolong);

  cout << str.c_str() << endl;
  return 0;
}

int
main(int argc,char **argv)
{
  google::ParseCommandLineFlags(&argc, &argv, true);

  if(FLAGS_h == true){
    printf("  --iuput : Input file path\n");
    printf("  --pre_filter : Regular expresion pattern to input string\n");
    printf("  --no_normalize : Don't use NFKC normalize\n");
    printf("  --no_tokenize : Don't use tokenize\n");
    printf("  --mecab_dic : Specifying mecab dictionary path\n");
    printf("  --use_baseform : Convert baseform by MeCab dictionary\n");
    printf("  --token_filter : Regular expresion pattern to token string\n");
    printf("  --use_wordndet : Convert baseform by WordNet\n");
    printf("  --cut_prolong : Cut prolong if token have over 3 characters\n");
    exit(0);
  }

  string str;
  if(FLAGS_input == ""){
    while(getline(cin, str)){
      if(str == "EOS"){
        break;
      }
      string_splitter(str);
    }
  } else {
    ifstream ifs(FLAGS_input.c_str());
    if(ifs.fail()) {
      cerr << "File do not exist.\n";
      exit(0);
    }
    while(getline(ifs, str)){
      string_splitter(str);
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>#include "strings.h"

BOOST_AUTO_TEST_CASE(std_string_literals)
{
    using namespace std::string_literals;
    auto s1{"Hello, world!"s};
    auto s2{L"Hello, world!"s};
    auto s3{u"Hello, world!"s};
    auto s4{U"Hello, world!"s};
    BOOST_REQUIRE((std::is_same_v<decltype(s1), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s2), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s3), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s4), XXX>));
}

BOOST_AUTO_TEST_CASE(std_string_variants)
{
    BOOST_REQUIRE((std::is_same_v<std::basic_string<char>, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string, std::basic_string<XXX>>));
    BOOST_REQUIRE((std::is_same_v<std::wstring, std::basic_string<XXX>>));
    BOOST_REQUIRE((std::is_same_v<std::u16string, std::basic_string<XXX>>));
    BOOST_REQUIRE((std::is_same_v<std::u32string, std::basic_string<XXX>>));
}

BOOST_AUTO_TEST_CASE(std_string_related_types)
{
    BOOST_REQUIRE((std::is_same_v<std::string::traits_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::value_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::reference, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::const_reference, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::reverse_iterator, std::reverse_iterator<XXX>>));
    BOOST_REQUIRE((std::is_same_v<std::string::const_reverse_iterator, std::reverse_iterator<XXX>>));
}

BOOST_AUTO_TEST_CASE(std_string_constructors)
{
    std::string const s1;
    BOOST_REQUIRE_EQUAL(xxx, s1.length());

    std::string const s2{5, 'E'};
    BOOST_REQUIRE_EQUAL(xxx, s2.length());

    std::string const s3{s2};
    BOOST_REQUIRE_EQUAL(xxx, s3.length());

    std::string const s4{s2, 1};
    BOOST_REQUIRE_EQUAL(xxx, s4.length());

    std::string const hw{"Hello, world!"};
    std::string const s5{hw, 1, 4};
    BOOST_REQUIRE_EQUAL(xxx, s5);

    std::string const s6{"Hello, world!"};
    BOOST_REQUIRE_EQUAL(xxx, s6.length());

    std::string const s7{"Hello, world!", 5};
    BOOST_REQUIRE_EQUAL(xxx, s7);

    std::string const s8{s7.begin(), s7.begin() + 1};
    BOOST_REQUIRE_EQUAL(xxx, s8);

    std::string const s9{'H', 'e', 'l', 'l', 'o'};
    BOOST_REQUIRE_EQUAL(xxx, s9);
}

BOOST_AUTO_TEST_CASE(std_string_accessors)
{
    std::string const s{"Hello, world!"};

    BOOST_REQUIRE_EQUAL(xxx, s[0]);
    BOOST_REQUIRE_EQUAL('w', s.at(xxx));
    BOOST_REQUIRE_THROW(s.at(1000), XXX);
    BOOST_REQUIRE_EQUAL(xxx, s.front());
    BOOST_REQUIRE_EQUAL(xxx, s.back());
    BOOST_REQUIRE((std::is_same_v<decltype(s.data()), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s.c_str()), XXX>));
}

BOOST_AUTO_TEST_CASE(string_iterators)
{
    std::string const s{"Hello, world!"};
    BOOST_REQUIRE((std::is_same_v<decltype(s.begin()), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s.cbegin()), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, *s.begin());
    BOOST_REQUIRE_EQUAL(xxx, *(s.end() - 1));
    BOOST_REQUIRE_EQUAL(xxx, *s.rbegin());
    BOOST_REQUIRE_EQUAL(xxx, *(s.rend() - 1));
}

BOOST_AUTO_TEST_CASE(std_string_capacity)
{
    std::string s{"Hello, world!"};
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_EQUAL(xxx, s.empty());
    BOOST_REQUIRE_GE(static_cast<std::string::size_type>(xxx), s.capacity());

    s += s;
    s = "Hello, world!";
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_GE(static_cast<std::string::size_type>(xxx), s.capacity());

    s.shrink_to_fit();
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_GE(static_cast<std::string::size_type>(xxx), s.capacity());

    s.reserve(1024);
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_EQUAL(xxx, s.capacity());
}

BOOST_AUTO_TEST_CASE(std_string_clear)
{
    std::string s{"Hello, world!"};
    s.clear();
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_EQUAL(xxx, s.empty());
    BOOST_REQUIRE_GE(s.capacity(), static_cast<std::string::size_type>(xxx));
}

BOOST_AUTO_TEST_CASE(std_string_insert)
{
    using namespace std::string_literals;

    std::string s2{"Bob"};
    auto res1 = s2.insert(1, "illy B");
    BOOST_REQUIRE((std::is_same_v<decltype(res1), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s2);

    auto res2 = s2.insert(0, 2, '-');
    BOOST_REQUIRE((std::is_same_v<decltype(res2), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s2);

    auto res3 = s2.insert(2, "Hello, world!", 7);
    BOOST_REQUIRE((std::is_same_v<decltype(res3), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s2);

    std::string s3{"Hello, world!"};
    std::string s4{"big, fat "};
    auto res4 = s3.insert(7, s4);
    BOOST_REQUIRE((std::is_same_v<decltype(res4), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s3);

    std::string s5{"Hello, world!"};
    auto res5 = s5.insert(7, s4, xxx, 3);
    BOOST_REQUIRE((std::is_same_v<decltype(res5), XXX>));
    BOOST_REQUIRE_EQUAL("Hello, fat world!"s, s5);

    std::string s6{"Hello? "};
    auto res6 = s5.insert<std::string::iterator>(s5.begin(), s6.begin(), xxx);
    BOOST_REQUIRE((std::is_same_v<decltype(res6), XXX>));
    BOOST_REQUIRE_EQUAL("Hello? Hello, fat world!"s, s5);
    BOOST_REQUIRE_EQUAL(xxx, *res6);

    std::string s7{", world"};
    auto res7 = s7.insert(0, {'H', 'e', 'l', 'l', 'o'});
    BOOST_REQUIRE((std::is_same_v<decltype(res7), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s7);
}

BOOST_AUTO_TEST_CASE(std_string_erase)
{
    using namespace std::string_literals;
    std::string s1{"Hello, world!"};
    s1.erase(5);
    BOOST_REQUIRE_EQUAL(xxx, s1);

    std::string s2{"Hello, world!"};
    s2.erase(5, 1);
    BOOST_REQUIRE_EQUAL(xxx, s2);

    std::string s3{"Hello, world!"};
    s3.erase(s3.end() - 1);
    BOOST_REQUIRE_EQUAL(xxx, s3);

    std::string s4{"Hello, world!"};
    s4.erase(xxx, s4.end() - 1);
    BOOST_REQUIRE_EQUAL("H!"s, s4);
}

BOOST_AUTO_TEST_CASE(std_string_push_back)
{
    using namespace std::string_literals;
    std::string s{"<"};
    s.push_back(xxx);
    BOOST_REQUIRE_EQUAL("<>", s);
}

BOOST_AUTO_TEST_CASE(std_string_pop_back)
{
    using namespace std::string_literals;
    std::string s{"[]"};
    s.pop_back();
    BOOST_REQUIRE_EQUAL(xxx, s);
}

BOOST_AUTO_TEST_CASE(std_string_append)
{
}

BOOST_AUTO_TEST_CASE(std_string_operators)
{
}

BOOST_AUTO_TEST_CASE(std_string_compare)
{
}

BOOST_AUTO_TEST_CASE(std_string_replace)
{
}

BOOST_AUTO_TEST_CASE(std_string_substr)
{
}

BOOST_AUTO_TEST_CASE(std_string_copy)
{
}

BOOST_AUTO_TEST_CASE(std_string_resize)
{
}

BOOST_AUTO_TEST_CASE(std_string_swap)
{
}

BOOST_AUTO_TEST_CASE(std_string_find)
{
}

BOOST_AUTO_TEST_CASE(std_string_rfind)
{
}

BOOST_AUTO_TEST_CASE(std_string_find_first_of)
{
}

BOOST_AUTO_TEST_CASE(std_string_find_first_not_of)
{
}

BOOST_AUTO_TEST_CASE(std_string_find_last_of)
{
}

BOOST_AUTO_TEST_CASE(std_string_find_last_not_of)
{
}

BOOST_AUTO_TEST_CASE(std_string_conversions)
{
}

BOOST_AUTO_TEST_CASE(std_string_allocators)
{
    BOOST_REQUIRE((std::is_same_v<std::string::allocator_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::size_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::difference_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::pointer, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::const_pointer, XXX>));
}
<commit_msg>Add std::string::append test case<commit_after>#include "strings.h"

BOOST_AUTO_TEST_CASE(std_string_literals)
{
    using namespace std::string_literals;
    auto s1{"Hello, world!"s};
    auto s2{L"Hello, world!"s};
    auto s3{u"Hello, world!"s};
    auto s4{U"Hello, world!"s};
    BOOST_REQUIRE((std::is_same_v<decltype(s1), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s2), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s3), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s4), XXX>));
}

BOOST_AUTO_TEST_CASE(std_string_variants)
{
    BOOST_REQUIRE((std::is_same_v<std::basic_string<char>, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string, std::basic_string<XXX>>));
    BOOST_REQUIRE((std::is_same_v<std::wstring, std::basic_string<XXX>>));
    BOOST_REQUIRE((std::is_same_v<std::u16string, std::basic_string<XXX>>));
    BOOST_REQUIRE((std::is_same_v<std::u32string, std::basic_string<XXX>>));
}

BOOST_AUTO_TEST_CASE(std_string_related_types)
{
    BOOST_REQUIRE((std::is_same_v<std::string::traits_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::value_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::reference, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::const_reference, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::reverse_iterator, std::reverse_iterator<XXX>>));
    BOOST_REQUIRE((std::is_same_v<std::string::const_reverse_iterator, std::reverse_iterator<XXX>>));
}

BOOST_AUTO_TEST_CASE(std_string_constructors)
{
    std::string const s1;
    BOOST_REQUIRE_EQUAL(xxx, s1.length());

    std::string const s2{5, 'E'};
    BOOST_REQUIRE_EQUAL(xxx, s2.length());

    std::string const s3{s2};
    BOOST_REQUIRE_EQUAL(xxx, s3.length());

    std::string const s4{s2, 1};
    BOOST_REQUIRE_EQUAL(xxx, s4.length());

    std::string const hw{"Hello, world!"};
    std::string const s5{hw, 1, 4};
    BOOST_REQUIRE_EQUAL(xxx, s5);

    std::string const s6{"Hello, world!"};
    BOOST_REQUIRE_EQUAL(xxx, s6.length());

    std::string const s7{"Hello, world!", 5};
    BOOST_REQUIRE_EQUAL(xxx, s7);

    std::string const s8{s7.begin(), s7.begin() + 1};
    BOOST_REQUIRE_EQUAL(xxx, s8);

    std::string const s9{'H', 'e', 'l', 'l', 'o'};
    BOOST_REQUIRE_EQUAL(xxx, s9);
}

BOOST_AUTO_TEST_CASE(std_string_accessors)
{
    std::string const s{"Hello, world!"};

    BOOST_REQUIRE_EQUAL(xxx, s[0]);
    BOOST_REQUIRE_EQUAL('w', s.at(xxx));
    BOOST_REQUIRE_THROW(s.at(1000), XXX);
    BOOST_REQUIRE_EQUAL(xxx, s.front());
    BOOST_REQUIRE_EQUAL(xxx, s.back());
    BOOST_REQUIRE((std::is_same_v<decltype(s.data()), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s.c_str()), XXX>));
}

BOOST_AUTO_TEST_CASE(string_iterators)
{
    std::string const s{"Hello, world!"};
    BOOST_REQUIRE((std::is_same_v<decltype(s.begin()), XXX>));
    BOOST_REQUIRE((std::is_same_v<decltype(s.cbegin()), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, *s.begin());
    BOOST_REQUIRE_EQUAL(xxx, *(s.end() - 1));
    BOOST_REQUIRE_EQUAL(xxx, *s.rbegin());
    BOOST_REQUIRE_EQUAL(xxx, *(s.rend() - 1));
}

BOOST_AUTO_TEST_CASE(std_string_capacity)
{
    std::string s{"Hello, world!"};
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_EQUAL(xxx, s.empty());
    BOOST_REQUIRE_GE(static_cast<std::string::size_type>(xxx), s.capacity());

    s += s;
    s = "Hello, world!";
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_GE(static_cast<std::string::size_type>(xxx), s.capacity());

    s.shrink_to_fit();
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_GE(static_cast<std::string::size_type>(xxx), s.capacity());

    s.reserve(1024);
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_EQUAL(xxx, s.capacity());
}

BOOST_AUTO_TEST_CASE(std_string_clear)
{
    std::string s{"Hello, world!"};
    s.clear();
    BOOST_REQUIRE_EQUAL(xxx, s.length());
    BOOST_REQUIRE_EQUAL(xxx, s.empty());
    BOOST_REQUIRE_GE(s.capacity(), static_cast<std::string::size_type>(xxx));
}

BOOST_AUTO_TEST_CASE(std_string_insert)
{
    using namespace std::string_literals;

    std::string s2{"Bob"};
    auto res1 = s2.insert(1, "illy B");
    BOOST_REQUIRE((std::is_same_v<decltype(res1), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s2);

    auto res2 = s2.insert(0, 2, '-');
    BOOST_REQUIRE((std::is_same_v<decltype(res2), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s2);

    auto res3 = s2.insert(2, "Hello, world!", 7);
    BOOST_REQUIRE((std::is_same_v<decltype(res3), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s2);

    std::string s3{"Hello, world!"};
    std::string s4{"big, fat "};
    auto res4 = s3.insert(7, s4);
    BOOST_REQUIRE((std::is_same_v<decltype(res4), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s3);

    std::string s5{"Hello, world!"};
    auto res5 = s5.insert(7, s4, xxx, 3);
    BOOST_REQUIRE((std::is_same_v<decltype(res5), XXX>));
    BOOST_REQUIRE_EQUAL("Hello, fat world!"s, s5);

    std::string s6{"Hello? "};
    auto res6 = s5.insert<std::string::iterator>(s5.begin(), s6.begin(), xxx);
    BOOST_REQUIRE((std::is_same_v<decltype(res6), XXX>));
    BOOST_REQUIRE_EQUAL("Hello? Hello, fat world!"s, s5);
    BOOST_REQUIRE_EQUAL(xxx, *res6);

    std::string s7{", world"};
    auto res7 = s7.insert(0, {'H', 'e', 'l', 'l', 'o'});
    BOOST_REQUIRE((std::is_same_v<decltype(res7), XXX>));
    BOOST_REQUIRE_EQUAL(xxx, s7);
}

BOOST_AUTO_TEST_CASE(std_string_erase)
{
    using namespace std::string_literals;
    std::string s1{"Hello, world!"};
    s1.erase(5);
    BOOST_REQUIRE_EQUAL(xxx, s1);

    std::string s2{"Hello, world!"};
    s2.erase(5, 1);
    BOOST_REQUIRE_EQUAL(xxx, s2);

    std::string s3{"Hello, world!"};
    s3.erase(s3.end() - 1);
    BOOST_REQUIRE_EQUAL(xxx, s3);

    std::string s4{"Hello, world!"};
    s4.erase(xxx, s4.end() - 1);
    BOOST_REQUIRE_EQUAL("H!"s, s4);
}

BOOST_AUTO_TEST_CASE(std_string_push_back)
{
    using namespace std::string_literals;
    std::string s{"<"};
    s.push_back(xxx);
    BOOST_REQUIRE_EQUAL("<>"s, s);
}

BOOST_AUTO_TEST_CASE(std_string_pop_back)
{
    std::string s{"[]"};
    s.pop_back();
    BOOST_REQUIRE_EQUAL(xxx, s);
}

BOOST_AUTO_TEST_CASE(std_string_append)
{
    using namespace std::string_literals;
    std::string s1{"<["};
    auto res1 = s1.append(xxx, 2);
    BOOST_REQUIRE((std::is_same_v<decltype(res1), XXX>));
    BOOST_REQUIRE_EQUAL("<[]>"s, s1);

    std::string s2{"Foo"};
    s2.append("bar"s);
    BOOST_REQUIRE_EQUAL(xxx, s2);

    std::string s3{"Meta"};
    s3.append("Well, what about the--"s, xxx);
    BOOST_REQUIRE_EQUAL("Meta--"s, s3);

    std::string s4{"Wafer "};
    s4.append("Something"s, 4, xxx);
    BOOST_REQUIRE_EQUAL("Wafer thin"s, s4);

    std::string s5{"The good "};
    s5.append(" wicked witch", xxx);
    BOOST_REQUIRE_EQUAL("The good witch"s, s5);

    std::string s6{"Powdered "};
    const char lit[] = "donut";
    s6.append(std::begin(lit), xxx);
    BOOST_REQUIRE_EQUAL("Powdered donut"s, s6);

    std::string s7{"+"};
    s7.append({ xxx, xxx, xxx });
    BOOST_REQUIRE_EQUAL("+--+"s, s7);
}

BOOST_AUTO_TEST_CASE(std_string_operators)
{
}

BOOST_AUTO_TEST_CASE(std_string_compare)
{
}

BOOST_AUTO_TEST_CASE(std_string_replace)
{
}

BOOST_AUTO_TEST_CASE(std_string_substr)
{
}

BOOST_AUTO_TEST_CASE(std_string_copy)
{
}

BOOST_AUTO_TEST_CASE(std_string_resize)
{
}

BOOST_AUTO_TEST_CASE(std_string_swap)
{
}

BOOST_AUTO_TEST_CASE(std_string_find)
{
}

BOOST_AUTO_TEST_CASE(std_string_rfind)
{
}

BOOST_AUTO_TEST_CASE(std_string_find_first_of)
{
}

BOOST_AUTO_TEST_CASE(std_string_find_first_not_of)
{
}

BOOST_AUTO_TEST_CASE(std_string_find_last_of)
{
}

BOOST_AUTO_TEST_CASE(std_string_find_last_not_of)
{
}

BOOST_AUTO_TEST_CASE(std_string_conversions)
{
}

BOOST_AUTO_TEST_CASE(std_string_allocators)
{
    BOOST_REQUIRE((std::is_same_v<std::string::allocator_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::size_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::difference_type, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::pointer, XXX>));
    BOOST_REQUIRE((std::is_same_v<std::string::const_pointer, XXX>));
}
<|endoftext|>