<commit_before>#include <CodeAdapter\EasyCA.h>
#include <CodeAdapterSFML\SFMLFactory.h>

int main()
{
	initializeCA<SFMLFactory>();

	i32 button1ClickCount = 0;

	auto window1 = caFactory->createWindow();
	window1->create(caDraw::Size(1024, 768), caUtil::String("Hello, World!"));

	auto rect = canew<caDraw::DrawableRectangle>(-32, -64, 256, 128);
	rect->edgeColor = caDraw::Color::Magenta;
	rect->fillColor = caDraw::Color::Yellow;
	rect->edgeWidth = 8.0f;

	auto ellipse = canew<caDraw::DrawableEllipse>(-32, -64, 256, 128);
	ellipse->edgeColor = caDraw::Color::Yellow;
	ellipse->fillColor = caDraw::Color::Magenta;
	ellipse->edgeWidth = 2.0f;

	auto ellipse2 = canew<caDraw::DrawableEllipse>(-40, -70, 2, 2);
	ellipse2->edgeColor = caDraw::Color::Red;
	ellipse2->fillColor = caDraw::Color::Red;
	ellipse2->edgeWidth = 1.0f;

	auto line1 = canew<caDraw::DrawableLine>(rect->x, rect->y,
		rect->x + rect->width, rect->y + rect->height);
	line1->color = caDraw::Color::Cyan;
	line1->thickness = 8.0f;

	auto font1 = caFactory->createFont();
	font1->loadFromFile("NanumGothic.ttf");
	font1->setCharacterSize(64);
	font1->setStyle(caDraw::FontStyles::Underline | caDraw::FontStyles::Bold);

	auto text1 = canew<caDraw::DrawableText>();
	text1->setFont(font1);
	text1->text = L"Hello, World!\nȳ !";
	text1->location.setLocation(64, 8);
	text1->color = caDraw::Color(34, 177, 76);

	auto texture1 = caFactory->createTexture();
	texture1->loadFromFile("neurowhai.png");

	auto sprite1 = canew<caDraw::DrawableTexture>();
	sprite1->setTexture(texture1);
	sprite1->location.setLocation(-512.f, -512.f);
	sprite1->color = caDraw::Color(caDraw::Color::Red, 85);
	sprite1->transform.scale.setVector(0.5f, 0.5f);

	auto sprite2 = canew<caDraw::DrawableTexture>();
	sprite2->setTexture(texture1);
	sprite2->location.setLocation(-512.f + 16.f, -512.f);
	sprite2->color = caDraw::Color(caDraw::Color::Green, 85);
	sprite2->transform.scale.setVector(0.5f, 0.5f);

	auto sprite3 = canew<caDraw::DrawableTexture>();
	sprite3->setTexture(texture1);
	sprite3->location.setLocation(-512.f + 8.f, -512.f + 13.85f);
	sprite3->color = caDraw::Color(caDraw::Color::Blue, 85);
	sprite3->transform.scale.setVector(0.5f, 0.5f);

	auto sprite4 = canew<caDraw::DrawableTexture>();
	sprite4->setTexture(texture1);
	sprite4->location.setLocation(-512.f, -512.f);

	auto label1 = canew<caUI::Label>();
	label1->setFont(font1);
	label1->setText(L"label1 text");
	label1->setTextMargin({ 8, 0 });
	label1->setBackColor(caDraw::Color::Gray);
	label1->setPosition({ 128, 128 });
	label1->setSize({ 330, 100 });
	label1->setSelectable(true);
	label1->WhenTouchDown = [&label1](const caUI::TouchEventArgs& args) {
		label1->setTextColor(caDraw::Color::Red);
		label1->setPosition({ static_cast<f32>(args.x) - 165,
			static_cast<f32>(args.y) - 50 });
	};
	label1->WhenTouchUp = [&label1](const caUI::TouchEventArgs& args) {
		label1->setTextColor(caDraw::Color::Black);
	};
	label1->WhenEnterFocus = [&label1](const caUI::EventArgs& args) {
		label1->setTextColor(caDraw::Color::Blue);
	};
	label1->WhenLeaveFocus = [&label1](const caUI::EventArgs& args) {
		label1->setTextColor(caDraw::Color::Black);
	};
	label1->WhenSelected = [&label1](const caUI::EventArgs& args) {
		label1->setBackColor(caDraw::Color::White);
	};
	label1->WhenDeselected = [&label1](const caUI::EventArgs& args) {
		label1->setBackColor(caDraw::Color::Gray);
	};
	label1->WhenKeyDown = [&label1](const caUI::KeyEventArgs& args) {
		switch (args.key)
		{
		case caSys::Keys::Space:
			label1->setPosition({ 128, 128 });
			break;
		}
	};

	auto label2 = canew<caUI::Label>(*label1);
	label2->WhenTouchDown = [&label2](const caUI::TouchEventArgs& args) {
		label2->setTextColor(caDraw::Color::Red);
		label2->setPosition({ static_cast<f32>(args.x) - 165,
			static_cast<f32>(args.y) - 50 });
	};
	label2->WhenTouchUp = [&label2](const caUI::TouchEventArgs& args) {
		label2->setTextColor(caDraw::Color::Black);
	};
	label2->WhenEnterFocus = [&label2](const caUI::EventArgs& args) {
		label2->setTextColor(caDraw::Color::Blue);
	};
	label2->WhenLeaveFocus = [&label2](const caUI::EventArgs& args) {
		label2->setTextColor(caDraw::Color::Black);
	};
	label2->WhenSelected = [&label2](const caUI::EventArgs& args) {
		label2->setBackColor(caDraw::Color::White);
	};
	label2->WhenDeselected = [&label2](const caUI::EventArgs& args) {
		label2->setBackColor(caDraw::Color::Gray);
	};
	label2->WhenKeyDown = [&label2](const caUI::KeyEventArgs& args) {
		switch (args.key)
		{
		case caSys::Keys::Space:
			label2->setPosition({ 128, 128 });
			break;
		}
	};

	auto button1 = canew<caUI::Button>();
	button1->setFont(font1);
	button1->setText(L"button1");
	button1->setBackColor(caDraw::Color::Gray);
	button1->setPosition({ 128, 300 });
	button1->setSize({ 330, 100 });
	button1->WhenClick = [&button1ClickCount, &label1](const caUI::EventArgs& args)
	{
		++button1ClickCount;

		label1->setText(std::to_string(button1ClickCount));
	};

	auto verticalScrollBar1 = canew<caUI::VerticalScrollBar>();
	verticalScrollBar1->transform.position = { 750, 32 };
	verticalScrollBar1->setSize({24, 256});
	verticalScrollBar1->setMaxValue(1024);
	verticalScrollBar1->WhenValueChanged = [&verticalScrollBar1, &label2](const caUI::EventArgs& args)
	{
		label2->setText(std::to_string(verticalScrollBar1->getValue()));
	};

	auto verticalScrollBar2 = canew<caUI::VerticalScrollBar>();
	verticalScrollBar2->transform.position = { 700, 32 };
	verticalScrollBar2->setSize({ 24, 256 });
	verticalScrollBar2->setMaxValue(1024);
	verticalScrollBar2->setMinBarLength(32);
	verticalScrollBar2->WhenValueChanged = [&verticalScrollBar2, &verticalScrollBar1](const caUI::EventArgs& args)
	{
		verticalScrollBar1->setMaxValue(verticalScrollBar2->getValue());
	};

	auto panel = caFactory->createPanel();
	panel->transform.position = { 64, 64 };
	panel->size = { 800, 600 };

	panel->addDrawable(sprite4);
	panel->addDrawable(sprite1);
	panel->addDrawable(sprite2);
	panel->addDrawable(sprite3);
	panel->addDrawable(rect);
	panel->addDrawable(ellipse);
	panel->addDrawable(ellipse2);
	panel->addDrawable(line1);
	panel->addDrawable(text1);
	panel->addDrawable(label1);
	panel->addUpdatable(label1);
	panel->addDrawable(button1);
	panel->addUpdatable(button1);
	panel->addDrawable(verticalScrollBar1);
	panel->addUpdatable(verticalScrollBar1);
	panel->addDrawable(verticalScrollBar2);
	panel->addUpdatable(verticalScrollBar2);

	window1->addPanel(panel);

	auto panel2 = caFactory->createPanel();
	panel2->transform.position = { 512, 400 };
	panel2->size = { 400, 300 };

	panel2->addDrawable(sprite4);
	panel2->addDrawable(sprite1);
	panel2->addDrawable(sprite2);
	panel2->addDrawable(sprite3);
	panel2->addDrawable(rect);
	panel2->addDrawable(ellipse);
	panel2->addDrawable(line1);
	panel2->addDrawable(text1);
	panel2->addDrawable(label2);
	panel2->addUpdatable(label2);

	window1->addPanel(panel2);

	f32 myScale = 1.0f;
	f32 scaleDir = 1.0f;

	while (window1->isRunning())
	{
		caTouch->update();

		caKeyboard->update();

		if (caKeyboard->isKeyPressed(caSys::Keys::W))
		{
			ellipse2->y -= 0.4f;
		}
		else if (caKeyboard->isKeyPressed(caSys::Keys::S))
		{
			ellipse2->y += 0.4f;
		}

		if (caKeyboard->isKeyPressed(caSys::Keys::A))
		{
			ellipse2->x -= 0.4f;
		}
		else if (caKeyboard->isKeyPressed(caSys::Keys::D))
		{
			ellipse2->x += 0.4f;
		}

		myScale -= scaleDir * myScale / 64.0f;
		if (scaleDir > 0.0f && myScale < 0.1f)
		{
			scaleDir = -1.0f;
		}
		else if (scaleDir < 0.0f && myScale > 2.0f)
		{
			scaleDir = 1.0f;
		}

		sprite1->transform.scale.setVector(myScale, myScale);
		sprite2->transform.scale.setVector(myScale, myScale);
		sprite3->transform.scale.setVector(myScale, myScale);

		panel2->transform.angle += 0.02f;

		rect->setVisible(ellipse->containsPoint(ellipse2->x, ellipse2->y));

		auto invPoint = panel2->transform.inverseTransformPoint(caTouch->getPositionF(*window1));
		ellipse2->setLocation(invPoint.x, invPoint.y);

		if (label1->isFocused())
		{
			label1->setPosition(label1->getPosition() + caDraw::PointF(0.4f, 0.0f));
		}

		if (label2->isFocused())
		{
			label2->setPosition(label2->getPosition() + caDraw::PointF(0.4f, 0.0f));
		}

		window1->update();
		window1->draw(caDraw::Color(230, 230, 230));
	}

	return 0;
}

<commit_msg>Fix sample code.<commit_after>#include <CodeAdapter\EasyCA.h>
#include <CodeAdapterSFML\SFMLFactory.h>

int main()
{
	initializeCA<SFMLFactory>();

	i32 button1ClickCount = 0;

	auto window1 = caFactory->createWindow();
	window1->create(caDraw::Size(1024, 768), caUtil::String("Hello, World!"));

	auto rect = canew<caDraw::DrawableRectangle>(-32, -64, 256, 128);
	rect->edgeColor = caDraw::Color::Magenta;
	rect->fillColor = caDraw::Color::Yellow;
	rect->edgeWidth = 8.0f;

	auto ellipse = canew<caDraw::DrawableEllipse>(-32, -64, 256, 128);
	ellipse->edgeColor = caDraw::Color::Yellow;
	ellipse->fillColor = caDraw::Color::Magenta;
	ellipse->edgeWidth = 2.0f;

	auto ellipse2 = canew<caDraw::DrawableEllipse>(-40, -70, 2, 2);
	ellipse2->edgeColor = caDraw::Color::Red;
	ellipse2->fillColor = caDraw::Color::Red;
	ellipse2->edgeWidth = 1.0f;

	auto line1 = canew<caDraw::DrawableLine>(rect->x, rect->y,
		rect->x + rect->width, rect->y + rect->height);
	line1->color = caDraw::Color::Cyan;
	line1->thickness = 8.0f;

	auto font1 = caFactory->createFont();
	font1->loadFromFile("NanumGothic.ttf");
	font1->setCharacterSize(64);
	font1->setStyle(caDraw::FontStyles::Underline | caDraw::FontStyles::Bold);

	auto text1 = canew<caDraw::DrawableText>();
	text1->setFont(font1);
	text1->text = L"Hello, World!\nȳ !";
	text1->location.setLocation(64, 8);
	text1->color = caDraw::Color(34, 177, 76);

	auto texture1 = caFactory->createTexture();
	texture1->loadFromFile("neurowhai.png");

	auto sprite1 = canew<caDraw::DrawableTexture>();
	sprite1->setTexture(texture1);
	sprite1->location.setLocation(-512.f, -512.f);
	sprite1->color = caDraw::Color(caDraw::Color::Red, 85);
	sprite1->transform.scale.setVector(0.5f, 0.5f);

	auto sprite2 = canew<caDraw::DrawableTexture>();
	sprite2->setTexture(texture1);
	sprite2->location.setLocation(-512.f + 16.f, -512.f);
	sprite2->color = caDraw::Color(caDraw::Color::Green, 85);
	sprite2->transform.scale.setVector(0.5f, 0.5f);

	auto sprite3 = canew<caDraw::DrawableTexture>();
	sprite3->setTexture(texture1);
	sprite3->location.setLocation(-512.f + 8.f, -512.f + 13.85f);
	sprite3->color = caDraw::Color(caDraw::Color::Blue, 85);
	sprite3->transform.scale.setVector(0.5f, 0.5f);

	auto sprite4 = canew<caDraw::DrawableTexture>();
	sprite4->setTexture(texture1);
	sprite4->location.setLocation(-512.f, -512.f);

	auto label1 = canew<caUI::Label>();
	label1->setFont(font1);
	label1->setText(L"label1 text");
	label1->setTextMargin({ 8, 0 });
	label1->setBackColor(caDraw::Color::Gray);
	label1->setPosition({ 128, 128 });
	label1->setSize({ 330, 100 });
	label1->setSelectable(true);
	label1->WhenTouchDown = [&label1](const caUI::TouchEventArgs& args) {
		label1->setTextColor(caDraw::Color::Red);
		label1->setPosition({ static_cast<f32>(args.x) - 165,
			static_cast<f32>(args.y) - 50 });
	};
	label1->WhenTouchUp = [&label1](const caUI::TouchEventArgs& args) {
		label1->setTextColor(caDraw::Color::Black);
	};
	label1->WhenEnterFocus = [&label1](const caUI::EventArgs& args) {
		label1->setTextColor(caDraw::Color::Blue);
	};
	label1->WhenLeaveFocus = [&label1](const caUI::EventArgs& args) {
		label1->setTextColor(caDraw::Color::Black);
	};
	label1->WhenSelected = [&label1](const caUI::EventArgs& args) {
		label1->setBackColor(caDraw::Color::White);
	};
	label1->WhenDeselected = [&label1](const caUI::EventArgs& args) {
		label1->setBackColor(caDraw::Color::Gray);
	};
	label1->WhenKeyDown = [&label1](const caUI::KeyEventArgs& args) {
		switch (args.key)
		{
		case caSys::Keys::Space:
			label1->setPosition({ 128, 128 });
			break;
		}
	};

	auto label2 = canew<caUI::Label>(*label1);
	label2->WhenTouchDown = [&label2](const caUI::TouchEventArgs& args) {
		label2->setTextColor(caDraw::Color::Red);
		label2->setPosition({ static_cast<f32>(args.x) - 165,
			static_cast<f32>(args.y) - 50 });
	};
	label2->WhenTouchUp = [&label2](const caUI::TouchEventArgs& args) {
		label2->setTextColor(caDraw::Color::Black);
	};
	label2->WhenEnterFocus = [&label2](const caUI::EventArgs& args) {
		label2->setTextColor(caDraw::Color::Blue);
	};
	label2->WhenLeaveFocus = [&label2](const caUI::EventArgs& args) {
		label2->setTextColor(caDraw::Color::Black);
	};
	label2->WhenSelected = [&label2](const caUI::EventArgs& args) {
		label2->setBackColor(caDraw::Color::White);
	};
	label2->WhenDeselected = [&label2](const caUI::EventArgs& args) {
		label2->setBackColor(caDraw::Color::Gray);
	};
	label2->WhenKeyDown = [&label2](const caUI::KeyEventArgs& args) {
		switch (args.key)
		{
		case caSys::Keys::Space:
			label2->setPosition({ 128, 128 });
			break;
		}
	};

	auto button1 = canew<caUI::Button>();
	button1->setFont(font1);
	button1->setText(L"button1");
	button1->setBackColor(caDraw::Color::Gray);
	button1->setPosition({ 128, 300 });
	button1->setSize({ 330, 100 });
	button1->WhenClick = [&button1ClickCount, &label1](const caUI::EventArgs& args)
	{
		++button1ClickCount;

		label1->setText(std::to_string(button1ClickCount));
	};

	auto verticalScrollBar1 = canew<caUI::VerticalScrollBar>();
	verticalScrollBar1->setPosition({ 750, 32 });
	verticalScrollBar1->setSize({24, 256});
	verticalScrollBar1->setMaxValue(1024);
	verticalScrollBar1->WhenValueChanged = [&verticalScrollBar1, &label2](const caUI::EventArgs& args)
	{
		label2->setText(std::to_string(verticalScrollBar1->getValue()));
	};

	auto verticalScrollBar2 = canew<caUI::VerticalScrollBar>();
	verticalScrollBar2->setPosition({ 700, 32 });
	verticalScrollBar2->setSize({ 24, 256 });
	verticalScrollBar2->setMaxValue(256);
	verticalScrollBar2->setMinBarLength(32);
	verticalScrollBar2->WhenValueChanged = [&verticalScrollBar2, &verticalScrollBar1](const caUI::EventArgs& args)
	{
		verticalScrollBar1->setMaxValue(verticalScrollBar2->getValue());
	};

	verticalScrollBar1->setMaxValue(verticalScrollBar2->getValue());

	auto panel = caFactory->createPanel();
	panel->transform.position = { 64, 64 };
	panel->size = { 800, 600 };

	panel->addDrawable(sprite4);
	panel->addDrawable(sprite1);
	panel->addDrawable(sprite2);
	panel->addDrawable(sprite3);
	panel->addDrawable(rect);
	panel->addDrawable(ellipse);
	panel->addDrawable(ellipse2);
	panel->addDrawable(line1);
	panel->addDrawable(text1);
	panel->addDrawable(label1);
	panel->addUpdatable(label1);
	panel->addDrawable(button1);
	panel->addUpdatable(button1);
	panel->addDrawable(verticalScrollBar1);
	panel->addUpdatable(verticalScrollBar1);
	panel->addDrawable(verticalScrollBar2);
	panel->addUpdatable(verticalScrollBar2);

	window1->addPanel(panel);

	auto panel2 = caFactory->createPanel();
	panel2->transform.position = { 512, 400 };
	panel2->size = { 400, 300 };

	panel2->addDrawable(sprite4);
	panel2->addDrawable(sprite1);
	panel2->addDrawable(sprite2);
	panel2->addDrawable(sprite3);
	panel2->addDrawable(rect);
	panel2->addDrawable(ellipse);
	panel2->addDrawable(line1);
	panel2->addDrawable(text1);
	panel2->addDrawable(label2);
	panel2->addUpdatable(label2);

	window1->addPanel(panel2);

	f32 myScale = 1.0f;
	f32 scaleDir = 1.0f;

	while (window1->isRunning())
	{
		caTouch->update();

		caKeyboard->update();

		if (caKeyboard->isKeyPressed(caSys::Keys::W))
		{
			ellipse2->y -= 0.4f;
		}
		else if (caKeyboard->isKeyPressed(caSys::Keys::S))
		{
			ellipse2->y += 0.4f;
		}

		if (caKeyboard->isKeyPressed(caSys::Keys::A))
		{
			ellipse2->x -= 0.4f;
		}
		else if (caKeyboard->isKeyPressed(caSys::Keys::D))
		{
			ellipse2->x += 0.4f;
		}

		myScale -= scaleDir * myScale / 64.0f;
		if (scaleDir > 0.0f && myScale < 0.1f)
		{
			scaleDir = -1.0f;
		}
		else if (scaleDir < 0.0f && myScale > 2.0f)
		{
			scaleDir = 1.0f;
		}

		sprite1->transform.scale.setVector(myScale, myScale);
		sprite2->transform.scale.setVector(myScale, myScale);
		sprite3->transform.scale.setVector(myScale, myScale);

		panel2->transform.angle += 0.02f;

		rect->setVisible(ellipse->containsPoint(ellipse2->x, ellipse2->y));

		auto invPoint = panel2->transform.inverseTransformPoint(caTouch->getPositionF(*window1));
		ellipse2->setLocation(invPoint.x, invPoint.y);

		if (label1->isFocused())
		{
			label1->setPosition(label1->getPosition() + caDraw::PointF(0.4f, 0.0f));
		}

		if (label2->isFocused())
		{
			label2->setPosition(label2->getPosition() + caDraw::PointF(0.4f, 0.0f));
		}

		window1->update();
		window1->draw(caDraw::Color(230, 230, 230));
	}

	return 0;
}

<|endoftext|>


<commit_before>#ifndef COFFEE_MILL_DCD_MODE
#define COFFEE_MILL_DCD_MODE
// #include "DCDtoMovie.hpp"
// #include "SuperImpose.hpp"
#include <src/mill_dcd_join.hpp>
// #include "mill_dcd_extract.hpp"
// #include "mill_dcd_msd.hpp"
// #include "mode_dcd_help.hpp"

namespace mill
{

// argv := arrayof{ "dcd", "command-name", {rests...} }
template<typename vectorT>
int mode_dcd(int argument_c, const char **argument_v)
{
    if(argument_c < 2)
    {
        // no commands provided: {"dcd"}
        std::cerr << "error: mill dcd-mode: too few arguments\n";
        mode_dcd_help(--argument_c, ++argument_v); // {}
        return 1;
    }

    const std::string command(argument_v[1]);
    if(command == "join")
    {
        // {"join", {"args"...}}
        return mill_dcd_join<vectorT>(--argument_c, ++argument_v);
    }
//     else if(command == "make-movie")
//     {
//         if(argument_c != 3)
//         {
//             std::cerr << "usage: mill dcd make-movie [file.dcd | file.toml]"
//                       << std::endl;
//             return 1;
//         }
//         const std::string fname(argument_v[2]);
//         return dcd_to_movie<vectorT>(fname);
//     }
//     else if(command == "impose")
//     {
//         if(argument_c != 3)
//         {
//             std::cerr << "usage: mill dcd impose [file.dcd | file.toml]"
//                       << std::endl;
//             return 1;
//         }
//         std::string fname(argument_v[2]);
//         return superimpose<vectorT>(fname);
//     }
//     else if(command == "extract")
//     {
//         if(argument_c < 3)
//         {
//             std::cerr << "usage: mill dcd extract [file.dcd | file.toml]"
//                       << " [begin, end]" << std::endl;
//             return 1;
//         }
//         return mill_dcd_extract<vectorT>(argument_c - 1, argument_v+1);
//     }
//     else if(command == "msd")
//     {
//         if(argument_c < 3)
//         {
//             std::cerr << "usage: mill dcd msd [file.dcd, ... | file.toml]"
//                       << std::endl;
//             return 1;
//         }
//         return mill_dcd_msd<vectorT>(argument_c - 1, argument_v+1);
//     }
    else if(command == "help")
    {
        // {"dcd", "help", {args...}} -> {"help", {args...}}
        return mode_dcd_help(--argument_c, ++argument_v);
    }
    else
    {
        std::cerr << "error: mill dcd-mode: unknown command : " << command << '\n';
        return 1;
    }
}

} // mill

#endif /* COFFEE_MILL_PDB_MODE */
<commit_msg>fix typo<commit_after>#ifndef COFFEE_MILL_DCD_MODE
#define COFFEE_MILL_DCD_MODE
// #include "DCDtoMovie.hpp"
// #include "SuperImpose.hpp"
#include <src/mode_dcd_join.hpp>
// #include "mill_dcd_extract.hpp"
// #include "mill_dcd_msd.hpp"
// #include "mode_dcd_help.hpp"

namespace mill
{

// argv := arrayof{ "dcd", "command-name", {rests...} }
template<typename vectorT>
int mode_dcd(int argument_c, const char **argument_v)
{
    if(argument_c < 2)
    {
        // no commands provided: {"dcd"}
        std::cerr << "error: mill dcd-mode: too few arguments\n";
        mode_dcd_help(--argument_c, ++argument_v); // {}
        return 1;
    }

    const std::string command(argument_v[1]);
    if(command == "join")
    {
        // {"join", {"args"...}}
        return mode_dcd_join<vectorT>(--argument_c, ++argument_v);
    }
//     else if(command == "make-movie")
//     {
//         if(argument_c != 3)
//         {
//             std::cerr << "usage: mill dcd make-movie [file.dcd | file.toml]"
//                       << std::endl;
//             return 1;
//         }
//         const std::string fname(argument_v[2]);
//         return dcd_to_movie<vectorT>(fname);
//     }
//     else if(command == "impose")
//     {
//         if(argument_c != 3)
//         {
//             std::cerr << "usage: mill dcd impose [file.dcd | file.toml]"
//                       << std::endl;
//             return 1;
//         }
//         std::string fname(argument_v[2]);
//         return superimpose<vectorT>(fname);
//     }
//     else if(command == "extract")
//     {
//         if(argument_c < 3)
//         {
//             std::cerr << "usage: mill dcd extract [file.dcd | file.toml]"
//                       << " [begin, end]" << std::endl;
//             return 1;
//         }
//         return mill_dcd_extract<vectorT>(argument_c - 1, argument_v+1);
//     }
//     else if(command == "msd")
//     {
//         if(argument_c < 3)
//         {
//             std::cerr << "usage: mill dcd msd [file.dcd, ... | file.toml]"
//                       << std::endl;
//             return 1;
//         }
//         return mill_dcd_msd<vectorT>(argument_c - 1, argument_v+1);
//     }
    else if(command == "help")
    {
        // {"dcd", "help", {args...}} -> {"help", {args...}}
        return mode_dcd_help(--argument_c, ++argument_v);
    }
    else
    {
        std::cerr << "error: mill dcd-mode: unknown command : " << command << '\n';
        return 1;
    }
}

} // mill

#endif /* COFFEE_MILL_PDB_MODE */
<|endoftext|>


<commit_before>#ifndef KEYCODE_HPP
#define KEYCODE_HPP

namespace org_pqrs_KeyRemap4MacBook {
  // ======================================================================
  class EventType {
  public:
    EventType(unsigned int v = 0) : value_(v) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const EventType& other) const { return value_ == other.get(); }
    bool operator!=(const EventType& other) const { return ! (*this == other); }

#include "keycode/output/include.EventType.hpp"

  private:
    unsigned int value_;
  };

  // ======================================================================
  class KeyboardType {
  public:
    KeyboardType(unsigned int v = 0) : value_(v) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const KeyboardType& other) const { return value_ == other.get(); }
    bool operator!=(const KeyboardType& other) const { return ! (*this == other); }

    bool isInternalKeyboard(void) const;

#include "keycode/output/include.KeyboardType.hpp"

  private:
    unsigned int value_;
  };

  // ======================================================================
  class KeyCode;
  class Flags;

  class ModifierFlag {
  public:
    unsigned int get(void) const { return value_; }
    bool operator==(const ModifierFlag& other) const { return value_ == other.get(); }
    bool operator!=(const ModifierFlag& other) const { return ! (*this == other); }

    unsigned int operator~(void) const { return ~value_; }

    const KeyCode& getKeyCode(void) const;

#include "keycode/output/include.ModifierFlag.hpp"

  private:
    ModifierFlag(unsigned int v) : value_(v) {}
    unsigned int value_;
  };
  namespace ModifierFlagList {
    const ModifierFlag list[] = {
      ModifierFlag::CAPSLOCK,
      ModifierFlag::SHIFT_L,
      ModifierFlag::SHIFT_R,
      ModifierFlag::CONTROL_L,
      ModifierFlag::CONTROL_R,
      ModifierFlag::OPTION_L,
      ModifierFlag::OPTION_R,
      ModifierFlag::COMMAND_L,
      ModifierFlag::COMMAND_R,
      ModifierFlag::FN,
    };
    const int listsize = sizeof(list) / sizeof(list[0]);
  };
  class Flags {
  public:
    Flags(unsigned int v = 0) : value_(v) {}
    Flags(const ModifierFlag& v) : value_(v.get()) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const Flags& other) const { return value_ == other.get(); }
    bool operator!=(const Flags& other) const { return ! (*this == other); }

    Flags operator|(const Flags& other) const { return value_ | other.get(); }
    Flags operator&(const Flags& other) const { return value_ & other.get(); }

    Flags& add(const Flags& flags) { value_ |= flags.get(); return *this; }
    Flags& stripFN(void)     { value_ &= ~ModifierFlag::FN;     return *this; }
    Flags& stripCURSOR(void) { value_ &= ~ModifierFlag::CURSOR; return *this; }
    Flags& stripKEYPAD(void) { value_ &= ~ModifierFlag::KEYPAD; return *this; }
    Flags& stripNONE(void)   { value_ &= ~ModifierFlag::NONE;   return *this; }

    bool isOn(const ModifierFlag& flag) const {
      return (value_ & flag.get()) == flag.get();
    }
    bool isOn(const Flags& flags) const {
      if (flags.isOn(ModifierFlag::NONE)) {
        return (value_ | ModifierFlag::NONE.get()) == flags.get();
      } else {
        return (value_ & flags.get()) == flags.get();
      }
    }

  private:
    unsigned int value_;
  };
  inline Flags operator|(const ModifierFlag& lhs, const ModifierFlag& rhs) { return lhs.get() | rhs.get(); }

  // ======================================================================
  class KeyCode {
  public:
    KeyCode(unsigned int v = 0) : value_(v) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const KeyCode& other) const { return value_ == other.get(); }
    bool operator!=(const KeyCode& other) const { return ! (*this == other); }

    bool operator> (const KeyCode& other) const { return value_ > other.get(); }
    bool operator>=(const KeyCode& other) const { return value_ >= other.get(); }

    void normalizeKey(Flags & flags, const KeyboardType &keyboardType);
    void reverseNormalizeKey(Flags & flags, const KeyboardType &keyboardType);

    ModifierFlag getModifierFlag(void) const;
    bool isModifier(void) const { return getModifierFlag() != ModifierFlag::NONE; }

#include "keycode/output/include.KeyCode.hpp"

  private:
    unsigned int value_;
  };

  // ======================================================================
  class ConsumerKeyCode {
  public:
    ConsumerKeyCode(unsigned int v = 0) : value_(v) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const ConsumerKeyCode& other) const { return value_ == other.get(); }
    bool operator!=(const ConsumerKeyCode& other) const { return ! (*this == other); }

    bool operator> (const ConsumerKeyCode& other) const { return value_ > other.get(); }
    bool operator>=(const ConsumerKeyCode& other) const { return value_ >= other.get(); }

#include "keycode/output/include.ConsumerKeyCode.hpp"

  private:
    unsigned int value_;
  };

  // ======================================================================
  class Buttons;

  class PointingButton {
  public:
    unsigned int get(void) const { return value_; }
    bool operator==(const PointingButton& other) const { return value_ == other.get(); }
    bool operator!=(const PointingButton& other) const { return ! (*this == other); }

    unsigned int operator~(void) const { return ~value_; }

#include "keycode/output/include.PointingButton.hpp"

  private:
    PointingButton(unsigned int v) : value_(v) {}
    unsigned int value_;
  };
  class Buttons {
  public:
    Buttons(unsigned int v = 0) : value_(v) {}
    Buttons(const PointingButton& v) : value_(v.get()) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const Buttons& other) const { return value_ == other.get(); }
    bool operator!=(const Buttons& other) const { return ! (*this == other); }

    Buttons& add(const PointingButton& button) { value_ |= button.get(); return *this; }
    Buttons& remove(const PointingButton& button) { value_ &= ~button; return *this; }

    bool isNONE(void) const { return value_ == 0; }
    bool isOn(const Buttons& buttons) {
      return (value_ & buttons.get()) == buttons.get();
    }

  private:
    unsigned int value_;
  };
  inline Buttons operator|(const PointingButton& lhs, const PointingButton& rhs) { return lhs.get() | rhs.get(); }
}

#endif
<commit_msg>update keycode @ kext<commit_after>#ifndef KEYCODE_HPP
#define KEYCODE_HPP

namespace org_pqrs_KeyRemap4MacBook {
  // ======================================================================
  class EventType {
  public:
    EventType(unsigned int v = 0) : value_(v) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const EventType& other) const { return value_ == other.get(); }
    bool operator!=(const EventType& other) const { return ! (*this == other); }

#include "keycode/output/include.EventType.hpp"

  private:
    unsigned int value_;
  };

  // ======================================================================
  class KeyboardType {
  public:
    KeyboardType(unsigned int v = 0) : value_(v) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const KeyboardType& other) const { return value_ == other.get(); }
    bool operator!=(const KeyboardType& other) const { return ! (*this == other); }

    bool isInternalKeyboard(void) const;

#include "keycode/output/include.KeyboardType.hpp"

  private:
    unsigned int value_;
  };

  // ======================================================================
  class KeyCode;
  class Flags;

  class ModifierFlag {
  public:
    unsigned int get(void) const { return value_; }
    bool operator==(const ModifierFlag& other) const { return value_ == other.get(); }
    bool operator!=(const ModifierFlag& other) const { return ! (*this == other); }

    unsigned int operator~(void) const { return ~value_; }

    const KeyCode& getKeyCode(void) const;

#include "keycode/output/include.ModifierFlag.hpp"

  private:
    ModifierFlag(unsigned int v) : value_(v) {}
    unsigned int value_;
  };
  namespace ModifierFlagList {
    const ModifierFlag list[] = {
      ModifierFlag::CAPSLOCK,
      ModifierFlag::SHIFT_L,
      ModifierFlag::SHIFT_R,
      ModifierFlag::CONTROL_L,
      ModifierFlag::CONTROL_R,
      ModifierFlag::OPTION_L,
      ModifierFlag::OPTION_R,
      ModifierFlag::COMMAND_L,
      ModifierFlag::COMMAND_R,
      ModifierFlag::FN,
    };
    const int listsize = sizeof(list) / sizeof(list[0]);
  };
  class Flags {
  public:
    Flags(unsigned int v = 0) : value_(v) {}
    Flags(const ModifierFlag& v) : value_(v.get()) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const Flags& other) const { return value_ == other.get(); }
    bool operator!=(const Flags& other) const { return ! (*this == other); }

    Flags operator|(const Flags& other) const { return value_ | other.get(); }
    Flags operator&(const Flags& other) const { return value_ & other.get(); }

    Flags& add(const Flags& flags) { value_ |= flags.get(); return *this; }
    Flags& stripFN(void)     { value_ &= ~ModifierFlag::FN;     return *this; }
    Flags& stripCURSOR(void) { value_ &= ~ModifierFlag::CURSOR; return *this; }
    Flags& stripKEYPAD(void) { value_ &= ~ModifierFlag::KEYPAD; return *this; }
    Flags& stripNONE(void)   { value_ &= ~ModifierFlag::NONE;   return *this; }

    bool isOn(const ModifierFlag& flag) const {
      return (value_ & flag.get()) == flag.get();
    }
    bool isOn(const Flags& flags) const {
      if (flags.isOn(ModifierFlag::NONE)) {
        return (value_ | ModifierFlag::NONE.get()) == flags.get();
      } else {
        return (value_ & flags.get()) == flags.get();
      }
    }

  private:
    unsigned int value_;
  };
  inline Flags operator|(const ModifierFlag& lhs, const ModifierFlag& rhs) { return lhs.get() | rhs.get(); }

  // ======================================================================
  class KeyCode {
  public:
    KeyCode(unsigned int v = 0) : value_(v) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const KeyCode& other) const { return value_ == other.get(); }
    bool operator!=(const KeyCode& other) const { return ! (*this == other); }

    bool operator> (const KeyCode& other) const { return value_ > other.get(); }
    bool operator>=(const KeyCode& other) const { return value_ >= other.get(); }

    void normalizeKey(Flags & flags, const KeyboardType &keyboardType);
    void reverseNormalizeKey(Flags & flags, const KeyboardType &keyboardType);

    ModifierFlag getModifierFlag(void) const;
    bool isModifier(void) const { return getModifierFlag() != ModifierFlag::NONE; }

#include "keycode/output/include.KeyCode.hpp"

  private:
    unsigned int value_;
  };

  // ======================================================================
  class ConsumerKeyCode {
  public:
    ConsumerKeyCode(unsigned int v = 0) : value_(v) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const ConsumerKeyCode& other) const { return value_ == other.get(); }
    bool operator!=(const ConsumerKeyCode& other) const { return ! (*this == other); }

    bool operator> (const ConsumerKeyCode& other) const { return value_ > other.get(); }
    bool operator>=(const ConsumerKeyCode& other) const { return value_ >= other.get(); }

#include "keycode/output/include.ConsumerKeyCode.hpp"

  private:
    unsigned int value_;
  };

  // ======================================================================
  class Buttons;

  class PointingButton {
  public:
    unsigned int get(void) const { return value_; }
    bool operator==(const PointingButton& other) const { return value_ == other.get(); }
    bool operator!=(const PointingButton& other) const { return ! (*this == other); }

    unsigned int operator~(void) const { return ~value_; }

#include "keycode/output/include.PointingButton.hpp"

  private:
    PointingButton(unsigned int v) : value_(v) {}
    unsigned int value_;
  };
  class Buttons {
  public:
    Buttons(unsigned int v = 0) : value_(v) {}
    Buttons(const PointingButton& v) : value_(v.get()) {}
    unsigned int get(void) const { return value_; }
    bool operator==(const Buttons& other) const { return value_ == other.get(); }
    bool operator!=(const Buttons& other) const { return ! (*this == other); }

    Buttons operator|(const Buttons& other) const { return value_ | other.get(); }

    Buttons& add(const PointingButton& button) { value_ |= button.get(); return *this; }
    Buttons& remove(const PointingButton& button) { value_ &= ~button; return *this; }

    bool isNONE(void) const { return value_ == 0; }
    bool isOn(const Buttons& buttons) {
      return (value_ & buttons.get()) == buttons.get();
    }

  private:
    unsigned int value_;
  };
  inline Buttons operator|(const PointingButton& lhs, const PointingButton& rhs) { return lhs.get() | rhs.get(); }
}

#endif
<|endoftext|>


<commit_before>//==- CGObjCRuntime.cpp - Interface to Shared Objective-C Runtime Features ==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This abstract class defines the interface for Objective-C runtime-specific
// code generation.  It provides some concrete helper methods for functionality
// shared between all (or most) of the Objective-C runtimes supported by clang.
//
//===----------------------------------------------------------------------===//

#include "CGObjCRuntime.h"

#include "CGRecordLayout.h"
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
#include "CGCleanup.h"

#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtObjC.h"

#include "llvm/Support/CallSite.h"

using namespace clang;
using namespace CodeGen;

static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
                                     const ObjCInterfaceDecl *OID,
                                     const ObjCImplementationDecl *ID,
                                     const ObjCIvarDecl *Ivar) {
  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();

  // FIXME: We should eliminate the need to have ObjCImplementationDecl passed
  // in here; it should never be necessary because that should be the lexical
  // decl context for the ivar.

  // If we know have an implementation (and the ivar is in it) then
  // look up in the implementation layout.
  const ASTRecordLayout *RL;
  if (ID && declaresSameEntity(ID->getClassInterface(), Container))
    RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
  else
    RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);

  // Compute field index.
  //
  // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
  // implemented. This should be fixed to get the information from the layout
  // directly.
  unsigned Index = 0;

  for (const ObjCIvarDecl *IVD = Container->all_declared_ivar_begin();
       IVD; IVD = IVD->getNextIvar()) {
    if (Ivar == IVD)
      break;
    ++Index;
  }
  assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");

  return RL->getFieldOffset(Index);
}

uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
                                              const ObjCInterfaceDecl *OID,
                                              const ObjCIvarDecl *Ivar) {
  return LookupFieldBitOffset(CGM, OID, 0, Ivar) /
    CGM.getContext().getCharWidth();
}

uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
                                              const ObjCImplementationDecl *OID,
                                              const ObjCIvarDecl *Ivar) {
  return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) /
    CGM.getContext().getCharWidth();
}

LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
                                               const ObjCInterfaceDecl *OID,
                                               llvm::Value *BaseValue,
                                               const ObjCIvarDecl *Ivar,
                                               unsigned CVRQualifiers,
                                               llvm::Value *Offset) {
  // Compute (type*) ( (char *) BaseValue + Offset)
  llvm::Type *I8Ptr = CGF.Int8PtrTy;
  QualType IvarTy = Ivar->getType();
  llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
  llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr);
  V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr");
  V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));

  if (!Ivar->isBitField()) {
    LValue LV = CGF.MakeNaturalAlignAddrLValue(V, IvarTy);
    LV.getQuals().addCVRQualifiers(CVRQualifiers);
    return LV;
  }

  // We need to compute an access strategy for this bit-field. We are given the
  // offset to the first byte in the bit-field, the sub-byte offset is taken
  // from the original layout. We reuse the normal bit-field access strategy by
  // treating this as an access to a struct where the bit-field is in byte 0,
  // and adjust the containing type size as appropriate.
  //
  // FIXME: Note that currently we make a very conservative estimate of the
  // alignment of the bit-field, because (a) it is not clear what guarantees the
  // runtime makes us, and (b) we don't have a way to specify that the struct is
  // at an alignment plus offset.
  //
  // Note, there is a subtle invariant here: we can only call this routine on
  // non-synthesized ivars but we may be called for synthesized ivars.  However,
  // a synthesized ivar can never be a bit-field, so this is safe.
  const ASTRecordLayout &RL =
    CGF.CGM.getContext().getASTObjCInterfaceLayout(OID);
  uint64_t TypeSizeInBits = CGF.CGM.getContext().toBits(RL.getSize());
  uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar);
  uint64_t BitOffset = FieldBitOffset % CGF.CGM.getContext().getCharWidth();
  uint64_t ContainingTypeAlign = CGF.CGM.getContext().getTargetInfo().getCharAlign();
  uint64_t ContainingTypeSize = TypeSizeInBits - (FieldBitOffset - BitOffset);
  uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext());

  // Allocate a new CGBitFieldInfo object to describe this access.
  //
  // FIXME: This is incredibly wasteful, these should be uniqued or part of some
  // layout object. However, this is blocked on other cleanups to the
  // Objective-C code, so for now we just live with allocating a bunch of these
  // objects.
  CGBitFieldInfo *Info = new (CGF.CGM.getContext()) CGBitFieldInfo(
    CGBitFieldInfo::MakeInfo(CGF.CGM.getTypes(), Ivar, BitOffset, BitFieldSize,
                             ContainingTypeSize, ContainingTypeAlign));

  return LValue::MakeBitfield(V, *Info,
                              IvarTy.withCVRQualifiers(CVRQualifiers));
}

namespace {
  struct CatchHandler {
    const VarDecl *Variable;
    const Stmt *Body;
    llvm::BasicBlock *Block;
    llvm::Value *TypeInfo;
  };

  struct CallObjCEndCatch : EHScopeStack::Cleanup {
    CallObjCEndCatch(bool MightThrow, llvm::Value *Fn) :
      MightThrow(MightThrow), Fn(Fn) {}
    bool MightThrow;
    llvm::Value *Fn;

    void Emit(CodeGenFunction &CGF, Flags flags) {
      if (!MightThrow) {
        CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
        return;
      }

      CGF.EmitCallOrInvoke(Fn);
    }
  };
}

void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF,
                                     const ObjCAtTryStmt &S,
                                     llvm::Constant *beginCatchFn,
                                     llvm::Constant *endCatchFn,
                                     llvm::Constant *exceptionRethrowFn) {
  // Jump destination for falling out of catch bodies.
  CodeGenFunction::JumpDest Cont;
  if (S.getNumCatchStmts())
    Cont = CGF.getJumpDestInCurrentScope("eh.cont");

  CodeGenFunction::FinallyInfo FinallyInfo;
  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
    FinallyInfo.enter(CGF, Finally->getFinallyBody(),
                      beginCatchFn, endCatchFn, exceptionRethrowFn);

  SmallVector<CatchHandler, 8> Handlers;

  // Enter the catch, if there is one.
  if (S.getNumCatchStmts()) {
    for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
      const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
      const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();

      Handlers.push_back(CatchHandler());
      CatchHandler &Handler = Handlers.back();
      Handler.Variable = CatchDecl;
      Handler.Body = CatchStmt->getCatchBody();
      Handler.Block = CGF.createBasicBlock("catch");

      // @catch(...) always matches.
      if (!CatchDecl) {
        Handler.TypeInfo = 0; // catch-all
        // Don't consider any other catches.
        break;
      }

      Handler.TypeInfo = GetEHType(CatchDecl->getType());
    }

    EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
    for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
  }

  // Emit the try body.
  CGF.EmitStmt(S.getTryBody());

  // Leave the try.
  if (S.getNumCatchStmts())
    CGF.popCatchScope();

  // Remember where we were.
  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();

  // Emit the handlers.
  for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
    CatchHandler &Handler = Handlers[I];

    CGF.EmitBlock(Handler.Block);
    llvm::Value *RawExn = CGF.getExceptionFromSlot();

    // Enter the catch.
    llvm::Value *Exn = RawExn;
    if (beginCatchFn) {
      Exn = CGF.Builder.CreateCall(beginCatchFn, RawExn, "exn.adjusted");
      cast<llvm::CallInst>(Exn)->setDoesNotThrow();
    }

    CodeGenFunction::LexicalScope cleanups(CGF, Handler.Body->getSourceRange());

    if (endCatchFn) {
      // Add a cleanup to leave the catch.
      bool EndCatchMightThrow = (Handler.Variable == 0);

      CGF.EHStack.pushCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
                                                EndCatchMightThrow,
                                                endCatchFn);
    }

    // Bind the catch parameter if it exists.
    if (const VarDecl *CatchParam = Handler.Variable) {
      llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
      llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);

      CGF.EmitAutoVarDecl(*CatchParam);

      llvm::Value *CatchParamAddr = CGF.GetAddrOfLocalVar(CatchParam);

      switch (CatchParam->getType().getQualifiers().getObjCLifetime()) {
      case Qualifiers::OCL_Strong:
        CastExn = CGF.EmitARCRetainNonBlock(CastExn);
        // fallthrough

      case Qualifiers::OCL_None:
      case Qualifiers::OCL_ExplicitNone:
      case Qualifiers::OCL_Autoreleasing:
        CGF.Builder.CreateStore(CastExn, CatchParamAddr);
        break;

      case Qualifiers::OCL_Weak:
        CGF.EmitARCInitWeak(CatchParamAddr, CastExn);
        break;
      }
    }

    CGF.ObjCEHValueStack.push_back(Exn);
    CGF.EmitStmt(Handler.Body);
    CGF.ObjCEHValueStack.pop_back();

    // Leave any cleanups associated with the catch.
    cleanups.ForceCleanup();

    CGF.EmitBranchThroughCleanup(Cont);
  }

  // Go back to the try-statement fallthrough.
  CGF.Builder.restoreIP(SavedIP);

  // Pop out of the finally.
  if (S.getFinallyStmt())
    FinallyInfo.exit(CGF);

  if (Cont.isValid())
    CGF.EmitBlock(Cont.getBlock());
}

namespace {
  struct CallSyncExit : EHScopeStack::Cleanup {
    llvm::Value *SyncExitFn;
    llvm::Value *SyncArg;
    CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
      : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}

    void Emit(CodeGenFunction &CGF, Flags flags) {
      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
    }
  };
}

void CGObjCRuntime::EmitAtSynchronizedStmt(CodeGenFunction &CGF,
                                           const ObjCAtSynchronizedStmt &S,
                                           llvm::Function *syncEnterFn,
                                           llvm::Function *syncExitFn) {
  CodeGenFunction::RunCleanupsScope cleanups(CGF);

  // Evaluate the lock operand.  This is guaranteed to dominate the
  // ARC release and lock-release cleanups.
  const Expr *lockExpr = S.getSynchExpr();
  llvm::Value *lock;
  if (CGF.getLangOpts().ObjCAutoRefCount) {
    lock = CGF.EmitARCRetainScalarExpr(lockExpr);
    lock = CGF.EmitObjCConsumeObject(lockExpr->getType(), lock);
  } else {
    lock = CGF.EmitScalarExpr(lockExpr);
  }
  lock = CGF.Builder.CreateBitCast(lock, CGF.VoidPtrTy);

  // Acquire the lock.
  CGF.Builder.CreateCall(syncEnterFn, lock)->setDoesNotThrow();

  // Register an all-paths cleanup to release the lock.
  CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup, syncExitFn, lock);

  // Emit the body of the statement.
  CGF.EmitStmt(S.getSynchBody());
}

/// Compute the pointer-to-function type to which a message send
/// should be casted in order to correctly call the given method
/// with the given arguments.
///
/// \param method - may be null
/// \param resultType - the result type to use if there's no method
/// \param argInfo - the actual arguments, including implicit ones
CGObjCRuntime::MessageSendInfo
CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method,
                                  QualType resultType,
                                  CallArgList &callArgs) {
  // If there's a method, use information from that.
  if (method) {
    const CGFunctionInfo &signature =
      CGM.getTypes().arrangeObjCMessageSendSignature(method, callArgs[0].Ty);

    llvm::PointerType *signatureType =
      CGM.getTypes().GetFunctionType(signature)->getPointerTo();

    // If that's not variadic, there's no need to recompute the ABI
    // arrangement.
    if (!signature.isVariadic())
      return MessageSendInfo(signature, signatureType);

    // Otherwise, there is.
    FunctionType::ExtInfo einfo = signature.getExtInfo();
    const CGFunctionInfo &argsInfo =
      CGM.getTypes().arrangeFunctionCall(resultType, callArgs, einfo,
                                         signature.getRequiredArgs());

    return MessageSendInfo(argsInfo, signatureType);
  }

  // There's no method;  just use a default CC.
  const CGFunctionInfo &argsInfo =
    CGM.getTypes().arrangeFunctionCall(resultType, callArgs,
                                       FunctionType::ExtInfo(),
                                       RequiredArgs::All);

  // Derive the signature to call from that.
  llvm::PointerType *signatureType =
    CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo();
  return MessageSendInfo(argsInfo, signatureType);
}
<commit_msg>Documentation fix: made the name given to \param match the code.<commit_after>//==- CGObjCRuntime.cpp - Interface to Shared Objective-C Runtime Features ==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This abstract class defines the interface for Objective-C runtime-specific
// code generation.  It provides some concrete helper methods for functionality
// shared between all (or most) of the Objective-C runtimes supported by clang.
//
//===----------------------------------------------------------------------===//

#include "CGObjCRuntime.h"

#include "CGRecordLayout.h"
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
#include "CGCleanup.h"

#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtObjC.h"

#include "llvm/Support/CallSite.h"

using namespace clang;
using namespace CodeGen;

static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
                                     const ObjCInterfaceDecl *OID,
                                     const ObjCImplementationDecl *ID,
                                     const ObjCIvarDecl *Ivar) {
  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();

  // FIXME: We should eliminate the need to have ObjCImplementationDecl passed
  // in here; it should never be necessary because that should be the lexical
  // decl context for the ivar.

  // If we know have an implementation (and the ivar is in it) then
  // look up in the implementation layout.
  const ASTRecordLayout *RL;
  if (ID && declaresSameEntity(ID->getClassInterface(), Container))
    RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
  else
    RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);

  // Compute field index.
  //
  // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
  // implemented. This should be fixed to get the information from the layout
  // directly.
  unsigned Index = 0;

  for (const ObjCIvarDecl *IVD = Container->all_declared_ivar_begin();
       IVD; IVD = IVD->getNextIvar()) {
    if (Ivar == IVD)
      break;
    ++Index;
  }
  assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");

  return RL->getFieldOffset(Index);
}

uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
                                              const ObjCInterfaceDecl *OID,
                                              const ObjCIvarDecl *Ivar) {
  return LookupFieldBitOffset(CGM, OID, 0, Ivar) /
    CGM.getContext().getCharWidth();
}

uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
                                              const ObjCImplementationDecl *OID,
                                              const ObjCIvarDecl *Ivar) {
  return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) /
    CGM.getContext().getCharWidth();
}

LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
                                               const ObjCInterfaceDecl *OID,
                                               llvm::Value *BaseValue,
                                               const ObjCIvarDecl *Ivar,
                                               unsigned CVRQualifiers,
                                               llvm::Value *Offset) {
  // Compute (type*) ( (char *) BaseValue + Offset)
  llvm::Type *I8Ptr = CGF.Int8PtrTy;
  QualType IvarTy = Ivar->getType();
  llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
  llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr);
  V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr");
  V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));

  if (!Ivar->isBitField()) {
    LValue LV = CGF.MakeNaturalAlignAddrLValue(V, IvarTy);
    LV.getQuals().addCVRQualifiers(CVRQualifiers);
    return LV;
  }

  // We need to compute an access strategy for this bit-field. We are given the
  // offset to the first byte in the bit-field, the sub-byte offset is taken
  // from the original layout. We reuse the normal bit-field access strategy by
  // treating this as an access to a struct where the bit-field is in byte 0,
  // and adjust the containing type size as appropriate.
  //
  // FIXME: Note that currently we make a very conservative estimate of the
  // alignment of the bit-field, because (a) it is not clear what guarantees the
  // runtime makes us, and (b) we don't have a way to specify that the struct is
  // at an alignment plus offset.
  //
  // Note, there is a subtle invariant here: we can only call this routine on
  // non-synthesized ivars but we may be called for synthesized ivars.  However,
  // a synthesized ivar can never be a bit-field, so this is safe.
  const ASTRecordLayout &RL =
    CGF.CGM.getContext().getASTObjCInterfaceLayout(OID);
  uint64_t TypeSizeInBits = CGF.CGM.getContext().toBits(RL.getSize());
  uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar);
  uint64_t BitOffset = FieldBitOffset % CGF.CGM.getContext().getCharWidth();
  uint64_t ContainingTypeAlign = CGF.CGM.getContext().getTargetInfo().getCharAlign();
  uint64_t ContainingTypeSize = TypeSizeInBits - (FieldBitOffset - BitOffset);
  uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext());

  // Allocate a new CGBitFieldInfo object to describe this access.
  //
  // FIXME: This is incredibly wasteful, these should be uniqued or part of some
  // layout object. However, this is blocked on other cleanups to the
  // Objective-C code, so for now we just live with allocating a bunch of these
  // objects.
  CGBitFieldInfo *Info = new (CGF.CGM.getContext()) CGBitFieldInfo(
    CGBitFieldInfo::MakeInfo(CGF.CGM.getTypes(), Ivar, BitOffset, BitFieldSize,
                             ContainingTypeSize, ContainingTypeAlign));

  return LValue::MakeBitfield(V, *Info,
                              IvarTy.withCVRQualifiers(CVRQualifiers));
}

namespace {
  struct CatchHandler {
    const VarDecl *Variable;
    const Stmt *Body;
    llvm::BasicBlock *Block;
    llvm::Value *TypeInfo;
  };

  struct CallObjCEndCatch : EHScopeStack::Cleanup {
    CallObjCEndCatch(bool MightThrow, llvm::Value *Fn) :
      MightThrow(MightThrow), Fn(Fn) {}
    bool MightThrow;
    llvm::Value *Fn;

    void Emit(CodeGenFunction &CGF, Flags flags) {
      if (!MightThrow) {
        CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
        return;
      }

      CGF.EmitCallOrInvoke(Fn);
    }
  };
}

void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF,
                                     const ObjCAtTryStmt &S,
                                     llvm::Constant *beginCatchFn,
                                     llvm::Constant *endCatchFn,
                                     llvm::Constant *exceptionRethrowFn) {
  // Jump destination for falling out of catch bodies.
  CodeGenFunction::JumpDest Cont;
  if (S.getNumCatchStmts())
    Cont = CGF.getJumpDestInCurrentScope("eh.cont");

  CodeGenFunction::FinallyInfo FinallyInfo;
  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
    FinallyInfo.enter(CGF, Finally->getFinallyBody(),
                      beginCatchFn, endCatchFn, exceptionRethrowFn);

  SmallVector<CatchHandler, 8> Handlers;

  // Enter the catch, if there is one.
  if (S.getNumCatchStmts()) {
    for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
      const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
      const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();

      Handlers.push_back(CatchHandler());
      CatchHandler &Handler = Handlers.back();
      Handler.Variable = CatchDecl;
      Handler.Body = CatchStmt->getCatchBody();
      Handler.Block = CGF.createBasicBlock("catch");

      // @catch(...) always matches.
      if (!CatchDecl) {
        Handler.TypeInfo = 0; // catch-all
        // Don't consider any other catches.
        break;
      }

      Handler.TypeInfo = GetEHType(CatchDecl->getType());
    }

    EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
    for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
  }

  // Emit the try body.
  CGF.EmitStmt(S.getTryBody());

  // Leave the try.
  if (S.getNumCatchStmts())
    CGF.popCatchScope();

  // Remember where we were.
  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();

  // Emit the handlers.
  for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
    CatchHandler &Handler = Handlers[I];

    CGF.EmitBlock(Handler.Block);
    llvm::Value *RawExn = CGF.getExceptionFromSlot();

    // Enter the catch.
    llvm::Value *Exn = RawExn;
    if (beginCatchFn) {
      Exn = CGF.Builder.CreateCall(beginCatchFn, RawExn, "exn.adjusted");
      cast<llvm::CallInst>(Exn)->setDoesNotThrow();
    }

    CodeGenFunction::LexicalScope cleanups(CGF, Handler.Body->getSourceRange());

    if (endCatchFn) {
      // Add a cleanup to leave the catch.
      bool EndCatchMightThrow = (Handler.Variable == 0);

      CGF.EHStack.pushCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
                                                EndCatchMightThrow,
                                                endCatchFn);
    }

    // Bind the catch parameter if it exists.
    if (const VarDecl *CatchParam = Handler.Variable) {
      llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
      llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);

      CGF.EmitAutoVarDecl(*CatchParam);

      llvm::Value *CatchParamAddr = CGF.GetAddrOfLocalVar(CatchParam);

      switch (CatchParam->getType().getQualifiers().getObjCLifetime()) {
      case Qualifiers::OCL_Strong:
        CastExn = CGF.EmitARCRetainNonBlock(CastExn);
        // fallthrough

      case Qualifiers::OCL_None:
      case Qualifiers::OCL_ExplicitNone:
      case Qualifiers::OCL_Autoreleasing:
        CGF.Builder.CreateStore(CastExn, CatchParamAddr);
        break;

      case Qualifiers::OCL_Weak:
        CGF.EmitARCInitWeak(CatchParamAddr, CastExn);
        break;
      }
    }

    CGF.ObjCEHValueStack.push_back(Exn);
    CGF.EmitStmt(Handler.Body);
    CGF.ObjCEHValueStack.pop_back();

    // Leave any cleanups associated with the catch.
    cleanups.ForceCleanup();

    CGF.EmitBranchThroughCleanup(Cont);
  }

  // Go back to the try-statement fallthrough.
  CGF.Builder.restoreIP(SavedIP);

  // Pop out of the finally.
  if (S.getFinallyStmt())
    FinallyInfo.exit(CGF);

  if (Cont.isValid())
    CGF.EmitBlock(Cont.getBlock());
}

namespace {
  struct CallSyncExit : EHScopeStack::Cleanup {
    llvm::Value *SyncExitFn;
    llvm::Value *SyncArg;
    CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
      : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}

    void Emit(CodeGenFunction &CGF, Flags flags) {
      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
    }
  };
}

void CGObjCRuntime::EmitAtSynchronizedStmt(CodeGenFunction &CGF,
                                           const ObjCAtSynchronizedStmt &S,
                                           llvm::Function *syncEnterFn,
                                           llvm::Function *syncExitFn) {
  CodeGenFunction::RunCleanupsScope cleanups(CGF);

  // Evaluate the lock operand.  This is guaranteed to dominate the
  // ARC release and lock-release cleanups.
  const Expr *lockExpr = S.getSynchExpr();
  llvm::Value *lock;
  if (CGF.getLangOpts().ObjCAutoRefCount) {
    lock = CGF.EmitARCRetainScalarExpr(lockExpr);
    lock = CGF.EmitObjCConsumeObject(lockExpr->getType(), lock);
  } else {
    lock = CGF.EmitScalarExpr(lockExpr);
  }
  lock = CGF.Builder.CreateBitCast(lock, CGF.VoidPtrTy);

  // Acquire the lock.
  CGF.Builder.CreateCall(syncEnterFn, lock)->setDoesNotThrow();

  // Register an all-paths cleanup to release the lock.
  CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup, syncExitFn, lock);

  // Emit the body of the statement.
  CGF.EmitStmt(S.getSynchBody());
}

/// Compute the pointer-to-function type to which a message send
/// should be casted in order to correctly call the given method
/// with the given arguments.
///
/// \param method - may be null
/// \param resultType - the result type to use if there's no method
/// \param callArgs - the actual arguments, including implicit ones
CGObjCRuntime::MessageSendInfo
CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method,
                                  QualType resultType,
                                  CallArgList &callArgs) {
  // If there's a method, use information from that.
  if (method) {
    const CGFunctionInfo &signature =
      CGM.getTypes().arrangeObjCMessageSendSignature(method, callArgs[0].Ty);

    llvm::PointerType *signatureType =
      CGM.getTypes().GetFunctionType(signature)->getPointerTo();

    // If that's not variadic, there's no need to recompute the ABI
    // arrangement.
    if (!signature.isVariadic())
      return MessageSendInfo(signature, signatureType);

    // Otherwise, there is.
    FunctionType::ExtInfo einfo = signature.getExtInfo();
    const CGFunctionInfo &argsInfo =
      CGM.getTypes().arrangeFunctionCall(resultType, callArgs, einfo,
                                         signature.getRequiredArgs());

    return MessageSendInfo(argsInfo, signatureType);
  }

  // There's no method;  just use a default CC.
  const CGFunctionInfo &argsInfo =
    CGM.getTypes().arrangeFunctionCall(resultType, callArgs,
                                       FunctionType::ExtInfo(),
                                       RequiredArgs::All);

  // Derive the signature to call from that.
  llvm::PointerType *signatureType =
    CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo();
  return MessageSendInfo(argsInfo, signatureType);
}
<|endoftext|>


<commit_before>
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 vmolsa <ville.molsa@gmail.com> (http://github.com/vmolsa)
*
* 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 "Platform.h"
#include <webrtc/base/ssladapter.h>
#include <webrtc/base/macsocketserver.h>
#include <webrtc/base/maccocoasocketserver.h>

using namespace WebRTC;

class PlatformWorker : public rtc::Thread {
  public:
    explicit PlatformWorker(rtc::SocketServer* ss = nullptr);
    virtual void Run();
};

PlatformWorker::PlatformWorker(rtc::SocketServer* ss) : rtc::Thread(ss) { }

void PlatformWorker::Run() {
  LOG(LS_INFO) << __PRETTY_FUNCTION__;
  bool running = false;

  do {
    running = rtc::Thread::ProcessMessages(1);
  } while(running);
}

rtc::MacCFSocketServer ss;
PlatformWorker *worker;

void Platform::Init() {
  LOG(LS_INFO) << __PRETTY_FUNCTION__;
  worker = new PlatformWorker(&ss);

  worker->Start();

  rtc::InitializeSSL();
  rtc::ThreadManager::Instance()->SetCurrentThread(worker);

  if (rtc::ThreadManager::Instance()->CurrentThread() != worker) {
    LOG(LS_ERROR) << "Internal Thread Error!";
    abort();
  }
}

void Platform::Dispose() {
  LOG(LS_INFO) << __PRETTY_FUNCTION__;

  worker->Stop();

  if (rtc::ThreadManager::Instance()->CurrentThread() == worker) {
    rtc::ThreadManager::Instance()->SetCurrentThread(NULL);
  }

  rtc::CleanupSSL();

  delete worker;
}<commit_msg>Update OSX Platform<commit_after>
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 vmolsa <ville.molsa@gmail.com> (http://github.com/vmolsa)
*
* 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 "Platform.h"
#include <webrtc/base/ssladapter.h>
#include <webrtc/base/macsocketserver.h>
#include <webrtc/base/maccocoasocketserver.h>

using namespace WebRTC;

class PlatformWorker : public rtc::Thread {
  public:
    explicit PlatformWorker(rtc::SocketServer* ss = nullptr);
    virtual void Run();
};

PlatformWorker::PlatformWorker(rtc::SocketServer* ss) : rtc::Thread(ss) {
  SetAllowBlockingCalls(true);
}

void PlatformWorker::Run() {
  LOG(LS_INFO) << __PRETTY_FUNCTION__;
  bool running = false;

  do {
    running = rtc::Thread::ProcessMessages(1);
  } while(running);
}

rtc::MacCFSocketServer ss;
PlatformWorker *worker;

void Platform::Init() {
  LOG(LS_INFO) << __PRETTY_FUNCTION__;
  worker = new PlatformWorker(&ss);

  worker->Start();

  rtc::InitializeSSL();
  rtc::ThreadManager::Instance()->SetCurrentThread(worker);

  if (rtc::ThreadManager::Instance()->CurrentThread() != worker) {
    LOG(LS_ERROR) << "Internal Thread Error!";
    abort();
  }
}

void Platform::Dispose() {
  LOG(LS_INFO) << __PRETTY_FUNCTION__;

  worker->Stop();

  if (rtc::ThreadManager::Instance()->CurrentThread() == worker) {
    rtc::ThreadManager::Instance()->SetCurrentThread(NULL);
  }

  rtc::CleanupSSL();

  delete worker;
}<|endoftext|>


<commit_before>/** \file    util.cc
 *  \brief   Implementation of various utility functions.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2015,2017,2018 Library of the University of Tübingen

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

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

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "util.h"
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <cctype>
#include <cstdlib>
#include <execinfo.h>
#include <signal.h>
#include "Compiler.h"
#include "FileLocker.h"
#include "MiscUtil.h"
#include "TimeUtil.h"

// Macro to determine the number of entries in a one-dimensional array:
#define DIM(array) (sizeof(array) / sizeof(array[0]))

char *progname; // Must be set in main() with "progname = argv[0];";

Logger::Logger(): fd_(STDERR_FILENO), log_process_pids_(false), log_no_decorations_(false), min_log_level_(LL_INFO) {
    const char * const min_log_level(::getenv("MIN_LOG_LEVEL"));
    if (min_log_level != nullptr)
        min_log_level_ = Logger::StringToLogLevel(min_log_level);
    const char * const logger_format(::getenv("LOGGER_FORMAT"));
    if (logger_format != nullptr) {
        if (std::strstr(logger_format, "process_pids") != 0)
            log_process_pids_ = true;
        else if (std::strstr(logger_format, "no_decorations") != 0)
            log_no_decorations_ = true;
    }
}

void Logger::error(const std::string &msg) {
    std::lock_guard<std::mutex> mutex_locker(mutex_);

    writeString("SEVERE", msg);
    if (::getenv("BACKTRACE") != nullptr) {
        const bool saved_log_no_decorations(log_no_decorations_);
        log_no_decorations_ = true;
        writeString("", "Backtrace:");
        for (const auto &stack_entry : MiscUtil::GetCallStack())
            writeString("", "  " + stack_entry);
        log_no_decorations_ = saved_log_no_decorations;
    }

    std::exit(EXIT_FAILURE);
}

void Logger::warning(const std::string &msg) {
    if (min_log_level_ < LL_WARNING)
        return;

    std::lock_guard<std::mutex> mutex_locker(mutex_);
    writeString("WARN", msg);
}

void Logger::info(const std::string &msg) {
    if (min_log_level_ < LL_INFO)
        return;

    std::lock_guard<std::mutex> mutex_locker(mutex_);
    writeString("INFO", msg);
}

void Logger::debug(const std::string &msg) {
    if ((min_log_level_ < LL_DEBUG) and (MiscUtil::SafeGetEnv("UTIL_LOG_DEBUG") != "true"))
        return;

    std::lock_guard<std::mutex> mutex_locker(mutex_);
    writeString("DEBUG", msg);
}

inline Logger *LoggerInstantiator() {
    return new Logger();
}

Logger *logger(LoggerInstantiator());

Logger::LogLevel Logger::StringToLogLevel(const std::string &level_candidate) {
    if (level_candidate == "ERROR")
        return Logger::LL_ERROR;
    if (level_candidate == "WARNING")
        return Logger::LL_WARNING;
    if (level_candidate == "INFO")
        return Logger::LL_INFO;
    if (level_candidate == "DEBUG")
        return Logger::LL_DEBUG;
    LOG_ERROR("not a valid minimum log level: \"" + level_candidate + "\"! (Use ERROR, WARNING, INFO or DEBUG)");
}

std::string Logger::LogLevelToString(const LogLevel log_level) {
    if (log_level == Logger::LL_ERROR)
        return "ERROR";
    if (log_level == Logger::LL_WARNING)
        return "WARNING";
    if (log_level == Logger::LL_INFO)
        return "INFO";
    if (log_level == Logger::LL_DEBUG)
        return "DEBUG";
    LOG_ERROR("unsupported log level, we should *never* get here!");
}

void Logger::writeString(const std::string &level, std::string msg) {
    if (unlikely(::progname == nullptr))
        msg = "You must set \"progname\" in main() with \"::progname = argv[0];\" in oder to use the Logger API!";
    else if (not log_no_decorations_) {
        msg = TimeUtil::GetCurrentDateAndTime(TimeUtil::ISO_8601_FORMAT) + " " + level + " " + std::string(::progname) + ": "
              + msg;
        if (log_process_pids_)
            msg += " (PID: " + std::to_string(::getpid()) + ")";
        msg += '\n';
    }

    FileLocker write_locker(fd_, FileLocker::WRITE_ONLY);
    if (unlikely(::write(fd_, reinterpret_cast<const void *>(msg.data()), msg.size()) == -1)) {
        const std::string error_message("in Logger::writeString(util.cc): write to file descriptor " + std::to_string(fd_)
                                        + " failed! (errno = " + std::to_string(errno) + ")");
        #pragma GCC diagnostic ignored "-Wunused-result"
        ::write(STDERR_FILENO, error_message.data(), error_message.size());
        #pragma GCC diagnostic warning "-Wunused-result"
        _exit(EXIT_FAILURE);
    }

    if (unlikely(::progname == nullptr))
        _exit(EXIT_FAILURE);
}

DSVReader::DSVReader(const std::string &filename, const char field_separator, const char field_delimiter)
    : field_separator_(field_separator), field_delimiter_(field_delimiter), line_no_(0), filename_(filename)
{
    input_ = std::fopen(filename.c_str(), "rm");
    if (input_ == nullptr)
        throw std::runtime_error("in DSVReader::DSVReader: can't open \"" + filename + "\" for reading!");
}

DSVReader::~DSVReader() {
    if (input_ != nullptr)
        std::fclose(input_);
}

namespace {

void SkipFieldPadding(FILE * const input) {
    int ch = std::fgetc(input);
    while (isblank(ch))
        ch = std::fgetc(input);
    std::ungetc(ch, input);
}

std::string ReadQuotedValue(FILE * const input, const char field_delimiter) {
    std::string value;
    bool delimiter_seen(false);
    for (;;) {
        const int ch(std::fgetc(input));
        if (ch == EOF)
            throw std::runtime_error("unexpected EOF while reading a quoted DSV value!");
        if (ch == field_delimiter) {
            if (delimiter_seen) {
                value += static_cast<char>(ch);
                delimiter_seen = false;
            } else
                delimiter_seen = true;
        } else if (delimiter_seen) {
            std::ungetc(ch, input);
            return value;
        } else
            value += static_cast<char>(ch);
    }
}

/** \brief Remove trailing spaces and tabs from "s". */
std::string TrimBlanks(std::string * s) {
    std::string::const_reverse_iterator it(s->crbegin());
    for (/* Empty! */; it != s->crend() and std::isblank(*it); ++it)
        /* Intentionally Empty! */;
    if (it != s->crbegin())
        *s = s->substr(0, std::distance(it, s->crend()));

    return *s;
}

std::string ReadNonQuotedValue(FILE * const input, const char field_separator) {
    std::string value;
    for (;;) {
        const int ch(std::fgetc(input));
        if (ch == EOF or ch == '\n' or ch == field_separator) {
            std::ungetc(ch, input);
            return TrimBlanks(&value);
        }
        value += static_cast<char>(ch);
    }
}

void BacktraceSignalHandler(int signal_no) {
    void *stack_return_addresses[20];
    const size_t number_of_addresses(::backtrace(stack_return_addresses, DIM(stack_return_addresses)));
    char err_msg[1024] = "Caught signal ";
    char *cp = err_msg + std::strlen(err_msg);
    if (signal_no > 10)
        *cp++ = '0' + (signal_no / 10);
    *cp++ = '0' + (signal_no % 10);
    *cp++ = '.';
    *cp++ = '\n';
    *cp = '\0';
    ssize_t unused(::write(STDERR_FILENO, err_msg, std::strlen(err_msg)));
    (void)unused;
    ::backtrace_symbols_fd(stack_return_addresses, number_of_addresses, STDERR_FILENO);
    ::_exit(EXIT_FAILURE);
}

int InstallSegvSignalHandler(void handler(int)) {
    ::signal(SIGSEGV, handler);
    return 0;
}

volatile int dummy = InstallSegvSignalHandler(BacktraceSignalHandler);

} // unnamed namespace

bool DSVReader::readLine(std::vector<std::string> * const values) {
    values->clear();
    ++line_no_;

    int ch;
    for (;;) {
        if (not values->empty()) {
            SkipFieldPadding(input_);
            ch = std::fgetc(input_);
            if (ch == EOF)
                return false;
            if (ch == '\n')
                return true;
            if (ch != field_separator_)
                throw std::runtime_error("in DSVReader::readLine: on line " + std::to_string(line_no_)
                                         + ": field separator expected, found '"
                                         + std::string(1, static_cast<char>(ch)) + "' instead!");
        }

        SkipFieldPadding(input_);
        ch = std::fgetc(input_);
        if (ch == '\n')
            return true;
        if (ch == EOF)
            return false;
        if (ch == field_separator_) {
            std::ungetc(ch, input_);
            values->emplace_back("");
        } else if (ch == field_delimiter_)
            values->emplace_back(ReadQuotedValue(input_, field_delimiter_));
        else {
            std::ungetc(ch, input_);
            values->emplace_back(ReadNonQuotedValue(input_, field_separator_));
        }
    }
}
<commit_msg>Missing newlines are not a great idea.<commit_after>/** \file    util.cc
 *  \brief   Implementation of various utility functions.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2015,2017,2018 Library of the University of Tübingen

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

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

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "util.h"
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <cctype>
#include <cstdlib>
#include <execinfo.h>
#include <signal.h>
#include "Compiler.h"
#include "FileLocker.h"
#include "MiscUtil.h"
#include "TimeUtil.h"

// Macro to determine the number of entries in a one-dimensional array:
#define DIM(array) (sizeof(array) / sizeof(array[0]))

char *progname; // Must be set in main() with "progname = argv[0];";

Logger::Logger(): fd_(STDERR_FILENO), log_process_pids_(false), log_no_decorations_(false), min_log_level_(LL_INFO) {
    const char * const min_log_level(::getenv("MIN_LOG_LEVEL"));
    if (min_log_level != nullptr)
        min_log_level_ = Logger::StringToLogLevel(min_log_level);
    const char * const logger_format(::getenv("LOGGER_FORMAT"));
    if (logger_format != nullptr) {
        if (std::strstr(logger_format, "process_pids") != 0)
            log_process_pids_ = true;
        else if (std::strstr(logger_format, "no_decorations") != 0)
            log_no_decorations_ = true;
    }
}

void Logger::error(const std::string &msg) {
    std::lock_guard<std::mutex> mutex_locker(mutex_);

    writeString("SEVERE", msg);
    if (::getenv("BACKTRACE") != nullptr) {
        const bool saved_log_no_decorations(log_no_decorations_);
        log_no_decorations_ = true;
        writeString("", "Backtrace:");
        for (const auto &stack_entry : MiscUtil::GetCallStack())
            writeString("", "  " + stack_entry);
        log_no_decorations_ = saved_log_no_decorations;
    }

    std::exit(EXIT_FAILURE);
}

void Logger::warning(const std::string &msg) {
    if (min_log_level_ < LL_WARNING)
        return;

    std::lock_guard<std::mutex> mutex_locker(mutex_);
    writeString("WARN", msg);
}

void Logger::info(const std::string &msg) {
    if (min_log_level_ < LL_INFO)
        return;

    std::lock_guard<std::mutex> mutex_locker(mutex_);
    writeString("INFO", msg);
}

void Logger::debug(const std::string &msg) {
    if ((min_log_level_ < LL_DEBUG) and (MiscUtil::SafeGetEnv("UTIL_LOG_DEBUG") != "true"))
        return;

    std::lock_guard<std::mutex> mutex_locker(mutex_);
    writeString("DEBUG", msg);
}

inline Logger *LoggerInstantiator() {
    return new Logger();
}

Logger *logger(LoggerInstantiator());

Logger::LogLevel Logger::StringToLogLevel(const std::string &level_candidate) {
    if (level_candidate == "ERROR")
        return Logger::LL_ERROR;
    if (level_candidate == "WARNING")
        return Logger::LL_WARNING;
    if (level_candidate == "INFO")
        return Logger::LL_INFO;
    if (level_candidate == "DEBUG")
        return Logger::LL_DEBUG;
    LOG_ERROR("not a valid minimum log level: \"" + level_candidate + "\"! (Use ERROR, WARNING, INFO or DEBUG)");
}

std::string Logger::LogLevelToString(const LogLevel log_level) {
    if (log_level == Logger::LL_ERROR)
        return "ERROR";
    if (log_level == Logger::LL_WARNING)
        return "WARNING";
    if (log_level == Logger::LL_INFO)
        return "INFO";
    if (log_level == Logger::LL_DEBUG)
        return "DEBUG";
    LOG_ERROR("unsupported log level, we should *never* get here!");
}

void Logger::writeString(const std::string &level, std::string msg) {
    if (unlikely(::progname == nullptr))
        msg = "You must set \"progname\" in main() with \"::progname = argv[0];\" in oder to use the Logger API!";
    else if (not log_no_decorations_) {
        msg = TimeUtil::GetCurrentDateAndTime(TimeUtil::ISO_8601_FORMAT) + " " + level + " " + std::string(::progname) + ": "
              + msg;
        if (log_process_pids_)
            msg += " (PID: " + std::to_string(::getpid()) + ")";
    }
    msg += '\n';

    FileLocker write_locker(fd_, FileLocker::WRITE_ONLY);
    if (unlikely(::write(fd_, reinterpret_cast<const void *>(msg.data()), msg.size()) == -1)) {
        const std::string error_message("in Logger::writeString(util.cc): write to file descriptor " + std::to_string(fd_)
                                        + " failed! (errno = " + std::to_string(errno) + ")");
        #pragma GCC diagnostic ignored "-Wunused-result"
        ::write(STDERR_FILENO, error_message.data(), error_message.size());
        #pragma GCC diagnostic warning "-Wunused-result"
        _exit(EXIT_FAILURE);
    }

    if (unlikely(::progname == nullptr))
        _exit(EXIT_FAILURE);
}

DSVReader::DSVReader(const std::string &filename, const char field_separator, const char field_delimiter)
    : field_separator_(field_separator), field_delimiter_(field_delimiter), line_no_(0), filename_(filename)
{
    input_ = std::fopen(filename.c_str(), "rm");
    if (input_ == nullptr)
        throw std::runtime_error("in DSVReader::DSVReader: can't open \"" + filename + "\" for reading!");
}

DSVReader::~DSVReader() {
    if (input_ != nullptr)
        std::fclose(input_);
}

namespace {

void SkipFieldPadding(FILE * const input) {
    int ch = std::fgetc(input);
    while (isblank(ch))
        ch = std::fgetc(input);
    std::ungetc(ch, input);
}

std::string ReadQuotedValue(FILE * const input, const char field_delimiter) {
    std::string value;
    bool delimiter_seen(false);
    for (;;) {
        const int ch(std::fgetc(input));
        if (ch == EOF)
            throw std::runtime_error("unexpected EOF while reading a quoted DSV value!");
        if (ch == field_delimiter) {
            if (delimiter_seen) {
                value += static_cast<char>(ch);
                delimiter_seen = false;
            } else
                delimiter_seen = true;
        } else if (delimiter_seen) {
            std::ungetc(ch, input);
            return value;
        } else
            value += static_cast<char>(ch);
    }
}

/** \brief Remove trailing spaces and tabs from "s". */
std::string TrimBlanks(std::string * s) {
    std::string::const_reverse_iterator it(s->crbegin());
    for (/* Empty! */; it != s->crend() and std::isblank(*it); ++it)
        /* Intentionally Empty! */;
    if (it != s->crbegin())
        *s = s->substr(0, std::distance(it, s->crend()));

    return *s;
}

std::string ReadNonQuotedValue(FILE * const input, const char field_separator) {
    std::string value;
    for (;;) {
        const int ch(std::fgetc(input));
        if (ch == EOF or ch == '\n' or ch == field_separator) {
            std::ungetc(ch, input);
            return TrimBlanks(&value);
        }
        value += static_cast<char>(ch);
    }
}

void BacktraceSignalHandler(int signal_no) {
    void *stack_return_addresses[20];
    const size_t number_of_addresses(::backtrace(stack_return_addresses, DIM(stack_return_addresses)));
    char err_msg[1024] = "Caught signal ";
    char *cp = err_msg + std::strlen(err_msg);
    if (signal_no > 10)
        *cp++ = '0' + (signal_no / 10);
    *cp++ = '0' + (signal_no % 10);
    *cp++ = '.';
    *cp++ = '\n';
    *cp = '\0';
    ssize_t unused(::write(STDERR_FILENO, err_msg, std::strlen(err_msg)));
    (void)unused;
    ::backtrace_symbols_fd(stack_return_addresses, number_of_addresses, STDERR_FILENO);
    ::_exit(EXIT_FAILURE);
}

int InstallSegvSignalHandler(void handler(int)) {
    ::signal(SIGSEGV, handler);
    return 0;
}

volatile int dummy = InstallSegvSignalHandler(BacktraceSignalHandler);

} // unnamed namespace

bool DSVReader::readLine(std::vector<std::string> * const values) {
    values->clear();
    ++line_no_;

    int ch;
    for (;;) {
        if (not values->empty()) {
            SkipFieldPadding(input_);
            ch = std::fgetc(input_);
            if (ch == EOF)
                return false;
            if (ch == '\n')
                return true;
            if (ch != field_separator_)
                throw std::runtime_error("in DSVReader::readLine: on line " + std::to_string(line_no_)
                                         + ": field separator expected, found '"
                                         + std::string(1, static_cast<char>(ch)) + "' instead!");
        }

        SkipFieldPadding(input_);
        ch = std::fgetc(input_);
        if (ch == '\n')
            return true;
        if (ch == EOF)
            return false;
        if (ch == field_separator_) {
            std::ungetc(ch, input_);
            values->emplace_back("");
        } else if (ch == field_delimiter_)
            values->emplace_back(ReadQuotedValue(input_, field_delimiter_));
        else {
            std::ungetc(ch, input_);
            values->emplace_back(ReadNonQuotedValue(input_, field_separator_));
        }
    }
}
<|endoftext|>


<commit_before>#include "dataraptor.h"
#include "routing.h"
namespace navitia { namespace routing { namespace raptor {

void dataRAPTOR::load(const type::PT_Data &data)
{
    retour_constant.resize(data.stop_points.size());
    retour_constant_reverse.resize(data.stop_points.size());

    for(auto &r : retour_constant_reverse) {
        r.dt = DateTime::min;
    }

    for(auto &r : retour_constant) {
        r.dt = DateTime::inf;
    }
    //Construction de la liste des marche à pied à partir des connections renseignées

    std::vector<list_connections> footpath_temp;
    footpath_temp.resize(data.stop_points.size());
    for(navitia::type::Connection connection : data.connections) {
        footpath_temp[connection.departure_stop_point_idx][connection.destination_stop_point_idx] = connection;
        navitia::type::Connection inverse;
        inverse.departure_stop_point_idx = connection.destination_stop_point_idx;
        inverse.destination_stop_point_idx = connection.departure_stop_point_idx;
        inverse.duration = connection.duration;
        footpath_temp[connection.destination_stop_point_idx][connection.departure_stop_point_idx] = inverse;
    }

    //On rajoute des connexions entre les stops points d'un même stop area si elles n'existent pas
    footpath_index.resize(data.stop_points.size());
    footpath_index.resize(data.stop_points.size());
    for(navitia::type::StopPoint sp : data.stop_points) {
        navitia::type::StopArea sa = data.stop_areas[sp.stop_area_idx];
        footpath_index[sp.idx].first = foot_path.size();

        int size = 0;
        for(auto conn : footpath_temp[sp.idx]) {
            foot_path.push_back(conn.second);
            ++size;
        }

        for(navitia::type::idx_t spidx : sa.stop_point_list) {
            navitia::type::StopPoint sp2 = data.stop_points[spidx];
            if(sp.idx != sp2.idx) {
                if(footpath_temp[sp.idx].find(sp2.idx) == footpath_temp[sp.idx].end()) {
                    navitia::type::Connection c;
                    c.departure_stop_point_idx = sp.idx;
                    c.destination_stop_point_idx = sp2.idx;
                    c.duration = 2 * 60;
                    foot_path.push_back(c);
                    ++size;
                }
            }
        }
        footpath_index[sp.idx].second = size;
    }

    typedef std::unordered_map<navitia::type::idx_t, vector_idx> idx_vector_idx;
    idx_vector_idx ridx_route;
    for(auto & route : data.routes) {
        ridx_route[route.idx] = vector_idx();
        if(route.route_point_list.size() > 0) {
            idx_vector_idx vp_vj;
            //Je regroupe entre elles les routes ayant le même validity pattern
            for(navitia::type::idx_t vjidx : route.vehicle_journey_list) {
                if(vp_vj.find(data.vehicle_journeys[vjidx].validity_pattern_idx) == vp_vj.end())
                    vp_vj[data.vehicle_journeys[vjidx].validity_pattern_idx] = vector_idx();
                vp_vj[data.vehicle_journeys[vjidx].validity_pattern_idx].push_back(vjidx);
            }

            for(idx_vector_idx::value_type vec : vp_vj) {
                if(vec.second.size() > 0) {
                    Route_t r;
                    r.idx = route.idx;
                    r.nbStops = route.route_point_list.size();
                    r.nbTrips = vec.second.size();
                    r.vp = data.validity_patterns[vec.first].idx;
                    r.firstStopTime = stopTimes.size();
                    for(auto vjidx : vec.second) {
                        for(navitia::type::idx_t stidx : data.vehicle_journeys[vjidx].stop_time_list) {
                            StopTime_t st =  data.stop_times[stidx];
                            stopTimes.push_back(st);
                        }
                    }
                    ridx_route[route.idx].push_back(routes.size());
                    routes.push_back(r);
                }
            }
        }
    }

    sp_indexrouteorder.resize(data.stop_points.size());
    sp_indexrouteorder_reverse.resize(data.stop_points.size());
    for(auto &sp : data.stop_points) {
        pair_int temp_index, temp_index_reverse;
        temp_index.first = sp_routeorder_const.size();
        temp_index_reverse.first = sp_routeorder_const_reverse.size();
        std::map<navitia::type::idx_t, int> temp, temp_reverse;
        for(navitia::type::idx_t idx_rp : sp.route_point_list) {
            auto &rp = data.route_points[idx_rp];
            for(auto rid : ridx_route[rp.route_idx]) {
                auto it = temp.find(rid), it_reverse = temp_reverse.find(rid);
                if(it == temp.end()) {
                    temp[rid] = rp.order;
                } else if(temp[rp.route_idx] > rp.order) {
                    temp[rid] = rp.order;
                }

                if(it_reverse == temp_reverse.end()) {
                    temp_reverse[rid] = rp.order;
                } else if(temp_reverse[rp.route_idx] < rp.order) {
                    temp_reverse[rid] = rp.order;
                }
            }

        }

        for(auto it : temp) {
            sp_routeorder_const.push_back(it);
        }

        for(auto it : temp_reverse) {
            sp_routeorder_const_reverse.push_back(it);
        }

        temp_index.second = sp_routeorder_const.size() - temp_index.first;
        temp_index_reverse.second = sp_routeorder_const_reverse.size() - temp_index_reverse.first;
        sp_indexrouteorder[sp.idx] = temp_index;
        sp_indexrouteorder_reverse[sp.idx] = temp_index_reverse;
    }

    std::cout << "Nb data stop times : " << data.stop_times.size() << " stopTimes : " << stopTimes.size()
              << " nb foot path : " << foot_path.size() << " Nombre de stop points : " << data.stop_points.size() << "nb vp : " << data.validity_patterns.size() << " nb routes " << routes.size() <<  std::endl;

}

}}}
<commit_msg>dataraptor : On trie les routes par vp dans sp route order<commit_after>#include "dataraptor.h"
#include "routing.h"
namespace navitia { namespace routing { namespace raptor {

void dataRAPTOR::load(const type::PT_Data &data)
{
    retour_constant.resize(data.stop_points.size());
    retour_constant_reverse.resize(data.stop_points.size());

    for(auto &r : retour_constant_reverse) {
        r.dt = DateTime::min;
    }

    for(auto &r : retour_constant) {
        r.dt = DateTime::inf;
    }
    //Construction de la liste des marche à pied à partir des connections renseignées

    std::vector<list_connections> footpath_temp;
    footpath_temp.resize(data.stop_points.size());
    for(navitia::type::Connection connection : data.connections) {
        footpath_temp[connection.departure_stop_point_idx][connection.destination_stop_point_idx] = connection;
        navitia::type::Connection inverse;
        inverse.departure_stop_point_idx = connection.destination_stop_point_idx;
        inverse.destination_stop_point_idx = connection.departure_stop_point_idx;
        inverse.duration = connection.duration;
        footpath_temp[connection.destination_stop_point_idx][connection.departure_stop_point_idx] = inverse;
    }

    //On rajoute des connexions entre les stops points d'un même stop area si elles n'existent pas
    footpath_index.resize(data.stop_points.size());
    footpath_index.resize(data.stop_points.size());
    for(navitia::type::StopPoint sp : data.stop_points) {
        navitia::type::StopArea sa = data.stop_areas[sp.stop_area_idx];
        footpath_index[sp.idx].first = foot_path.size();

        int size = 0;
        for(auto conn : footpath_temp[sp.idx]) {
            foot_path.push_back(conn.second);
            ++size;
        }

        for(navitia::type::idx_t spidx : sa.stop_point_list) {
            navitia::type::StopPoint sp2 = data.stop_points[spidx];
            if(sp.idx != sp2.idx) {
                if(footpath_temp[sp.idx].find(sp2.idx) == footpath_temp[sp.idx].end()) {
                    navitia::type::Connection c;
                    c.departure_stop_point_idx = sp.idx;
                    c.destination_stop_point_idx = sp2.idx;
                    c.duration = 2 * 60;
                    foot_path.push_back(c);
                    ++size;
                }
            }
        }
        footpath_index[sp.idx].second = size;
    }

    typedef std::unordered_map<navitia::type::idx_t, vector_idx> idx_vector_idx;
    idx_vector_idx ridx_route;
    for(auto & route : data.routes) {
        ridx_route[route.idx] = vector_idx();
        if(route.route_point_list.size() > 0) {
            idx_vector_idx vp_vj;
            //Je regroupe entre elles les routes ayant le même validity pattern
            for(navitia::type::idx_t vjidx : route.vehicle_journey_list) {
                if(vp_vj.find(data.vehicle_journeys[vjidx].validity_pattern_idx) == vp_vj.end())
                    vp_vj[data.vehicle_journeys[vjidx].validity_pattern_idx] = vector_idx();
                vp_vj[data.vehicle_journeys[vjidx].validity_pattern_idx].push_back(vjidx);
            }

            for(idx_vector_idx::value_type vec : vp_vj) {
                if(vec.second.size() > 0) {
                    Route_t r;
                    r.idx = route.idx;
                    r.nbStops = route.route_point_list.size();
                    r.nbTrips = vec.second.size();
                    r.vp = data.validity_patterns[vec.first].idx;
                    r.firstStopTime = stopTimes.size();
                    for(auto vjidx : vec.second) {
                        for(navitia::type::idx_t stidx : data.vehicle_journeys[vjidx].stop_time_list) {
                            StopTime_t st =  data.stop_times[stidx];
                            stopTimes.push_back(st);
                        }
                    }
                    ridx_route[route.idx].push_back(routes.size());
                    routes.push_back(r);
                }
            }
        }
    }

    sp_indexrouteorder.resize(data.stop_points.size());
    sp_indexrouteorder_reverse.resize(data.stop_points.size());
    for(auto &sp : data.stop_points) {
        pair_int temp_index, temp_index_reverse;
        temp_index.first = sp_routeorder_const.size();
        temp_index_reverse.first = sp_routeorder_const_reverse.size();
        std::map<navitia::type::idx_t, int> temp, temp_reverse;
        for(navitia::type::idx_t idx_rp : sp.route_point_list) {
            auto &rp = data.route_points[idx_rp];
            for(auto rid : ridx_route[rp.route_idx]) {
                auto it = temp.find(rid), it_reverse = temp_reverse.find(rid);
                if(it == temp.end()) {
                    temp[rid] = rp.order;
                } else if(temp[rp.route_idx] > rp.order) {
                    temp[rid] = rp.order;
                }

                if(it_reverse == temp_reverse.end()) {
                    temp_reverse[rid] = rp.order;
                } else if(temp_reverse[rp.route_idx] < rp.order) {
                    temp_reverse[rid] = rp.order;
                }
            }

        }

        std::vector<pair_int> tmp;
        for(auto it : temp) {
            tmp.push_back(it);
        }
        std::sort(tmp.begin(), tmp.end(), [&](pair_int p1, pair_int p2){return routes[p1.first].vp < routes[p2.first].vp;});
        sp_routeorder_const.insert(sp_routeorder_const.end(), tmp.begin(), tmp.end());

        tmp.clear();

        for(auto it : temp_reverse) {
            tmp.push_back(it);
        }
        std::sort(tmp.begin(), tmp.end(), [&](pair_int p1, pair_int p2){return routes[p1.first].vp < routes[p2.first].vp;});
        sp_routeorder_const_reverse.insert(sp_routeorder_const_reverse.end(), tmp.begin(), tmp.end());

        temp_index.second = sp_routeorder_const.size() - temp_index.first;
        temp_index_reverse.second = sp_routeorder_const_reverse.size() - temp_index_reverse.first;
        sp_indexrouteorder[sp.idx] = temp_index;
        sp_indexrouteorder_reverse[sp.idx] = temp_index_reverse;
    }

    std::cout << "Nb data stop times : " << data.stop_times.size() << " stopTimes : " << stopTimes.size()
              << " nb foot path : " << foot_path.size() << " Nombre de stop points : " << data.stop_points.size() << "nb vp : " << data.validity_patterns.size() << " nb routes " << routes.size() <<  std::endl;

}

}}}
<|endoftext|>