<commit_before>/***********************************************************************
 *    filename:   Element.cpp
 *    created:    28/10/2011
 *    author:     Martin Preisler
 *************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2011 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUI/Element.h"

#include <boost/test/unit_test.hpp>
#include <boost/timer.hpp>

BOOST_AUTO_TEST_SUITE(Element)

BOOST_AUTO_TEST_CASE(RelativeSizing)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(50.0f * CEGUI::UDim::percent(), 25.0f * CEGUI::UDim::percent()));
    root->addChild(child);

    BOOST_CHECK_EQUAL(root->getPixelSize(), CEGUI::Sizef(100.0f, 100.0f));
    BOOST_CHECK_EQUAL(child->getPixelSize(), CEGUI::Sizef(50.0f, 25.0f));

    CEGUI::Element* innerChild = new CEGUI::Element();
    child->addChild(innerChild);
    innerChild->setSize(CEGUI::USize(200.0f * CEGUI::UDim::percent(), 100.0f * CEGUI::UDim::percent()));
    BOOST_CHECK_EQUAL(innerChild->getPixelSize(), CEGUI::Sizef(100.0f, 25.0f));

    delete innerChild;
    delete child;
    delete root;
}

BOOST_AUTO_TEST_CASE(RelativePositioning)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setPosition(CEGUI::UVector2(50.0f * CEGUI::UDim::percent(), 50.0f * CEGUI::UDim::percent()));
    child->setSize(CEGUI::USize(10.0f * CEGUI::UDim::px(), 10 * CEGUI::UDim::px()));
    root->addChild(child);

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(50.0f, 50.0f, 60.0f, 60.0f));

    delete child;
    delete root;
}

// TODO: RelativeRotation!

BOOST_AUTO_TEST_CASE(HorizontalLeftAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(50.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getHorizontalAlignment(), CEGUI::HA_LEFT);
    BOOST_CHECK_EQUAL(child->getHorizontalAlignment(), CEGUI::HA_LEFT);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 100, 0));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 50, 0));

    child->setPosition(CEGUI::UVector2(10.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(10, 0, 60, 0));
}

BOOST_AUTO_TEST_CASE(HorizontalCentreAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(50.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getHorizontalAlignment(), CEGUI::HA_LEFT);
    child->setHorizontalAlignment(CEGUI::HA_CENTRE);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 100, 0));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(25, 0, 75, 0));

    child->setPosition(CEGUI::UVector2(10.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(35, 0, 85, 0));
}

BOOST_AUTO_TEST_CASE(HorizontalRightAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(50.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getHorizontalAlignment(), CEGUI::HA_LEFT);
    child->setHorizontalAlignment(CEGUI::HA_RIGHT);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 100, 0));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(50, 0, 100, 0));

    child->setPosition(CEGUI::UVector2(-10.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(40, 0, 90, 0));
}

BOOST_AUTO_TEST_CASE(VerticalTopAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 50.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getVerticalAlignment(), CEGUI::VA_TOP);
    BOOST_CHECK_EQUAL(child->getVerticalAlignment(), CEGUI::VA_TOP);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 0, 100));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 0, 50));

    child->setPosition(CEGUI::UVector2(0.0f * CEGUI::UDim::px(), 5.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 5, 0, 55));
}

BOOST_AUTO_TEST_CASE(VerticalCentreAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 50.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getVerticalAlignment(), CEGUI::VA_TOP);
    child->setVerticalAlignment(CEGUI::VA_CENTRE);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 0, 100));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 25, 0, 75));

    child->setPosition(CEGUI::UVector2(0.0f * CEGUI::UDim::px(), 5.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 30, 0, 80));
}

BOOST_AUTO_TEST_CASE(VerticalBottomAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 50.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getVerticalAlignment(), CEGUI::VA_TOP);
    child->setVerticalAlignment(CEGUI::VA_BOTTOM);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 0, 100));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 50, 0, 100));

    child->setPosition(CEGUI::UVector2(0.0f * CEGUI::UDim::px(), -5.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 45, 0, 95));
}

BOOST_AUTO_TEST_CASE(AspectLocking)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getAspectMode(), CEGUI::AM_IGNORE);
    BOOST_CHECK_EQUAL(root->getPixelSize(), CEGUI::Sizef(100, 100));

    root->setAspectMode(CEGUI::AM_SHRINK);
    root->setAspectRatio(1.0f / 2.0f);

    // todo: should have tolerances or something, or does boost do that automatically?
    BOOST_CHECK_EQUAL(root->getPixelSize(), CEGUI::Sizef(50, 100));

    root->setAspectMode(CEGUI::AM_EXPAND);
    root->setAspectRatio(1.0f / 2.0f);

    // todo: should have tolerances or something, or does boost do that automatically?
    BOOST_CHECK_EQUAL(root->getPixelSize(), CEGUI::Sizef(100, 200));
}

BOOST_AUTO_TEST_CASE(PixelAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setPosition(CEGUI::UVector2(0.2f * CEGUI::UDim::px(), 0.2f * CEGUI::UDim::px()));
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 100.0f * CEGUI::UDim::px()));

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK(root->isPixelAligned());

    // todo: should have tolerances or something, or does boost do that automatically?
    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 100, 100));

    root->setPixelAligned(false);

    // todo: should have tolerances or something, or does boost do that automatically?
    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0.2f, 0.2f, 100.2f, 100.2f));
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Cleanup after the test cases in Element<commit_after>/***********************************************************************
 *    filename:   Element.cpp
 *    created:    28/10/2011
 *    author:     Martin Preisler
 *************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2011 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUI/Element.h"

#include <boost/test/unit_test.hpp>
#include <boost/timer.hpp>

BOOST_AUTO_TEST_SUITE(Element)

BOOST_AUTO_TEST_CASE(RelativeSizing)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(50.0f * CEGUI::UDim::percent(), 25.0f * CEGUI::UDim::percent()));
    root->addChild(child);

    BOOST_CHECK_EQUAL(root->getPixelSize(), CEGUI::Sizef(100.0f, 100.0f));
    BOOST_CHECK_EQUAL(child->getPixelSize(), CEGUI::Sizef(50.0f, 25.0f));

    CEGUI::Element* innerChild = new CEGUI::Element();
    child->addChild(innerChild);
    innerChild->setSize(CEGUI::USize(200.0f * CEGUI::UDim::percent(), 100.0f * CEGUI::UDim::percent()));
    BOOST_CHECK_EQUAL(innerChild->getPixelSize(), CEGUI::Sizef(100.0f, 25.0f));

    delete innerChild;
    delete child;
    delete root;
}

BOOST_AUTO_TEST_CASE(RelativePositioning)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setPosition(CEGUI::UVector2(50.0f * CEGUI::UDim::percent(), 50.0f * CEGUI::UDim::percent()));
    child->setSize(CEGUI::USize(10.0f * CEGUI::UDim::px(), 10 * CEGUI::UDim::px()));
    root->addChild(child);

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(50.0f, 50.0f, 60.0f, 60.0f));

    delete child;
    delete root;
}

// TODO: RelativeRotation!

BOOST_AUTO_TEST_CASE(HorizontalLeftAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(50.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getHorizontalAlignment(), CEGUI::HA_LEFT);
    BOOST_CHECK_EQUAL(child->getHorizontalAlignment(), CEGUI::HA_LEFT);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 100, 0));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 50, 0));

    child->setPosition(CEGUI::UVector2(10.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(10, 0, 60, 0));

    delete child;
    delete root;
}

BOOST_AUTO_TEST_CASE(HorizontalCentreAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(50.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getHorizontalAlignment(), CEGUI::HA_LEFT);
    child->setHorizontalAlignment(CEGUI::HA_CENTRE);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 100, 0));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(25, 0, 75, 0));

    child->setPosition(CEGUI::UVector2(10.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(35, 0, 85, 0));

    delete child;
    delete root;
}

BOOST_AUTO_TEST_CASE(HorizontalRightAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(50.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getHorizontalAlignment(), CEGUI::HA_LEFT);
    child->setHorizontalAlignment(CEGUI::HA_RIGHT);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 100, 0));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(50, 0, 100, 0));

    child->setPosition(CEGUI::UVector2(-10.0f * CEGUI::UDim::px(), 0.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(40, 0, 90, 0));

    delete child;
    delete root;
}

BOOST_AUTO_TEST_CASE(VerticalTopAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 50.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getVerticalAlignment(), CEGUI::VA_TOP);
    BOOST_CHECK_EQUAL(child->getVerticalAlignment(), CEGUI::VA_TOP);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 0, 100));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 0, 50));

    child->setPosition(CEGUI::UVector2(0.0f * CEGUI::UDim::px(), 5.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 5, 0, 55));

    delete child;
    delete root;
}

BOOST_AUTO_TEST_CASE(VerticalCentreAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 50.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getVerticalAlignment(), CEGUI::VA_TOP);
    child->setVerticalAlignment(CEGUI::VA_CENTRE);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 0, 100));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 25, 0, 75));

    child->setPosition(CEGUI::UVector2(0.0f * CEGUI::UDim::px(), 5.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 30, 0, 80));

    delete child;
    delete root;
}

BOOST_AUTO_TEST_CASE(VerticalBottomAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));
    CEGUI::Element* child = new CEGUI::Element();
    child->setSize(CEGUI::USize(0.0f * CEGUI::UDim::px(), 50.0f * CEGUI::UDim::px()));
    root->addChild(child);

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getVerticalAlignment(), CEGUI::VA_TOP);
    child->setVerticalAlignment(CEGUI::VA_BOTTOM);

    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 0, 100));
    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 50, 0, 100));

    child->setPosition(CEGUI::UVector2(0.0f * CEGUI::UDim::px(), -5.0f * CEGUI::UDim::px()));

    BOOST_CHECK_EQUAL(child->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 45, 0, 95));

    delete child;
    delete root;
}

BOOST_AUTO_TEST_CASE(AspectLocking)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 100 * CEGUI::UDim::px()));

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK_EQUAL(root->getAspectMode(), CEGUI::AM_IGNORE);
    BOOST_CHECK_EQUAL(root->getPixelSize(), CEGUI::Sizef(100, 100));

    root->setAspectMode(CEGUI::AM_SHRINK);
    root->setAspectRatio(1.0f / 2.0f);

    // todo: should have tolerances or something, or does boost do that automatically?
    BOOST_CHECK_EQUAL(root->getPixelSize(), CEGUI::Sizef(50, 100));

    root->setAspectMode(CEGUI::AM_EXPAND);
    root->setAspectRatio(1.0f / 2.0f);

    // todo: should have tolerances or something, or does boost do that automatically?
    BOOST_CHECK_EQUAL(root->getPixelSize(), CEGUI::Sizef(100, 200));

    delete root;
}

BOOST_AUTO_TEST_CASE(PixelAlignment)
{
    CEGUI::Element* root = new CEGUI::Element();
    root->setPosition(CEGUI::UVector2(0.2f * CEGUI::UDim::px(), 0.2f * CEGUI::UDim::px()));
    root->setSize(CEGUI::USize(100.0f * CEGUI::UDim::px(), 100.0f * CEGUI::UDim::px()));

    // even though it is the default at the point of writing the test, we have to make sure this fact doesn't change!
    BOOST_CHECK(root->isPixelAligned());

    // todo: should have tolerances or something, or does boost do that automatically?
    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0, 0, 100, 100));

    root->setPixelAligned(false);

    // todo: should have tolerances or something, or does boost do that automatically?
    BOOST_CHECK_EQUAL(root->getUnclippedOuterRect().get(), CEGUI::Rectf(0.2f, 0.2f, 100.2f, 100.2f));

    delete root;
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

extern "C" {
#define LUA_OK		0
#define LUA_YIELD	1
#define LUA_ERRRUN	2
#define LUA_ERRSYNTAX	3
#define LUA_ERRMEM	4
#define LUA_ERRERR	5
static const char* THREAD_STATUS_STR[] = {"done", "yield", "errrun", "errsyntax", "errmem", "errerr"};

#define LUA_GLOBALSINDEX	(-10002)
struct lua_State;
#define LUA_IDSIZE	60	/* Size of lua_Debug.short_src. */
struct lua_Debug {
  int event;
  const char *name;	/* (n) */
  const char *namewhat;	/* (n) `global', `local', `field', `method' */
  const char *what;	/* (S) `Lua', `C', `main', `tail' */
  const char *source;	/* (S) */
  int currentline;	/* (l) */
  int nups;		/* (u) number of upvalues */
  int linedefined;	/* (S) */
  int lastlinedefined;	/* (S) */
  char short_src[LUA_IDSIZE]; /* (S) */
  /* private part */
  int i_ci;  /* active function */
};
typedef int (*lua_resume_t)(lua_State *L, int narg);
typedef int (*lua_getstack_t) (lua_State *L, int level, lua_Debug *ar);
typedef int (*lua_getinfo_t) (lua_State *L, const char *what, lua_Debug *ar);
typedef int (*lua_gettop_t) (lua_State *L);
typedef int (*lua_type_t) (lua_State *L, int index);
typedef void (*lua_call_t) (lua_State *L, int nargs, int nresults);
typedef const char * (*lua_tostring_t) (lua_State *L, int index, size_t* len);
typedef void  (*lua_pushvalue_t) (lua_State *L, int index);
typedef void (*lua_settop_t)(lua_State *L, int idx);
typedef void (*lua_getfield_t) (lua_State *L, int index, const char *k);

static lua_resume_t lua_resume_f = NULL;
static lua_getstack_t lua_getstack_f = NULL;
static lua_getinfo_t lua_getinfo_f = NULL;
static lua_gettop_t lua_gettop_f = NULL;
static lua_type_t lua_type_f = NULL;
static lua_call_t lua_call_f = NULL;
static lua_tostring_t lua_tostring_f = NULL;
static lua_pushvalue_t lua_pushvalue_f = NULL;
static lua_settop_t lua_settop_f = NULL;
static lua_getfield_t lua_getfield_f = NULL;

static const char* getFuncInfo(lua_State* L) {
	const static size_t buflen = 512;
	static char buf[buflen];

	if (lua_gettop_f(L) > 0) {
		if (lua_type_f(L, 1) == 6) {
			lua_pushvalue_f(L, 1);
			lua_Debug info;
			lua_getinfo_f(L, ">nSl", &info);
			snprintf(buf, buflen, "%s,%s,%d",
				info.name, info.source, info.currentline ?: info.linedefined);
			return buf;
		}
	}

	lua_Debug info;
	lua_getstack_f(L, 1, &info);
	lua_getinfo_f(L, "nSl", &info);
	snprintf(buf, buflen, "%s,%s,%d",
			info.name, info.short_src, info.currentline ?: info.linedefined);
	return buf;
}

static void initfunc() {
	if (!lua_resume_f) {
		lua_resume_f = (lua_resume_t)dlsym(RTLD_NEXT, "lua_resume");
		lua_getstack_f = (lua_getstack_t)dlsym(RTLD_NEXT, "lua_getstack");
		lua_getinfo_f = (lua_getinfo_t)dlsym(RTLD_NEXT, "lua_getinfo");
		lua_gettop_f = (lua_gettop_t)dlsym(RTLD_NEXT, "lua_gettop");
		lua_type_f = (lua_type_t)dlsym(RTLD_NEXT, "lua_type");
		lua_call_f = (lua_call_t)dlsym(RTLD_NEXT, "lua_call");
		lua_tostring_f = (lua_tostring_t)dlsym(RTLD_NEXT, "lua_tolstring");
		lua_pushvalue_f = (lua_pushvalue_t)dlsym(RTLD_NEXT, "lua_pushvalue");
		lua_settop_f = (lua_settop_t)dlsym(RTLD_NEXT, "lua_settop");
		lua_getfield_f = (lua_getfield_t)dlsym(RTLD_NEXT, "lua_getfield");
	}
}

int lua_resume(lua_State *L, int narg) {
	initfunc();

	static bool enabled = true;

	if (!enabled) {
		return lua_resume_f(L, narg);
	}

	// skip init phase, keep static variables untouched in master process
	{
		char buf[32];
		lua_getfield_f(L, LUA_GLOBALSINDEX, "ngx");
		lua_getfield_f(L, -1, "get_phase");
		lua_call_f(L, 0, 1);
		size_t len;
		const char* str = lua_tostring_f(L, -1, &len);
		len = (len > 31) ? 31 : len;
		strncpy(buf, str, len);
		buf[len] = 0;
		lua_settop_f(L, -(2)-1);
		if (strcmp(buf, "init") == 0) {
			return lua_resume_f(L, narg);
		}
	}

	// read configs from nginx.conf once
	static bool initCfg = false;
	static int NGX_LUA_BLOCK_CHECK_MIN_MS = 10;
	static FILE* fp = NULL;
	static char* fpath = NULL;
	if (!initCfg) {
		char* tmp = getenv("NGX_LUA_BLOCK_CHECK");
		enabled = (tmp && strcmp(tmp, "true") == 0);
		if (!enabled) {
			return lua_resume_f(L, narg);
		}

		char* threshold = getenv("NGX_LUA_BLOCK_CHECK_MIN_MS");
		if (threshold) {
			NGX_LUA_BLOCK_CHECK_MIN_MS = atoi(threshold);
		}

		fpath = getenv("NGX_LUA_BLOCK_CHECK_OUTPUT_FILE");

		initCfg = true;
	}

	// avoid reentrent, we just care about the top level invocation
	static bool invoking = false;
	if (invoking) {
		return lua_resume_f(L, narg);
	} else {
		invoking = true;
	}

	timeval tv1;
	gettimeofday(&tv1, NULL);

	const char* funcInfo1 = getFuncInfo(L);

	int ret = lua_resume_f(L, narg);

	timeval tv2;
	gettimeofday(&tv2, NULL);

	if (tv2.tv_usec < tv1.tv_usec) {
		tv2.tv_sec--;
		tv2.tv_usec += 1000000;
	}
	unsigned long delta = (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec) / 1000;

	if (delta >= NGX_LUA_BLOCK_CHECK_MIN_MS) {
		tm now;
		localtime_r(&tv1.tv_sec, &now);
		char tmbuf[64];
		strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", &now);

		const static size_t urllen = 128;
		char url[urllen];
		lua_getfield_f(L, LUA_GLOBALSINDEX, "ngx");
		lua_getfield_f(L, -1, "var");
		lua_getfield_f(L, -1, "request_uri");
		size_t len;
		const char* str = lua_tostring_f(L, -1, &len);
		len = (len > urllen - 1) ? (urllen - 1) : len;
		strncpy(url, str, len);
		url[len] = 0;
		lua_settop_f(L, -(3)-1);

		if (!fp && fpath) {
			char tmp[64];
			pid_t pid = getpid();
			sprintf(tmp, "%s.%d", fpath, pid);
			fp = fopen(tmp, "w");
		}

		FILE* tfp = fp ?: stdout;
		char ts[64];
		sprintf(ts, "%s.%06d %d ", tmbuf, tv1.tv_usec, delta);
		fwrite(ts, strlen(ts), 1, tfp);
		fwrite(url, strlen(url), 1, tfp);
		fwrite(" ", 1, 1, tfp);
		fwrite(funcInfo1, strlen(funcInfo1), 1, tfp);
		fwrite(" ", 1, 1, tfp);
		const char* funcInfo2 = getFuncInfo(L);
		fwrite(funcInfo2, strlen(funcInfo2), 1, tfp);
		const char* status = (ret >= 0 && ret < sizeof(THREAD_STATUS_STR)) ? THREAD_STATUS_STR[ret] : NULL;
		if (status) {
			fwrite(" ", 1, 1, tfp);
			fwrite(status, strlen(status), 1, tfp);
		}
		fwrite("\n", 1, 1, tfp);
		fflush(tfp);
	}

	invoking = false;

	return ret;
}
}
<commit_msg>modify the log format<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

extern "C" {
#define LUA_OK		0
#define LUA_YIELD	1
#define LUA_ERRRUN	2
#define LUA_ERRSYNTAX	3
#define LUA_ERRMEM	4
#define LUA_ERRERR	5
static const char* THREAD_STATUS_STR[] = {"done", "yield", "errrun", "errsyntax", "errmem", "errerr"};

#define LUA_GLOBALSINDEX	(-10002)
struct lua_State;
#define LUA_IDSIZE	60	/* Size of lua_Debug.short_src. */
struct lua_Debug {
  int event;
  const char *name;	/* (n) */
  const char *namewhat;	/* (n) `global', `local', `field', `method' */
  const char *what;	/* (S) `Lua', `C', `main', `tail' */
  const char *source;	/* (S) */
  int currentline;	/* (l) */
  int nups;		/* (u) number of upvalues */
  int linedefined;	/* (S) */
  int lastlinedefined;	/* (S) */
  char short_src[LUA_IDSIZE]; /* (S) */
  /* private part */
  int i_ci;  /* active function */
};
typedef int (*lua_resume_t)(lua_State *L, int narg);
typedef int (*lua_getstack_t) (lua_State *L, int level, lua_Debug *ar);
typedef int (*lua_getinfo_t) (lua_State *L, const char *what, lua_Debug *ar);
typedef int (*lua_gettop_t) (lua_State *L);
typedef int (*lua_type_t) (lua_State *L, int index);
typedef void (*lua_call_t) (lua_State *L, int nargs, int nresults);
typedef const char * (*lua_tostring_t) (lua_State *L, int index, size_t* len);
typedef void  (*lua_pushvalue_t) (lua_State *L, int index);
typedef void (*lua_settop_t)(lua_State *L, int idx);
typedef void (*lua_getfield_t) (lua_State *L, int index, const char *k);

static lua_resume_t lua_resume_f = NULL;
static lua_getstack_t lua_getstack_f = NULL;
static lua_getinfo_t lua_getinfo_f = NULL;
static lua_gettop_t lua_gettop_f = NULL;
static lua_type_t lua_type_f = NULL;
static lua_call_t lua_call_f = NULL;
static lua_tostring_t lua_tostring_f = NULL;
static lua_pushvalue_t lua_pushvalue_f = NULL;
static lua_settop_t lua_settop_f = NULL;
static lua_getfield_t lua_getfield_f = NULL;

static const char* getFuncInfo(lua_State* L) {
	const static size_t buflen = 512;
	static char buf[buflen];

	if (lua_gettop_f(L) > 0) {
		if (lua_type_f(L, 1) == 6) {
			lua_pushvalue_f(L, 1);
			lua_Debug info;
			lua_getinfo_f(L, ">nSl", &info);
			snprintf(buf, buflen, "%s,%s,%d",
				info.name, info.source, info.currentline ?: info.linedefined);
			return buf;
		}
	}

	lua_Debug info;
	lua_getstack_f(L, 1, &info);
	lua_getinfo_f(L, "nSl", &info);
	snprintf(buf, buflen, "%s,%s,%d",
			info.name, info.short_src, info.currentline ?: info.linedefined);
	return buf;
}

static void initfunc() {
	if (!lua_resume_f) {
		lua_resume_f = (lua_resume_t)dlsym(RTLD_NEXT, "lua_resume");
		lua_getstack_f = (lua_getstack_t)dlsym(RTLD_NEXT, "lua_getstack");
		lua_getinfo_f = (lua_getinfo_t)dlsym(RTLD_NEXT, "lua_getinfo");
		lua_gettop_f = (lua_gettop_t)dlsym(RTLD_NEXT, "lua_gettop");
		lua_type_f = (lua_type_t)dlsym(RTLD_NEXT, "lua_type");
		lua_call_f = (lua_call_t)dlsym(RTLD_NEXT, "lua_call");
		lua_tostring_f = (lua_tostring_t)dlsym(RTLD_NEXT, "lua_tolstring");
		lua_pushvalue_f = (lua_pushvalue_t)dlsym(RTLD_NEXT, "lua_pushvalue");
		lua_settop_f = (lua_settop_t)dlsym(RTLD_NEXT, "lua_settop");
		lua_getfield_f = (lua_getfield_t)dlsym(RTLD_NEXT, "lua_getfield");
	}
}

int lua_resume(lua_State *L, int narg) {
	initfunc();

	static bool enabled = true;

	if (!enabled) {
		return lua_resume_f(L, narg);
	}

	// skip init phase, keep static variables untouched in master process
	{
		char buf[32];
		lua_getfield_f(L, LUA_GLOBALSINDEX, "ngx");
		lua_getfield_f(L, -1, "get_phase");
		lua_call_f(L, 0, 1);
		size_t len;
		const char* str = lua_tostring_f(L, -1, &len);
		len = (len > 31) ? 31 : len;
		strncpy(buf, str, len);
		buf[len] = 0;
		lua_settop_f(L, -(2)-1);
		if (strcmp(buf, "init") == 0) {
			return lua_resume_f(L, narg);
		}
	}

	// read configs from nginx.conf once
	static bool initCfg = false;
	static int NGX_LUA_BLOCK_CHECK_MIN_MS = 10;
	static FILE* fp = NULL;
	static char* fpath = NULL;
	if (!initCfg) {
		char* tmp = getenv("NGX_LUA_BLOCK_CHECK");
		enabled = (tmp && strcmp(tmp, "true") == 0);
		if (!enabled) {
			return lua_resume_f(L, narg);
		}

		char* threshold = getenv("NGX_LUA_BLOCK_CHECK_MIN_MS");
		if (threshold) {
			NGX_LUA_BLOCK_CHECK_MIN_MS = atoi(threshold);
		}

		fpath = getenv("NGX_LUA_BLOCK_CHECK_OUTPUT_FILE");

		initCfg = true;
	}

	// avoid reentrent, we just care about the top level invocation
	static bool invoking = false;
	if (invoking) {
		return lua_resume_f(L, narg);
	} else {
		invoking = true;
	}

	timeval tv1;
	gettimeofday(&tv1, NULL);

	const char* funcInfo1 = getFuncInfo(L);

	int ret = lua_resume_f(L, narg);

	timeval tv2;
	gettimeofday(&tv2, NULL);

	if (tv2.tv_usec < tv1.tv_usec) {
		tv2.tv_sec--;
		tv2.tv_usec += 1000000;
	}
	unsigned long delta = (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec) / 1000;

	if (delta >= NGX_LUA_BLOCK_CHECK_MIN_MS) {
		tm now;
		localtime_r(&tv1.tv_sec, &now);
		char tmbuf[64];
		strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", &now);

		const static size_t urllen = 128;
		char url[urllen];
		lua_getfield_f(L, LUA_GLOBALSINDEX, "ngx");
		lua_getfield_f(L, -1, "var");
		lua_getfield_f(L, -1, "request_uri");
		size_t len;
		const char* str = lua_tostring_f(L, -1, &len);
		len = (len > urllen - 1) ? (urllen - 1) : len;
		strncpy(url, str, len);
		url[len] = 0;
		lua_settop_f(L, -(3)-1);

		if (!fp && fpath) {
			char tmp[64];
			pid_t pid = getpid();
			sprintf(tmp, "%s.%d", fpath, pid);
			fp = fopen(tmp, "w");
		}

		FILE* tfp = fp ?: stdout;
		char ts[64];
		sprintf(ts, "%s.%06d %dms ", tmbuf, tv1.tv_usec, delta);
		fwrite(ts, strlen(ts), 1, tfp);
		fwrite(url, strlen(url), 1, tfp);
		fwrite(" ", 1, 1, tfp);
		fwrite(funcInfo1, strlen(funcInfo1), 1, tfp);
		fwrite(" ", 1, 1, tfp);
		const char* funcInfo2 = getFuncInfo(L);
		fwrite(funcInfo2, strlen(funcInfo2), 1, tfp);
		const char* status = (ret >= 0 && ret < sizeof(THREAD_STATUS_STR)) ? THREAD_STATUS_STR[ret] : NULL;
		if (status) {
			fwrite(" ", 1, 1, tfp);
			fwrite(status, strlen(status), 1, tfp);
		}
		fwrite("\n", 1, 1, tfp);
		fflush(tfp);
	}

	invoking = false;

	return ret;
}
}
<|endoftext|>


<commit_before>/*
 * (c) 2005-2020  Copyright, Real-Time Innovations, Inc. All rights reserved.
 * Subject to Eclipse Public License v1.0; see LICENSE.md for details.
 */

#include "Infrastructure_common.h"

/*
 * Connext DDS Pro and Micro have their own implementation for:
 *
 * - Semaphore
 * - Mutex
 * - Clock
 * - Threads
 *
 * Therefore we will use those, to ensure not having to use the C++11 code,
 * which will make us compatible with less OSs. In other cases we do need a
 * implementation for these classes.
 */
#if !defined(PERFTEST_RTI_MICRO) && !defined(PERFTEST_RTI_PRO)

/********************************************************************/
/* Perftest Semaphore class */

PerftestSemaphore* PerftestSemaphore_new(unsigned int count)
{
    return new PerftestSemaphore(count);
}

PerftestSemaphore* PerftestSemaphore_new()
{
    PerftestSemaphore *semaphore = NULL;
    semaphore = new PerftestSemaphore(PERFTEST_SEMAPHORE_COUNT);
    return semaphore;
}

void PerftestSemaphore_delete(PerftestSemaphore* semaphore)
{
    delete semaphore;
}

bool PerftestSemaphore_give(PerftestSemaphore* semaphore)
{
    return semaphore->give();
}

bool PerftestSemaphore_take(PerftestSemaphore* semaphore, int timeout)
{
    return semaphore->take();
}

/********************************************************************/
/* Perftest Mutex class */

PerftestMutex* PerftestMutex_new()
{
    PerftestMutex* mutex;
    mutex = new PerftestMutex();
    return mutex;
}

void PerftestMutex_delete(std::mutex* mutex)
{
    delete mutex;
}

void PerftestMutex_give(std::mutex* mutex)
{
    mutex->unlock();
}

bool PerftestMutex_take(std::mutex* mutex)
{
    try
    {
        return mutex->try_lock();
    }
    catch(const std::exception& e)
    {
        std::cerr << "[Exception]: " << e.what() << '\n';
        return false;
    }
}

/********************************************************************/
/* Perftest Clock class */

#define SPIN_MACRO(spinCount)                 \
{                                                \
    unsigned long long int spin;                 \
    unsigned long long int ad, bd, cd;           \
    volatile unsigned long long int *a, *b, *c;  \
    a = &ad;                                     \
    b = &bd;                                     \
    c = &cd;                                     \
    for (spin = 0; spin < (spinCount); ++spin) { \
        *a = 3;                                  \
        *b = 1;                                  \
        *c = (*a / (*b)) * spin;                 \
    }                                            \
}

PerftestClock &PerftestClock::getInstance()
{
    static PerftestClock instance;
    return instance;
}

unsigned long long PerftestClock::getTime()
{
    clock_gettime(CLOCK_MONOTONIC, &timeStruct);
    return (timeStruct.tv_sec * ONE_MILLION) + timeStruct.tv_nsec/1000;
}

void PerftestClock::milliSleep(unsigned int millisec)
{
    std::this_thread::sleep_for(std::chrono::milliseconds(millisec));
}

void PerftestClock::sleep(const struct DDS_Duration_t& sleep_period)
{
    NDDSUtility::sleep(sleep_period);
}

void NDDSUtility::sleep(const struct DDS_Duration_t &durationIn)
{
    std::this_thread::sleep_for(
            std::chrono::seconds(durationIn.sec)
            + std::chrono::nanoseconds(durationIn.nanosec));
}

void NDDSUtility::spin(unsigned long long int spinCount)
{
    SPIN_MACRO(spinCount);
}

unsigned long long int
NDDSUtility::get_spin_per_microsecond(unsigned int precision)
{
    /* Same default values used by DDS */
    unsigned int spinCount = 200000;
    unsigned long long clockCalculationLoopCountMax = 100;

    unsigned long long usec = 0;
    unsigned long long iterations = 0;

    PerftestClock clock = PerftestClock::getInstance();

    do{
        usec = clock.getTime(); // Initial time
        SPIN_MACRO(spinCount * iterations);
        usec = clock.getTime() - usec; // Final time
        iterations++;
        /*
        * If the the clock have a low precision, increase spinCount
        * until we measure some us or reach a maximun count loop
        */
    } while (usec < precision && iterations < clockCalculationLoopCountMax);

    /*
    * The measure time can be zero due to lack of resolution or non
    * monotonic clocks and a really fast machine.
    * We may end on a exception condition, unable to calculate the
    * spins per micro-seconds.
    */
    if (usec == 0) {
        fprintf(stderr,
                "Unable to calculate the number of spins per"
                "micro-seconds\n");
        return 0;
    }
    return (unsigned long long) (iterations * spinCount) / usec;
}

/********************************************************************/
/* Perftest Thread class */

struct PerftestThreadOnSpawnedMethod
{
    ThreadOnSpawnedMethod method;
    void *thread_param;

}

PerftestThread* PerftestThread_new(
    const char *name,
    int, // threadPriority (not used here)
    int, // threadOptions (not used here)
    ThreadOnSpawnedMethod method,
    void *threadParam)
{
    return new PerftestThread(method, threadParam);
}

void PerftestThread_delete(PerftestThread* thread)
{
    if (thread != NULL) {
        thread->join();
        delete thread;
    }
}

#endif // If not defined PRO or MICRO

/********************************************************************/
/* Perftest Timer class */

void *PerftestTimer::waitAndExecute(void *scheduleInfo)
{
    ScheduleInfo *info = static_cast<ScheduleInfo *>(scheduleInfo);

    PerftestClock::milliSleep(info->timer * 1000u);

    if (info->handlerFunction != NULL) {
        info->handlerFunction();
    }

    return NULL;
}

PerftestTimer &PerftestTimer::getInstance()
{
    static PerftestTimer instance;
    return instance;
}

PerftestThread *PerftestTimer::setTimeout(PerftestTimer::ScheduleInfo &info)
{
    struct PerftestThread *timerThread = NULL;

    timerThread = PerftestThread_new(
            "timerThread",
            Perftest_THREAD_PRIORITY_DEFAULT,
            Perftest_THREAD_OPTION_DEFAULT,
            waitAndExecute,
            &info);

    return timerThread;
}

/********************************************************************/
/* Perftest FileHandler class */

bool PerftestFileHandler::path_is_file(std::string const& path)
{

  #if defined(RTI_UNIX) || defined(RTI_WIN32)
    struct stat fileStat;
    if (stat(path.c_str(), &fileStat) == 0) {
        if (fileStat.st_mode & S_IFREG) {
            return true;
        } else {
            std::cerr << "[Error] path_is_file: \"" << path
                      << "\" is not a regular file" << std::endl;
            return false;
        }
    } else {
        std::cerr << "[Error] path_is_file: Could not open file: \"" << path
                  << "\"" << std::endl;
        return false;
    }
  #else
    std::cerr << "[Error] path_is_file: Function not implemented for this OS"
              << std::endl;
    return false;
  #endif
}

long PerftestFileHandler::get_file_size(std::string const& fileName)
{

  #if defined(RTI_UNIX) || defined(RTI_WIN32)
    std::ifstream ifs(fileName.c_str(), std::ios::binary | std::ios::ate);
    if (!ifs.good()) {
        std::cerr << "[Error] get_file_size: Could not open file: \""
                  << fileName
                  << "\""
                  << std::endl;
        return -1;
    }
    std::ifstream::pos_type pos = ifs.tellg();
    ifs.close();
    return pos;
  #else
    std::cerr << "[Error] get_file_size: Function not implemented for this OS"
              << std::endl;
    return -1;
  #endif
}

/* If the function can not read the file would return -1 */
long PerftestFileHandler::read_file(
        std::string const& fileName,
        char * outputData,
        unsigned int bytesToRead,
        unsigned int startPos)
{
  #if defined(RTI_UNIX) || defined(RTI_WIN32)
    std::ifstream ifs(fileName.c_str(), std::ios::binary | std::ios::ate);

    if (!ifs.good()) {
        std::cerr << "[Error] read_file: Could not open file: \"" << fileName
                  << "\""
                  << std::endl;
        return -1;
    }

    std::ifstream::pos_type pos = ifs.tellg();
    if (bytesToRead != 0 && bytesToRead < pos) {
        pos = bytesToRead;
    }
    else if (bytesToRead > pos) {
        std::cerr << "[Error] read_file: The file \""
                  << fileName
                  << "\" does not have the number of bytes requested ("
                  << bytesToRead
                  << ") from the start position "
                  << startPos
                  << "."
                  << std::endl;
        return -1;
    }

    /* By default startPos is 0 */
    ifs.seekg(startPos, std::ios::beg);
    ifs.read(outputData, pos);
    ifs.close();

    return pos;
  #else
    std::cerr << "[Error] read_file: Function not implemented for this OS"
              << std::endl;
    return -1;
  #endif
}

/*
 * Function to check if a given string is an ip (it does not check for ranges)
 */
bool is_ip_address(std::string ip_string)
{
    int octect1, octect2, octect3, octect4;
    if (sscanf(ip_string.c_str(),
               "%d.%d.%d.%d",
               &octect1,
               &octect2,
               &octect3,
               &octect4)
        != 4) {
        return false;
    }
    return true;
}
<commit_msg>Simplify code<commit_after>/*
 * (c) 2005-2020  Copyright, Real-Time Innovations, Inc. All rights reserved.
 * Subject to Eclipse Public License v1.0; see LICENSE.md for details.
 */

#include "Infrastructure_common.h"

/*
 * Connext DDS Pro and Micro have their own implementation for:
 *
 * - Semaphore
 * - Mutex
 * - Clock
 * - Threads
 *
 * Therefore we will use those, to ensure not having to use the C++11 code,
 * which will make us compatible with less OSs. In other cases we do need a
 * implementation for these classes.
 */
#if !defined(PERFTEST_RTI_MICRO) && !defined(PERFTEST_RTI_PRO)

/********************************************************************/
/* Perftest Semaphore class */

PerftestSemaphore* PerftestSemaphore_new(unsigned int count)
{
    return new PerftestSemaphore(count);
}

PerftestSemaphore* PerftestSemaphore_new()
{
    PerftestSemaphore *semaphore = NULL;
    semaphore = new PerftestSemaphore(PERFTEST_SEMAPHORE_COUNT);
    return semaphore;
}

void PerftestSemaphore_delete(PerftestSemaphore* semaphore)
{
    delete semaphore;
}

bool PerftestSemaphore_give(PerftestSemaphore* semaphore)
{
    return semaphore->give();
}

bool PerftestSemaphore_take(PerftestSemaphore* semaphore, int timeout)
{
    return semaphore->take();
}

/********************************************************************/
/* Perftest Mutex class */

PerftestMutex* PerftestMutex_new()
{
    PerftestMutex* mutex;
    mutex = new PerftestMutex();
    return mutex;
}

void PerftestMutex_delete(std::mutex* mutex)
{
    delete mutex;
}

void PerftestMutex_give(std::mutex* mutex)
{
    mutex->unlock();
}

bool PerftestMutex_take(std::mutex* mutex)
{
    return mutex->try_lock();
}

/********************************************************************/
/* Perftest Clock class */

#define SPIN_MACRO(spinCount)                 \
{                                                \
    unsigned long long int spin;                 \
    unsigned long long int ad, bd, cd;           \
    volatile unsigned long long int *a, *b, *c;  \
    a = &ad;                                     \
    b = &bd;                                     \
    c = &cd;                                     \
    for (spin = 0; spin < (spinCount); ++spin) { \
        *a = 3;                                  \
        *b = 1;                                  \
        *c = (*a / (*b)) * spin;                 \
    }                                            \
}

PerftestClock &PerftestClock::getInstance()
{
    static PerftestClock instance;
    return instance;
}

unsigned long long PerftestClock::getTime()
{
    clock_gettime(CLOCK_MONOTONIC, &timeStruct);
    return (timeStruct.tv_sec * ONE_MILLION) + timeStruct.tv_nsec/1000;
}

void PerftestClock::milliSleep(unsigned int millisec)
{
    std::this_thread::sleep_for(std::chrono::milliseconds(millisec));
}

void PerftestClock::sleep(const struct DDS_Duration_t& sleep_period)
{
    NDDSUtility::sleep(sleep_period);
}

void NDDSUtility::sleep(const struct DDS_Duration_t &durationIn)
{
    std::this_thread::sleep_for(
            std::chrono::seconds(durationIn.sec)
            + std::chrono::nanoseconds(durationIn.nanosec));
}

void NDDSUtility::spin(unsigned long long int spinCount)
{
    SPIN_MACRO(spinCount);
}

unsigned long long int
NDDSUtility::get_spin_per_microsecond(unsigned int precision)
{
    /* Same default values used by DDS */
    unsigned int spinCount = 200000;
    unsigned long long clockCalculationLoopCountMax = 100;

    unsigned long long usec = 0;
    unsigned long long iterations = 0;

    PerftestClock clock = PerftestClock::getInstance();

    do{
        usec = clock.getTime(); // Initial time
        SPIN_MACRO(spinCount * iterations);
        usec = clock.getTime() - usec; // Final time
        iterations++;
        /*
        * If the the clock have a low precision, increase spinCount
        * until we measure some us or reach a maximun count loop
        */
    } while (usec < precision && iterations < clockCalculationLoopCountMax);

    /*
    * The measure time can be zero due to lack of resolution or non
    * monotonic clocks and a really fast machine.
    * We may end on a exception condition, unable to calculate the
    * spins per micro-seconds.
    */
    if (usec == 0) {
        fprintf(stderr,
                "Unable to calculate the number of spins per"
                "micro-seconds\n");
        return 0;
    }
    return (unsigned long long) (iterations * spinCount) / usec;
}

/********************************************************************/
/* Perftest Thread class */

struct PerftestThreadOnSpawnedMethod
{
    ThreadOnSpawnedMethod method;
    void *thread_param;

}

PerftestThread* PerftestThread_new(
    const char *name,
    int, // threadPriority (not used here)
    int, // threadOptions (not used here)
    ThreadOnSpawnedMethod method,
    void *threadParam)
{
    return new PerftestThread(method, threadParam);
}

void PerftestThread_delete(PerftestThread* thread)
{
    if (thread != NULL) {
        thread->join();
        delete thread;
    }
}

#endif // If not defined PRO or MICRO

/********************************************************************/
/* Perftest Timer class */

void *PerftestTimer::waitAndExecute(void *scheduleInfo)
{
    ScheduleInfo *info = static_cast<ScheduleInfo *>(scheduleInfo);

    PerftestClock::milliSleep(info->timer * 1000u);

    if (info->handlerFunction != NULL) {
        info->handlerFunction();
    }

    return NULL;
}

PerftestTimer &PerftestTimer::getInstance()
{
    static PerftestTimer instance;
    return instance;
}

PerftestThread *PerftestTimer::setTimeout(PerftestTimer::ScheduleInfo &info)
{
    struct PerftestThread *timerThread = NULL;

    timerThread = PerftestThread_new(
            "timerThread",
            Perftest_THREAD_PRIORITY_DEFAULT,
            Perftest_THREAD_OPTION_DEFAULT,
            waitAndExecute,
            &info);

    return timerThread;
}

/********************************************************************/
/* Perftest FileHandler class */

bool PerftestFileHandler::path_is_file(std::string const& path)
{

  #if defined(RTI_UNIX) || defined(RTI_WIN32)
    struct stat fileStat;
    if (stat(path.c_str(), &fileStat) == 0) {
        if (fileStat.st_mode & S_IFREG) {
            return true;
        } else {
            std::cerr << "[Error] path_is_file: \"" << path
                      << "\" is not a regular file" << std::endl;
            return false;
        }
    } else {
        std::cerr << "[Error] path_is_file: Could not open file: \"" << path
                  << "\"" << std::endl;
        return false;
    }
  #else
    std::cerr << "[Error] path_is_file: Function not implemented for this OS"
              << std::endl;
    return false;
  #endif
}

long PerftestFileHandler::get_file_size(std::string const& fileName)
{

  #if defined(RTI_UNIX) || defined(RTI_WIN32)
    std::ifstream ifs(fileName.c_str(), std::ios::binary | std::ios::ate);
    if (!ifs.good()) {
        std::cerr << "[Error] get_file_size: Could not open file: \""
                  << fileName
                  << "\""
                  << std::endl;
        return -1;
    }
    std::ifstream::pos_type pos = ifs.tellg();
    ifs.close();
    return pos;
  #else
    std::cerr << "[Error] get_file_size: Function not implemented for this OS"
              << std::endl;
    return -1;
  #endif
}

/* If the function can not read the file would return -1 */
long PerftestFileHandler::read_file(
        std::string const& fileName,
        char * outputData,
        unsigned int bytesToRead,
        unsigned int startPos)
{
  #if defined(RTI_UNIX) || defined(RTI_WIN32)
    std::ifstream ifs(fileName.c_str(), std::ios::binary | std::ios::ate);

    if (!ifs.good()) {
        std::cerr << "[Error] read_file: Could not open file: \"" << fileName
                  << "\""
                  << std::endl;
        return -1;
    }

    std::ifstream::pos_type pos = ifs.tellg();
    if (bytesToRead != 0 && bytesToRead < pos) {
        pos = bytesToRead;
    }
    else if (bytesToRead > pos) {
        std::cerr << "[Error] read_file: The file \""
                  << fileName
                  << "\" does not have the number of bytes requested ("
                  << bytesToRead
                  << ") from the start position "
                  << startPos
                  << "."
                  << std::endl;
        return -1;
    }

    /* By default startPos is 0 */
    ifs.seekg(startPos, std::ios::beg);
    ifs.read(outputData, pos);
    ifs.close();

    return pos;
  #else
    std::cerr << "[Error] read_file: Function not implemented for this OS"
              << std::endl;
    return -1;
  #endif
}

/*
 * Function to check if a given string is an ip (it does not check for ranges)
 */
bool is_ip_address(std::string ip_string)
{
    int octect1, octect2, octect3, octect4;
    if (sscanf(ip_string.c_str(),
               "%d.%d.%d.%d",
               &octect1,
               &octect2,
               &octect3,
               &octect4)
        != 4) {
        return false;
    }
    return true;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2012 Couchbase, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#include "config.h"
#include <gtest/gtest.h>
#include <libcouchbase/couchbase.h>

#define EVENT_LISTS_UNIT_TESTS 1
#include "plugins/io/win32/event_lists.h"

class CCBC_103 : public ::testing::Test
{
};

TEST_F(CCBC_103, events)
{
    winsock_io_cookie instance;
    winsock_event e1, e2, e3, e4;

    link_event(&instance, &e1);
    ASSERT_EQ(&e1, instance.events);

    link_event(&instance, &e2);
    ASSERT_EQ(&e2, instance.events);

    link_event(&instance, &e3);
    ASSERT_EQ(&e3, instance.events);

    link_event(&instance, &e4);
    ASSERT_EQ(&e4, instance.events);

    ASSERT_EQ(1, event_contains(&instance, &e1));
    ASSERT_EQ(1, event_contains(&instance, &e2));
    ASSERT_EQ(1, event_contains(&instance, &e3));
    ASSERT_EQ(1, event_contains(&instance, &e4));

    // Try to unlink the one in the middle
    unlink_event(&instance, &e2);
    ASSERT_EQ(1, event_contains(&instance, &e1));
    ASSERT_EQ(0, event_contains(&instance, &e2));
    ASSERT_EQ(1, event_contains(&instance, &e3));
    ASSERT_EQ(1, event_contains(&instance, &e4));

    // Try to unlink the last one
    unlink_event(&instance, &e1);
    ASSERT_EQ(0, event_contains(&instance, &e1));
    ASSERT_EQ(0, event_contains(&instance, &e2));
    ASSERT_EQ(1, event_contains(&instance, &e3));
    ASSERT_EQ(1, event_contains(&instance, &e4));

    // try to unlink the current head
    unlink_event(&instance, &e4);
    ASSERT_EQ(0, event_contains(&instance, &e1));
    ASSERT_EQ(0, event_contains(&instance, &e2));
    ASSERT_EQ(1, event_contains(&instance, &e3));
    ASSERT_EQ(0, event_contains(&instance, &e4));

    // try to unlink the last one
    unlink_event(&instance, &e3);
    ASSERT_EQ(0, event_contains(&instance, &e1));
    ASSERT_EQ(0, event_contains(&instance, &e2));
    ASSERT_EQ(0, event_contains(&instance, &e3));
    ASSERT_EQ(0, event_contains(&instance, &e4));

    // And we should be able to add all back
    link_event(&instance, &e1);
    link_event(&instance, &e2);
    link_event(&instance, &e3);
    link_event(&instance, &e4);
    ASSERT_EQ(1, event_contains(&instance, &e1));
    ASSERT_EQ(1, event_contains(&instance, &e2));
    ASSERT_EQ(1, event_contains(&instance, &e3));
    ASSERT_EQ(1, event_contains(&instance, &e4));
}

TEST_F(CCBC_103, timers)
{
    winsock_io_cookie instance;
    winsock_timer e1, e2, e3, e4;

    link_timer(&instance, &e1);
    ASSERT_EQ(&e1, instance.timers);

    link_timer(&instance, &e2);
    ASSERT_EQ(&e2, instance.timers);

    link_timer(&instance, &e3);
    ASSERT_EQ(&e3, instance.timers);

    link_timer(&instance, &e4);
    ASSERT_EQ(&e4, instance.timers);

    ASSERT_EQ(1, timer_contains(&instance, &e1));
    ASSERT_EQ(1, timer_contains(&instance, &e2));
    ASSERT_EQ(1, timer_contains(&instance, &e3));
    ASSERT_EQ(1, timer_contains(&instance, &e4));

    // Try to unlink the one in the middle
    unlink_timer(&instance, &e2);
    ASSERT_EQ(1, timer_contains(&instance, &e1));
    ASSERT_EQ(0, timer_contains(&instance, &e2));
    ASSERT_EQ(1, timer_contains(&instance, &e3));
    ASSERT_EQ(1, timer_contains(&instance, &e4));

    // Try to unlink the last one
    unlink_timer(&instance, &e1);
    ASSERT_EQ(0, timer_contains(&instance, &e1));
    ASSERT_EQ(0, timer_contains(&instance, &e2));
    ASSERT_EQ(1, timer_contains(&instance, &e3));
    ASSERT_EQ(1, timer_contains(&instance, &e4));

    // try to unlink the current head
    unlink_timer(&instance, &e4);
    ASSERT_EQ(0, timer_contains(&instance, &e1));
    ASSERT_EQ(0, timer_contains(&instance, &e2));
    ASSERT_EQ(1, timer_contains(&instance, &e3));
    ASSERT_EQ(0, timer_contains(&instance, &e4));

    // try to unlink the last one
    unlink_timer(&instance, &e3);
    ASSERT_EQ(0, timer_contains(&instance, &e1));
    ASSERT_EQ(0, timer_contains(&instance, &e2));
    ASSERT_EQ(0, timer_contains(&instance, &e3));
    ASSERT_EQ(0, timer_contains(&instance, &e4));

    // And we should be able to add all back
    link_timer(&instance, &e1);
    link_timer(&instance, &e2);
    link_timer(&instance, &e3);
    link_timer(&instance, &e4);
    ASSERT_EQ(1, timer_contains(&instance, &e1));
    ASSERT_EQ(1, timer_contains(&instance, &e2));
    ASSERT_EQ(1, timer_contains(&instance, &e3));
    ASSERT_EQ(1, timer_contains(&instance, &e4));
}
<commit_msg>Rewrite test for CCBC-103 to use lcb_list_t<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2012 Couchbase, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#include "config.h"
#include <gtest/gtest.h>
#include <libcouchbase/couchbase.h>
#include "list.h"

class CCBC_103 : public ::testing::Test
{
};

typedef struct {
    lcb_list_t list;
} event_t;

typedef struct {
    event_t events;
} io_cookie;

TEST_F(CCBC_103, lists)
{
    io_cookie instance;
    event_t e1, e2, e3, e4;

    lcb_list_init(&instance.events.list);
    lcb_list_append(&instance.events.list, &e1.list);
    ASSERT_EQ(&e1.list, instance.events.list.prev);

    lcb_list_append(&instance.events.list, &e2.list);
    ASSERT_EQ(&e2.list, instance.events.list.prev);

    lcb_list_append(&instance.events.list, &e3.list);
    ASSERT_EQ(&e3.list, instance.events.list.prev);

    lcb_list_append(&instance.events.list, &e4.list);
    ASSERT_EQ(&e4.list, instance.events.list.prev);

    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e1.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e2.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e3.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e4.list));

    // Try to unlink the one in the middle
    lcb_list_delete(&e2.list);
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e1.list));
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e2.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e3.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e4.list));

    // Try to unlink the last one
    lcb_list_delete(&e1.list);
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e1.list));
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e2.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e3.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e4.list));

    // try to unlink the current head
    lcb_list_delete(&e4.list);
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e1.list));
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e2.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e3.list));
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e4.list));

    // try to unlink the last one
    lcb_list_delete(&e3.list);
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e1.list));
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e2.list));
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e3.list));
    ASSERT_EQ(0, lcb_list_contains(&instance.events.list, &e4.list));

    // And we should be able to add all back
    lcb_list_append(&instance.events.list, &e1.list);
    lcb_list_append(&instance.events.list, &e2.list);
    lcb_list_append(&instance.events.list, &e3.list);
    lcb_list_append(&instance.events.list, &e4.list);
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e1.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e2.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e3.list));
    ASSERT_EQ(1, lcb_list_contains(&instance.events.list, &e4.list));
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * @file    application.cpp
 * @authors  Sam Decrock
 *
 * Detect sound over a sliding window
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "application.h"

/* Function prototypes -------------------------------------------------------*/
void updateState(int pin, int state);
void postState(int pin, int state);
void readIncommingHttpData();

/* Variables -----------------------------------------------------------------*/
const int ledPin = D0;
const int ledPin2 = D1;
const int soundPins[] = {A0, A1, A2, A3, A4, A5, A6, A7};

static const int pinCount = 8;
int soundValues[pinCount] = {0};

int threshold = 2200; //in mV
int capacity[pinCount] = {0};
int thresholdCapacity[pinCount] = {0};
int currentSoundState[pinCount] = {0};

// HTTP:
TCPClient httpclient;
IPAddress httpServer(10,100,11,7); // Sam
// IPAddress httpServer(10,100,11,216); // Dorthe
int httpPort = 8090;

uint8_t responseBuffer[1024];

char actionSound[pinCount][230];
char actionNoSound[pinCount][231];

bool debug = true;

/* This function is called once at start up ----------------------------------*/
void setup()
{
	pinMode(ledPin, OUTPUT);
	pinMode(ledPin2, OUTPUT);

	// register every pin as input:
	for (int pin = 0; pin < pinCount; ++pin)
	{
		pinMode(soundPins[pin], INPUT);

		// create http post strings:
		sprintf(actionSound[pin], "PUT /message/putit HTTP/1.1\r\nHost: somehost\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nContent-Length: 75\r\n\r\n{\n\t\"MicStateChangedInRunningMeeting\": {\n\t\t\"SeatNr\": %d,\n\t\t\"State\": \"On\"\n\t}\n}", pin);
		sprintf(actionNoSound[pin], "PUT /message/putit HTTP/1.1\r\nHost: somehost\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nContent-Length: 76\r\n\r\n{\n\t\"MicStateChangedInRunningMeeting\": {\n\t\t\"SeatNr\": %d,\n\t\t\"State\": \"Off\"\n\t}\n}", pin);
	}

	if(debug) Serial.begin(9600);

	// indicates machine is booting:
	digitalWrite(ledPin2, 1);
}

/* This function loops forever (every 5ms) ------------------------------------*/
void loop()
{
	for (int pin = 0; pin < pinCount; ++pin)
	{
		soundValues[pin] = analogRead(soundPins[pin]);

		if(soundValues[pin] > threshold)
		{
			thresholdCapacity[pin]++;

			if(thresholdCapacity[pin] >= 3)
			{
				capacity[pin] = 200; //2 seconds
				thresholdCapacity[pin] = 0;

				updateState(pin, 1);
			}
		}
		else
		{
			capacity[pin]--;
			if(capacity[pin] <= 0 ){
				// happens after capacity*(delay+5 ms):
				capacity[pin] = 0; //cap

				updateState(pin, 0);
			}

			thresholdCapacity[pin]--;
			if(thresholdCapacity[pin] <= 0)
			{
				thresholdCapacity[pin] = 0;
			}
		}
	}

	readIncommingHttpData(); // so that the socket doesn't block everything

	delay(5); // wait an extra 5ms, that's 10ms between loops

	// indicates machine has booted:
	digitalWrite(ledPin2, 0);
}

void updateState(int pin, int state)
{
	// only send state if different from previous:
	if(currentSoundState[pin] != state)
	{
		currentSoundState[pin] = state;

		digitalWrite(ledPin, state); // turn LED on/off

		postState(pin, state);
	}
}

void postState(int pin, int state) {
	if(debug) Serial.println("Sending state over HTTP POST");
	if(debug) Serial.print("Pin: ");
	if(debug) Serial.print(pin);
	if(debug) Serial.print("State: ");
	if(debug) Serial.println(state);

	if( !httpclient.connected() )
	{
		if(debug) Serial.println("HTTP was not connected. Connecting...");
		httpclient.connect(httpServer, httpPort);
	}

	if( !httpclient.connected() )
	{
		if(debug) Serial.println("HTTP still not connected. Trying a second time...");
		httpclient.connect(httpServer, httpPort);
	}

	if( !httpclient.connected() )
	{
		if(debug) Serial.println("HTTP could not connect.");
		return;
	}

	if(debug) Serial.println("HTTP connected. Sending state.");

	if(state == 1)
	{
		httpclient.print(actionSound[pin]);
	}

	if(state == 0)
	{
		httpclient.print(actionNoSound[pin]);
	}

	// flush, so the buffer is clear to read response:
	httpclient.flush();

	if(debug) Serial.println("> HTTP request sent:");

	// httpclient.stop(); //break connection (not necessary, server will break connection depending on 'Connection' header)
}

void readIncommingHttpData()
{
	// READ RESPONSE
	if( httpclient.available() )
	{
		// 1. fill the buffer with zeros
		memset(responseBuffer, 0x00, 1024);

		// 2. read the first 1023 bytes
		httpclient.read(responseBuffer, 1023);

		// 3. read the rest of the socket buffer so that it's empty
		while(httpclient.available())
		{
			httpclient.read();
		}

		if(responseBuffer[0] != 0x00)
		{
			if(debug) Serial.println("> incomming HTTP response:");
			if(debug) Serial.println();
			if(debug) Serial.println((char*)responseBuffer);
			if(debug) Serial.println();
		}
	}
}
<commit_msg>code clean up<commit_after>/**
 ******************************************************************************
 * @file    application.cpp
 * @authors  Sam Decrock
 *
 * Detect sound over a sliding window
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "application.h"

/* Function prototypes -------------------------------------------------------*/
void updateState(int pin, int state);
void postState(int pin, int state);
void readIncommingHttpData();

/* Variables -----------------------------------------------------------------*/
const int ledPin = D0;
const int ledPin2 = D1;
const int soundPins[] = {A0, A1, A2, A3, A4, A5, A6, A7};

const int pinCount = 8;
int soundValues[pinCount] = {0};

int threshold = 2200; //in mV
int capacity[pinCount] = {0};
int thresholdCapacity[pinCount] = {0};
int currentSoundState[pinCount] = {0};

// HTTP:
TCPClient httpclient;
IPAddress httpServer(10,100,11,7); // Sam
// IPAddress httpServer(10,100,11,216); // Dorthe
int httpPort = 8090;

uint8_t responseBuffer[1024];

char actionSound[pinCount][230];
char actionNoSound[pinCount][231];

bool debug = false;

/* This function is called once at start up ----------------------------------*/
void setup()
{
	pinMode(ledPin, OUTPUT);
	pinMode(ledPin2, OUTPUT);

	for (int pin = 0; pin < pinCount; ++pin)
	{
		// register every pin as input:
		pinMode(soundPins[pin], INPUT);

		// create http post strings:
		sprintf(actionSound[pin], "PUT /message/putit HTTP/1.1\r\nHost: somehost\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nContent-Length: 75\r\n\r\n{\n\t\"MicStateChangedInRunningMeeting\": {\n\t\t\"SeatNr\": %d,\n\t\t\"State\": \"On\"\n\t}\n}", pin);
		sprintf(actionNoSound[pin], "PUT /message/putit HTTP/1.1\r\nHost: somehost\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nContent-Length: 76\r\n\r\n{\n\t\"MicStateChangedInRunningMeeting\": {\n\t\t\"SeatNr\": %d,\n\t\t\"State\": \"Off\"\n\t}\n}", pin);
	}

	if(debug) Serial.begin(9600);

	// indicates machine is booting:
	digitalWrite(ledPin2, 1);
}

/* This function loops forever (every 5ms) ------------------------------------*/
void loop()
{
	for (int pin = 0; pin < pinCount; ++pin)
	{
		soundValues[pin] = analogRead(soundPins[pin]);

		if(soundValues[pin] > threshold)
		{
			thresholdCapacity[pin]++;

			if(thresholdCapacity[pin] >= 3)
			{
				capacity[pin] = 200; //2 seconds
				thresholdCapacity[pin] = 0;

				updateState(pin, 1);
			}
		}
		else
		{
			capacity[pin]--;
			if(capacity[pin] <= 0 ){
				// happens after capacity*(delay+5 ms):
				capacity[pin] = 0; //cap

				updateState(pin, 0);
			}

			thresholdCapacity[pin]--;
			if(thresholdCapacity[pin] <= 0)
			{
				thresholdCapacity[pin] = 0;
			}
		}
	}

	readIncommingHttpData(); // so that the socket doesn't block everything

	delay(5); // wait an extra 5ms, that's 10ms between loops

	// indicates machine has booted:
	digitalWrite(ledPin2, 0);
}

void updateState(int pin, int state)
{
	// only send state if different from previous:
	if(currentSoundState[pin] != state)
	{
		currentSoundState[pin] = state;

		digitalWrite(ledPin, state); // turn LED on/off

		postState(pin, state);
	}
}

void postState(int pin, int state) {
	if(debug) Serial.println("> Sending state over HTTP POST");
	if(debug) Serial.print("> pin: ");
	if(debug) Serial.print(pin);
	if(debug) Serial.print(" | state: ");
	if(debug) Serial.println(state);

	if( !httpclient.connected() )
	{
		if(debug) Serial.println("> HTTP was not connected. Connecting...");
		httpclient.connect(httpServer, httpPort);
	}

	if( !httpclient.connected() )
	{
		if(debug) Serial.println("> HTTP still not connected. Trying a second time...");
		httpclient.connect(httpServer, httpPort);
	}

	if( !httpclient.connected() )
	{
		if(debug) Serial.println("> HTTP could not connect.");
		return;
	}

	if(debug) Serial.println("> HTTP connected. Sending state.");

	if(state == 1)
	{
		httpclient.print(actionSound[pin]);
	}

	if(state == 0)
	{
		httpclient.print(actionNoSound[pin]);
	}

	// flush, so the buffer is clear to read response:
	httpclient.flush();

	if(debug) Serial.println("> HTTP request sent.");

	// httpclient.stop(); //break connection (not necessary, server will break connection depending on 'Connection' header)
}

void readIncommingHttpData()
{
	// READ RESPONSE
	if( httpclient.available() )
	{
		// 1. fill the buffer with zeros
		memset(responseBuffer, 0x00, 1024);

		// 2. read the first 1023 bytes
		httpclient.read(responseBuffer, 1023);

		// 3. read the rest of the socket buffer so that it's empty
		while(httpclient.available())
		{
			httpclient.read();
		}

		if(responseBuffer[0] != 0x00)
		{
			if(debug) Serial.println("> incomming HTTP response:");
			if(debug) Serial.println();
			if(debug) Serial.println((char*)responseBuffer);
			if(debug) Serial.println();
		}
	}
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_MAT_FUN_DIVIDE_HPP
#define STAN_MATH_REV_MAT_FUN_DIVIDE_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/mat/fun/to_var.hpp>
#include <stan/math/prim/meta.hpp>
namespace stan {
namespace math {

namespace internal {
template <int R, int C>
class matrix_scalar_divide_dv_vari : public vari {
 public:
  int rows_;
  int cols_;
  vari* adjCRef_;
  vari** adjResultRef_;
  double invc_;

  explicit matrix_scalar_divide_dv_vari(const Eigen::Matrix<double, R, C>& m,
                                        const var& c)
      : vari(0),
        rows_(m.rows()),
        cols_(m.cols()),
        adjCRef_(c.vi_),
        adjResultRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        invc_(1.0 / c.val()) {
    Eigen::Matrix<double, R, C> result = invc_ * m;
    Eigen::Map<matrix_vi>(adjResultRef_, rows_, cols_)
        = result.unaryExpr([](double x) { return new vari(x, false); });
  }

  virtual void chain() {
    Eigen::Map<matrix_vi> adjResult(adjResultRef_, rows_, cols_);
    adjCRef_->adj_
        -= invc_ * (adjResult.adj().array() * adjResult.val().array()).sum();
  }
};

template <int R, int C>
class matrix_scalar_divide_vd_vari : public vari {
 public:
  int rows_;
  int cols_;
  vari** adjMRef_;
  vari** adjResultRef_;
  double invc_;

  explicit matrix_scalar_divide_vd_vari(const Eigen::Matrix<var, R, C>& m,
                                        const double& c)
      : vari(0),
        rows_(m.rows()),
        cols_(m.cols()),
        adjMRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        adjResultRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        invc_(1.0 / c) {
    Eigen::Map<matrix_vi>(adjMRef_, rows_, cols_) = m.vi();
    Eigen::Matrix<double, R, C> result = invc_ * m.val();
    Eigen::Map<matrix_vi>(adjResultRef_, rows_, cols_)
        = result.unaryExpr([](double x) { return new vari(x, false); });
  }

  virtual void chain() {
    Eigen::Map<matrix_vi> adjM(adjMRef_, rows_, cols_);
    Eigen::Map<matrix_vi> adjResult(adjResultRef_, rows_, cols_);
    adjM.adj() += invc_ * adjResult.adj();
  }
};

template <int R, int C>
class matrix_scalar_divide_vv_vari : public vari {
 public:
  int rows_;
  int cols_;
  vari** adjMRef_;
  vari* adjC_;
  vari** adjResultRef_;
  double invc_;

  explicit matrix_scalar_divide_vv_vari(const Eigen::Matrix<var, R, C>& m,
                                        const var& c)
      : vari(0),
        rows_(m.rows()),
        cols_(m.cols()),
        adjMRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        adjC_(c.vi_),
        adjResultRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        invc_(1.0 / c.val()) {
    Eigen::Map<matrix_vi>(adjMRef_, rows_, cols_) = m.vi();
    Eigen::Matrix<double, R, C> result = invc_ * m.val();
    Eigen::Map<matrix_vi>(adjResultRef_, rows_, cols_)
        = result.unaryExpr([](double x) { return new vari(x, false); });
  }

  virtual void chain() {
    Eigen::Map<matrix_vi> adjM(adjMRef_, rows_, cols_);
    Eigen::Map<matrix_vi> adjResult(adjResultRef_, rows_, cols_);
    adjC_->adj_
        -= invc_ * (adjResult.adj().array() * adjResult.val().array()).sum();
    adjM.adj() += invc_ * adjResult.adj();
  }
};

}  // namespace internal

/**
 * Return matrix divided by scalar.
 * @tparam R number of rows or Eigen::Dynamic
 * @tparam C number of columns or Eigen::Dynamic
 * @param[in] m specified matrix
 * @param[in] c specified scalar
 * @return matrix divided by the scalar
 */
template <int R, int C>
inline Eigen::Matrix<var, R, C> divide(const Eigen::Matrix<double, R, C>& m,
                                       const var& c) {
  internal::matrix_scalar_divide_dv_vari<R, C>* baseVari
      = new internal::matrix_scalar_divide_dv_vari<R, C>(m, c);
  Eigen::Matrix<var, R, C> result(m.rows(), m.cols());
  result.vi()
      = Eigen::Map<matrix_vi>(baseVari->adjResultRef_, m.rows(), m.cols());
  return result;
}

/**
 * Return matrix divided by scalar.
 * @tparam R number of rows or Eigen::Dynamic
 * @tparam C number of columns or Eigen::Dynamic
 * @param[in] m specified matrix
 * @param[in] c specified scalar
 * @return matrix divided by the scalar
 */
template <int R, int C>
inline Eigen::Matrix<var, R, C> divide(const Eigen::Matrix<var, R, C>& m,
                                       const double& c) {
  internal::matrix_scalar_divide_vd_vari<R, C>* baseVari
      = new internal::matrix_scalar_divide_vd_vari<R, C>(m, c);
  Eigen::Matrix<var, R, C> result(m.rows(), m.cols());
  result.vi()
      = Eigen::Map<matrix_vi>(baseVari->adjResultRef_, m.rows(), m.cols());
  return result;
}

/**
 * Return matrix divided by scalar.
 * @tparam R number of rows or Eigen::Dynamic
 * @tparam C number of columns or Eigen::Dynamic
 * @param[in] m specified matrix
 * @param[in] c specified scalar
 * @return matrix divided by the scalar
 */
template <int R, int C>
inline Eigen::Matrix<var, R, C> divide(const Eigen::Matrix<var, R, C>& m,
                                       const var& c) {
  internal::matrix_scalar_divide_vv_vari<R, C>* baseVari
      = new internal::matrix_scalar_divide_vv_vari<R, C>(m, c);
  Eigen::Matrix<var, R, C> result(m.rows(), m.cols());
  result.vi()
      = Eigen::Map<matrix_vi>(baseVari->adjResultRef_, m.rows(), m.cols());
  return result;
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>Avoid constructing matrix in temporary.<commit_after>#ifndef STAN_MATH_REV_MAT_FUN_DIVIDE_HPP
#define STAN_MATH_REV_MAT_FUN_DIVIDE_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/mat/fun/to_var.hpp>
#include <stan/math/prim/meta.hpp>
namespace stan {
namespace math {

namespace internal {
template <int R, int C>
class matrix_scalar_divide_dv_vari : public vari {
 public:
  int rows_;
  int cols_;
  vari* adjCRef_;
  vari** adjResultRef_;
  double invc_;

  explicit matrix_scalar_divide_dv_vari(const Eigen::Matrix<double, R, C>& m,
                                        const var& c)
      : vari(0),
        rows_(m.rows()),
        cols_(m.cols()),
        adjCRef_(c.vi_),
        adjResultRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        invc_(1.0 / c.val()) {
    Eigen::Map<matrix_vi>(adjResultRef_, rows_, cols_)
        = (invc_ * m).unaryExpr([](double x) { return new vari(x, false); });
  }

  virtual void chain() {
    Eigen::Map<matrix_vi> adjResult(adjResultRef_, rows_, cols_);
    adjCRef_->adj_
        -= invc_ * (adjResult.adj().array() * adjResult.val().array()).sum();
  }
};

template <int R, int C>
class matrix_scalar_divide_vd_vari : public vari {
 public:
  int rows_;
  int cols_;
  vari** adjMRef_;
  vari** adjResultRef_;
  double invc_;

  explicit matrix_scalar_divide_vd_vari(const Eigen::Matrix<var, R, C>& m,
                                        const double& c)
      : vari(0),
        rows_(m.rows()),
        cols_(m.cols()),
        adjMRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        adjResultRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        invc_(1.0 / c) {
    Eigen::Map<matrix_vi>(adjMRef_, rows_, cols_) = m.vi();
    Eigen::Map<matrix_vi>(adjResultRef_, rows_, cols_)
        = (invc_ * m.val()).unaryExpr([](double x) {
            return new vari(x, false);
          });
  }

  virtual void chain() {
    Eigen::Map<matrix_vi> adjM(adjMRef_, rows_, cols_);
    Eigen::Map<matrix_vi> adjResult(adjResultRef_, rows_, cols_);
    adjM.adj() += invc_ * adjResult.adj();
  }
};

template <int R, int C>
class matrix_scalar_divide_vv_vari : public vari {
 public:
  int rows_;
  int cols_;
  vari** adjMRef_;
  vari* adjC_;
  vari** adjResultRef_;
  double invc_;

  explicit matrix_scalar_divide_vv_vari(const Eigen::Matrix<var, R, C>& m,
                                        const var& c)
      : vari(0),
        rows_(m.rows()),
        cols_(m.cols()),
        adjMRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        adjC_(c.vi_),
        adjResultRef_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
            m.rows() * m.cols())),
        invc_(1.0 / c.val()) {
    Eigen::Map<matrix_vi>(adjMRef_, rows_, cols_) = m.vi();
    Eigen::Map<matrix_vi>(adjResultRef_, rows_, cols_)
        = (invc_ * m.val()).unaryExpr([](double x) {
            return new vari(x, false);
          });
  }

  virtual void chain() {
    Eigen::Map<matrix_vi> adjM(adjMRef_, rows_, cols_);
    Eigen::Map<matrix_vi> adjResult(adjResultRef_, rows_, cols_);
    adjC_->adj_
        -= invc_ * (adjResult.adj().array() * adjResult.val().array()).sum();
    adjM.adj() += invc_ * adjResult.adj();
  }
};

}  // namespace internal

/**
 * Return matrix divided by scalar.
 * @tparam R number of rows or Eigen::Dynamic
 * @tparam C number of columns or Eigen::Dynamic
 * @param[in] m specified matrix
 * @param[in] c specified scalar
 * @return matrix divided by the scalar
 */
template <int R, int C>
inline Eigen::Matrix<var, R, C> divide(const Eigen::Matrix<double, R, C>& m,
                                       const var& c) {
  internal::matrix_scalar_divide_dv_vari<R, C>* baseVari
      = new internal::matrix_scalar_divide_dv_vari<R, C>(m, c);
  Eigen::Matrix<var, R, C> result(m.rows(), m.cols());
  result.vi()
      = Eigen::Map<matrix_vi>(baseVari->adjResultRef_, m.rows(), m.cols());
  return result;
}

/**
 * Return matrix divided by scalar.
 * @tparam R number of rows or Eigen::Dynamic
 * @tparam C number of columns or Eigen::Dynamic
 * @param[in] m specified matrix
 * @param[in] c specified scalar
 * @return matrix divided by the scalar
 */
template <int R, int C>
inline Eigen::Matrix<var, R, C> divide(const Eigen::Matrix<var, R, C>& m,
                                       const double& c) {
  internal::matrix_scalar_divide_vd_vari<R, C>* baseVari
      = new internal::matrix_scalar_divide_vd_vari<R, C>(m, c);
  Eigen::Matrix<var, R, C> result(m.rows(), m.cols());
  result.vi()
      = Eigen::Map<matrix_vi>(baseVari->adjResultRef_, m.rows(), m.cols());
  return result;
}

/**
 * Return matrix divided by scalar.
 * @tparam R number of rows or Eigen::Dynamic
 * @tparam C number of columns or Eigen::Dynamic
 * @param[in] m specified matrix
 * @param[in] c specified scalar
 * @return matrix divided by the scalar
 */
template <int R, int C>
inline Eigen::Matrix<var, R, C> divide(const Eigen::Matrix<var, R, C>& m,
                                       const var& c) {
  internal::matrix_scalar_divide_vv_vari<R, C>* baseVari
      = new internal::matrix_scalar_divide_vv_vari<R, C>(m, c);
  Eigen::Matrix<var, R, C> result(m.rows(), m.cols());
  result.vi()
      = Eigen::Map<matrix_vi>(baseVari->adjResultRef_, m.rows(), m.cols());
  return result;
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2010-2012 Jeremy Lainé
 * Contact: http://code.google.com/p/qdjango/
 *
 * This file is part of the QDjango Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#include <cstdlib>

#include "QDjango.h"

#include "util.h"

bool initialiseDatabase()
{
    char *p;

    // enable SQL debugging
    if ((p = getenv("QDJANGO_DB_DEBUG")) != 0)
        QDjango::setDebugEnabled(true);

    // open database
    QString databaseDriver = "QSQLITE";
    if ((p = getenv("QDJANGO_DB_DRIVER")) != 0)
        databaseDriver = QString::fromLocal8Bit(p);
    QSqlDatabase db = QSqlDatabase::addDatabase(databaseDriver);

    if ((p = getenv("QDJANGO_DB_NAME")) != 0)
        db.setDatabaseName(QString::fromLocal8Bit(p));
    else if (databaseDriver == "QSQLITE")
        db.setDatabaseName(":memory:");

    if ((p = getenv("QDJANGO_DB_USER")) != 0)
        db.setUserName(QString::fromLocal8Bit(p));

    if ((p = getenv("QDJANGO_DB_PASSWORD")) != 0)
        db.setPassword(QString::fromLocal8Bit(p));

    if ((p = getenv("QDJANGO_DB_HOST")) != 0)
        db.setHostName(QString::fromLocal8Bit(p));

    if (db.open()) {
        QDjango::setDatabase(db);
        return true;
    } else {
        return false;
    }
}

QString normalizeSql(const QSqlDatabase &db, const QString &sql)
{
    const QString driverName = db.driverName();
    QString modSql(sql);
    if (driverName == "QMYSQL")
        modSql.replace("`", "\"");
    else if (driverName == "QSQLITE" || driverName == "QSQLITE2")
        modSql.replace("LIKE ? ESCAPE '\\'", "LIKE ?");
    return modSql;
}
<commit_msg>fix SQL normalisation for tests<commit_after>/*
 * Copyright (C) 2010-2012 Jeremy Lainé
 * Contact: http://code.google.com/p/qdjango/
 *
 * This file is part of the QDjango Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#include <cstdlib>

#include "QDjango.h"

#include "util.h"

bool initialiseDatabase()
{
    char *p;

    // enable SQL debugging
    if ((p = getenv("QDJANGO_DB_DEBUG")) != 0)
        QDjango::setDebugEnabled(true);

    // open database
    QString databaseDriver = "QSQLITE";
    if ((p = getenv("QDJANGO_DB_DRIVER")) != 0)
        databaseDriver = QString::fromLocal8Bit(p);
    QSqlDatabase db = QSqlDatabase::addDatabase(databaseDriver);

    if ((p = getenv("QDJANGO_DB_NAME")) != 0)
        db.setDatabaseName(QString::fromLocal8Bit(p));
    else if (databaseDriver == "QSQLITE")
        db.setDatabaseName(":memory:");

    if ((p = getenv("QDJANGO_DB_USER")) != 0)
        db.setUserName(QString::fromLocal8Bit(p));

    if ((p = getenv("QDJANGO_DB_PASSWORD")) != 0)
        db.setPassword(QString::fromLocal8Bit(p));

    if ((p = getenv("QDJANGO_DB_HOST")) != 0)
        db.setHostName(QString::fromLocal8Bit(p));

    if (db.open()) {
        QDjango::setDatabase(db);
        return true;
    } else {
        return false;
    }
}

QString normalizeSql(const QSqlDatabase &db, const QString &sql)
{
    const QString driverName = db.driverName();
    QString modSql(sql);
    if (driverName == "QMYSQL")
        modSql.replace("`", "\"");
    else if (driverName == "QSQLITE" || driverName == "QSQLITE2")
        modSql.replace("? ESCAPE '\\'", "?");
    return modSql;
}
<|endoftext|>