<commit_before>#include "stdafx.hpp"

#include <cfloat>

#include <CppUnitTest.h>
#include <functional>

#include "Geometry/Grassmann.hpp"
#include "Geometry/R3Element.hpp"
#include "Quantities/Astronomy.hpp"
#include "Quantities/BIPM.hpp"
#include "Quantities/Constants.hpp"
#include "Quantities/Dimensionless.hpp"
#include "Quantities/ElementaryFunctions.hpp"
#include "Quantities/Quantities.hpp"
#include "Quantities/SI.hpp"
#include "Quantities/UK.hpp"
#include "TestUtilities/Algebra.hpp"
#include "TestUtilities/GeometryComparisons.hpp"
#include "TestUtilities/QuantityComparisons.hpp"
#include "TestUtilities/TestUtilities.hpp"

namespace principia {
namespace geometry {

using namespace astronomy;
using namespace bipm;
using namespace constants;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace quantities;
using namespace si;
using namespace test_utilities;
using namespace uk;

TEST_CLASS(GrassmannTests) {
 public:
  struct World;
  R3Element<Length> const null_displacement_ =
      R3Element<Length>(0 * Metre, 0 * Metre, 0 * Metre);
  R3Element<Length> const u_ =
      R3Element<Length>(3 * Metre, -42 * Metre, 0 * Metre);
  R3Element<Length> const v_ =
      R3Element<Length>(-π * Metre, -e * Metre, -1 * Metre);
  R3Element<Length> const w_ =
      R3Element<Length>(2 * Metre, 2 * Metre, 2 * Metre);
  R3Element<Length> const a_ =
      R3Element<Length>(1 * Inch, 2 * Foot, 3 * admiralty::Fathom);

  template<typename LScalar, typename RScalar, typename Frame, int Rank>
  static Product<LScalar, RScalar> MultivectorInnerProduct(
      Multivector<LScalar, Frame, Rank> const& left,
      Multivector<RScalar, Frame, Rank> const& right) {
    return InnerProduct(left, right);
  }

  TEST_METHOD(SpecialOrthogonalLieAlgebra) {
    TestLieBracket(Commutator<Dimensionless, Dimensionless, World>,
                   Bivector<Dimensionless, World>(u_ / Foot),
                   Bivector<Dimensionless, World>(v_ / Metre),
                   Bivector<Dimensionless, World>(w_ / Rod),
                   Bivector<Dimensionless, World>(a_ / Furlong),
                   Dimensionless(0.42), 3e-14);
  }

  TEST_METHOD(VectorSpaces) {
    TestInnerProductSpace(MultivectorInnerProduct<Length, Length, World, 1>,
                          Vector<Length, World>(null_displacement_),
                          Vector<Length, World>(u_),
                          Vector<Length, World>(v_),
                          Vector<Length, World>(w_),
                          Vector<Length, World>(a_),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2), 12 * DBL_EPSILON);
    TestInnerProductSpace(MultivectorInnerProduct<Length, Length, World, 2>,
                          Bivector<Length, World>(null_displacement_),
                          Bivector<Length, World>(u_),
                          Bivector<Length, World>(v_),
                          Bivector<Length, World>(w_),
                          Bivector<Length, World>(a_),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2), 12 * DBL_EPSILON);
    TestInnerProductSpace(MultivectorInnerProduct<Length, Length, World, 3>,
                          Trivector<Length, World>(null_displacement_.x),
                          Trivector<Length, World>(u_.y),
                          Trivector<Length, World>(v_.z),
                          Trivector<Length, World>(w_.x),
                          Trivector<Length, World>(a_.y),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2));
    TestInnerProductSpace(MultivectorInnerProduct<Dimensionless, Dimensionless,
                                                  World, 1>,
                          Vector<Dimensionless,
                                 World>(null_displacement_ / Metre),
                          Vector<Dimensionless, World>(u_ / Metre),
                          Vector<Dimensionless, World>(v_ / Metre),
                          Vector<Dimensionless, World>(w_ / Metre),
                          Vector<Dimensionless, World>(a_ / Metre),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2), 12 * DBL_EPSILON);
    TestInnerProductSpace(MultivectorInnerProduct<Dimensionless, Dimensionless,
                                                  World, 2>,
                          Bivector<Dimensionless,
                                   World>(null_displacement_ / Metre),
                          Bivector<Dimensionless, World>(u_ / Metre),
                          Bivector<Dimensionless, World>(v_ / Metre),
                          Bivector<Dimensionless, World>(w_ / Metre),
                          Bivector<Dimensionless, World>(a_ / Metre),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2), 12 * DBL_EPSILON);
    TestInnerProductSpace(MultivectorInnerProduct<Dimensionless, Dimensionless,
                                                  World, 3>,
                          Trivector<Dimensionless,
                                    World>(null_displacement_.x / Metre),
                          Trivector<Dimensionless, World>(u_.y / Metre),
                          Trivector<Dimensionless, World>(v_.z / Metre),
                          Trivector<Dimensionless, World>(w_.x / Metre),
                          Trivector<Dimensionless, World>(a_.y / Metre),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2));
  }

  TEST_METHOD(GrassmannAlgebra) {
    R3Element<Dimensionless> u(3, -42, 0);
    R3Element<Dimensionless> v(-π, -e, -1);
    R3Element<Dimensionless> w(2, 2, 2);
    R3Element<Dimensionless> a(1.2, 2.3, 3.4);
    auto vectorWedge = [](Vector<Dimensionless, World> a,
                          Vector<Dimensionless, World> b) {
        return Wedge(a, b);
      };
    TestAlternatingBilinearMap(vectorWedge, Vector<Dimensionless, World>(u),
                               Vector<Dimensionless, World>(u),
                               Vector<Dimensionless, World>(u),
                               Vector<Dimensionless, World>(u),
                               Dimensionless(6 * 9));
  }
};

}  // namespace geometry
}  // namespace principia
<commit_msg>Use DBL_EPSILON in the lie algebra test.<commit_after>#include "stdafx.hpp"

#include <cfloat>

#include <CppUnitTest.h>
#include <functional>

#include "Geometry/Grassmann.hpp"
#include "Geometry/R3Element.hpp"
#include "Quantities/Astronomy.hpp"
#include "Quantities/BIPM.hpp"
#include "Quantities/Constants.hpp"
#include "Quantities/Dimensionless.hpp"
#include "Quantities/ElementaryFunctions.hpp"
#include "Quantities/Quantities.hpp"
#include "Quantities/SI.hpp"
#include "Quantities/UK.hpp"
#include "TestUtilities/Algebra.hpp"
#include "TestUtilities/GeometryComparisons.hpp"
#include "TestUtilities/QuantityComparisons.hpp"
#include "TestUtilities/TestUtilities.hpp"

namespace principia {
namespace geometry {

using namespace astronomy;
using namespace bipm;
using namespace constants;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace quantities;
using namespace si;
using namespace test_utilities;
using namespace uk;

TEST_CLASS(GrassmannTests) {
 public:
  struct World;
  R3Element<Length> const null_displacement_ =
      R3Element<Length>(0 * Metre, 0 * Metre, 0 * Metre);
  R3Element<Length> const u_ =
      R3Element<Length>(3 * Metre, -42 * Metre, 0 * Metre);
  R3Element<Length> const v_ =
      R3Element<Length>(-π * Metre, -e * Metre, -1 * Metre);
  R3Element<Length> const w_ =
      R3Element<Length>(2 * Metre, 2 * Metre, 2 * Metre);
  R3Element<Length> const a_ =
      R3Element<Length>(1 * Inch, 2 * Foot, 3 * admiralty::Fathom);

  template<typename LScalar, typename RScalar, typename Frame, int Rank>
  static Product<LScalar, RScalar> MultivectorInnerProduct(
      Multivector<LScalar, Frame, Rank> const& left,
      Multivector<RScalar, Frame, Rank> const& right) {
    return InnerProduct(left, right);
  }

  TEST_METHOD(SpecialOrthogonalLieAlgebra) {
    TestLieBracket(Commutator<Dimensionless, Dimensionless, World>,
                   Bivector<Dimensionless, World>(u_ / Foot),
                   Bivector<Dimensionless, World>(v_ / Metre),
                   Bivector<Dimensionless, World>(w_ / Rod),
                   Bivector<Dimensionless, World>(a_ / Furlong),
                   Dimensionless(0.42), 128 * DBL_EPSILON);
  }

  TEST_METHOD(VectorSpaces) {
    TestInnerProductSpace(MultivectorInnerProduct<Length, Length, World, 1>,
                          Vector<Length, World>(null_displacement_),
                          Vector<Length, World>(u_),
                          Vector<Length, World>(v_),
                          Vector<Length, World>(w_),
                          Vector<Length, World>(a_),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2), 12 * DBL_EPSILON);
    TestInnerProductSpace(MultivectorInnerProduct<Length, Length, World, 2>,
                          Bivector<Length, World>(null_displacement_),
                          Bivector<Length, World>(u_),
                          Bivector<Length, World>(v_),
                          Bivector<Length, World>(w_),
                          Bivector<Length, World>(a_),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2), 12 * DBL_EPSILON);
    TestInnerProductSpace(MultivectorInnerProduct<Length, Length, World, 3>,
                          Trivector<Length, World>(null_displacement_.x),
                          Trivector<Length, World>(u_.y),
                          Trivector<Length, World>(v_.z),
                          Trivector<Length, World>(w_.x),
                          Trivector<Length, World>(a_.y),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2));
    TestInnerProductSpace(MultivectorInnerProduct<Dimensionless, Dimensionless,
                                                  World, 1>,
                          Vector<Dimensionless,
                                 World>(null_displacement_ / Metre),
                          Vector<Dimensionless, World>(u_ / Metre),
                          Vector<Dimensionless, World>(v_ / Metre),
                          Vector<Dimensionless, World>(w_ / Metre),
                          Vector<Dimensionless, World>(a_ / Metre),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2), 12 * DBL_EPSILON);
    TestInnerProductSpace(MultivectorInnerProduct<Dimensionless, Dimensionless,
                                                  World, 2>,
                          Bivector<Dimensionless,
                                   World>(null_displacement_ / Metre),
                          Bivector<Dimensionless, World>(u_ / Metre),
                          Bivector<Dimensionless, World>(v_ / Metre),
                          Bivector<Dimensionless, World>(w_ / Metre),
                          Bivector<Dimensionless, World>(a_ / Metre),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2), 12 * DBL_EPSILON);
    TestInnerProductSpace(MultivectorInnerProduct<Dimensionless, Dimensionless,
                                                  World, 3>,
                          Trivector<Dimensionless,
                                    World>(null_displacement_.x / Metre),
                          Trivector<Dimensionless, World>(u_.y / Metre),
                          Trivector<Dimensionless, World>(v_.z / Metre),
                          Trivector<Dimensionless, World>(w_.x / Metre),
                          Trivector<Dimensionless, World>(a_.y / Metre),
                          Dimensionless(0), Dimensionless(1), Sqrt(163),
                          -Sqrt(2));
  }

  TEST_METHOD(GrassmannAlgebra) {
    R3Element<Dimensionless> u(3, -42, 0);
    R3Element<Dimensionless> v(-π, -e, -1);
    R3Element<Dimensionless> w(2, 2, 2);
    R3Element<Dimensionless> a(1.2, 2.3, 3.4);
    auto vectorWedge = [](Vector<Dimensionless, World> a,
                          Vector<Dimensionless, World> b) {
        return Wedge(a, b);
      };
    TestAlternatingBilinearMap(vectorWedge, Vector<Dimensionless, World>(u),
                               Vector<Dimensionless, World>(u),
                               Vector<Dimensionless, World>(u),
                               Vector<Dimensionless, World>(u),
                               Dimensionless(6 * 9));
  }
};

}  // namespace geometry
}  // namespace principia
<|endoftext|>


<commit_before>/*
** Copyright 2013,2015 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/io/events.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::io;

// Class instance.
static events* _instance(NULL);

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Get class instance.
 *
 *  @return Class instance.
 */
events& events::instance() {
  return (*_instance);
}

/**
 *  Load singleton.
 */
void events::load() {
  if (!_instance)
    _instance = new events;
  return ;
}

/**
 *  Unload singleton.
 */
void events::unload() {
  // Delete operator is NULL-aware.
  delete _instance;
  _instance = NULL;
  return ;
}

/**
 *  Register a category.
 *
 *  @param[in] name  Categoy name.
 *  @param[in] hint  Whished category ID.
 *
 *  @return Assigned category ID. This could be different than hint.
 */
unsigned short events::register_category(
                         std::string const& name,
                         unsigned short hint) {
  if (!hint)
    ++hint;
  while (_elements.find(hint) != _elements.end()) {
    if (!++hint)
      ++hint;
  }
  _elements[hint].name = name;
  return (hint);
}

/**
 *  Unregister a category.
 *
 *  @param[in] category_id  Category ID.
 */
void events::unregister_category(unsigned short category_id) {
  categories_container::iterator it(_elements.find(category_id));
  if (it != _elements.end())
    _elements.erase(it);
  return ;
}

/**
 *  Register an event.
 *
 *  @param[in] category_id  Category ID. Category must have been
 *                          registered through register_category().
 *  @param[in] event_id     Event ID whithin the category.
 *  @param[in] info         Information about the event.
 *
 *  @return Event type ID.
 */
unsigned int events::register_event(
                       unsigned short category_id,
                       unsigned short event_id,
                       event_info const& info) {
  categories_container::iterator it(_elements.find(category_id));
  if (it == _elements.end())
    throw (exceptions::msg() << "core: could not register event '"
           << info.get_name() << "': category " << category_id
           << " was not registered");
  int type(make_type(category_id, event_id));
  it->second.events[type] = info;
  return (type);
}

/**
 *  Unregister an event.
 *
 *  @param[in] type_id  Type ID.
 */
void events::unregister_event(unsigned int type_id) {
  unsigned short category_id(category_of_type(type_id));
  categories_container::iterator itc(_elements.find(category_id));
  if (itc != _elements.end()) {
    events_container::iterator ite(itc->second.events.find(type_id));
    if (ite != itc->second.events.end())
      itc->second.events.erase(ite);
  }
  return ;
}

/**
 *  Get first iterator.
 *
 *  @return First iterator.
 */
events::categories_container::const_iterator events::begin() const {
  return (_elements.begin());
}

/**
 *  Get last iterator.
 *
 *  @return Last iterator.
 */
events::categories_container::const_iterator events::end() const {
  return (_elements.end());
}

/**
 *  Get the content of a category.
 *
 *  @param[in] name  Category name.
 *
 *  @return Category elements.
 */
events::events_container events::get_events_by_category_name(
                                   std::string const& name) const {
  // Special category matching all registered events.
  if (name == "all") {
    events::events_container all;
    for (categories_container::const_iterator
           it1(_elements.begin()), end1(_elements.end());
         it1 != end1;
         ++it1)
      for (events_container::const_iterator
             it2(it1->second.events.begin()),
             end2(it1->second.events.end());
           it2 != end2;
           ++it2)
        all.insert(*it2);
    return (all);
  }
  // Category name.
  else {
    for (categories_container::const_iterator
           it(_elements.begin()), end(_elements.end());
         it != end;
         ++it) {
      if (it->second.name == name)
        return (it->second.events);
    }
  }
  throw (exceptions::msg() << "core: cannot find event category '"
         << name << "'");
}

/**
 *  Get an event information structure.
 *
 *  @param[in] type  Event type ID.
 *
 *  @return Event information structure if found, NULL otherwise.
 */
event_info const* events::get_event_info(unsigned int type) {
  umap<unsigned short, category_info>::const_iterator
    itc(_elements.find(category_of_type(type)));
  if (itc != _elements.end()) {
    umap<unsigned int, event_info>::const_iterator
      ite(itc->second.events.find(type));
    if (ite != itc->second.events.end())
      return (&ite->second);
  }
  return (NULL);
}

/**
 *  Get all the events matching this name.
 *
 *  If it's a category name, get the content of the category.
 *  If it's a category name followed by : and the name of an event,
 *  get this event.
 *
 *  @param[in] name  The name.
 *
 *  @return  A list of all the matching events.
 */
events::events_container events::get_matching_events(
                                   std::string const& name) const {
  // Ignore internal category.
  if (name.compare(0, ::strlen("internal"), "internal") == 0)
    return (events_container());

  size_t num = std::count(name.begin(), name.end(), ':');
  if (num == 0)
    return (get_events_by_category_name(name));
  else if (num == 1) {
    size_t place = name.find_first_of(':');
    std::string category_name = name.substr(0, place);
    events::events_container const &events = get_events_by_category_name(
                                               category_name);
    std::string event_name = name.substr(place + 1);
    for (events::events_container::const_iterator
           it(events.begin()),
           end(events.end());
         it != end;
         ++it) {
      if (it->second.get_name() == event_name) {
        events::events_container res;
        res[it->first] = it->second;
        return (res);
      }
    }
    throw (exceptions::msg() << "core: cannot find event '"
           << event_name << "' in '" << name << "'");
  }
  else
    throw (exceptions::msg() << "core: too many ':' in '"
           << name << "'");
}

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Default constructor.
 */
events::events() {
  // Register internal category.
  register_category("internal", io::events::internal);
}

/**
 *  Destructor.
 */
events::~events() {
  unregister_category(io::events::internal);
}
<commit_msg>Core: remove internal category mishap.<commit_after>/*
** Copyright 2013,2015 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/io/events.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::io;

// Class instance.
static events* _instance(NULL);

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Get class instance.
 *
 *  @return Class instance.
 */
events& events::instance() {
  return (*_instance);
}

/**
 *  Load singleton.
 */
void events::load() {
  if (!_instance)
    _instance = new events;
  return ;
}

/**
 *  Unload singleton.
 */
void events::unload() {
  // Delete operator is NULL-aware.
  delete _instance;
  _instance = NULL;
  return ;
}

/**
 *  Register a category.
 *
 *  @param[in] name  Categoy name.
 *  @param[in] hint  Whished category ID.
 *
 *  @return Assigned category ID. This could be different than hint.
 */
unsigned short events::register_category(
                         std::string const& name,
                         unsigned short hint) {
  if (!hint)
    ++hint;
  while (_elements.find(hint) != _elements.end()) {
    if (!++hint)
      ++hint;
  }
  _elements[hint].name = name;
  return (hint);
}

/**
 *  Unregister a category.
 *
 *  @param[in] category_id  Category ID.
 */
void events::unregister_category(unsigned short category_id) {
  categories_container::iterator it(_elements.find(category_id));
  if (it != _elements.end())
    _elements.erase(it);
  return ;
}

/**
 *  Register an event.
 *
 *  @param[in] category_id  Category ID. Category must have been
 *                          registered through register_category().
 *  @param[in] event_id     Event ID whithin the category.
 *  @param[in] info         Information about the event.
 *
 *  @return Event type ID.
 */
unsigned int events::register_event(
                       unsigned short category_id,
                       unsigned short event_id,
                       event_info const& info) {
  categories_container::iterator it(_elements.find(category_id));
  if (it == _elements.end())
    throw (exceptions::msg() << "core: could not register event '"
           << info.get_name() << "': category " << category_id
           << " was not registered");
  int type(make_type(category_id, event_id));
  it->second.events[type] = info;
  return (type);
}

/**
 *  Unregister an event.
 *
 *  @param[in] type_id  Type ID.
 */
void events::unregister_event(unsigned int type_id) {
  unsigned short category_id(category_of_type(type_id));
  categories_container::iterator itc(_elements.find(category_id));
  if (itc != _elements.end()) {
    events_container::iterator ite(itc->second.events.find(type_id));
    if (ite != itc->second.events.end())
      itc->second.events.erase(ite);
  }
  return ;
}

/**
 *  Get first iterator.
 *
 *  @return First iterator.
 */
events::categories_container::const_iterator events::begin() const {
  return (_elements.begin());
}

/**
 *  Get last iterator.
 *
 *  @return Last iterator.
 */
events::categories_container::const_iterator events::end() const {
  return (_elements.end());
}

/**
 *  Get the content of a category.
 *
 *  @param[in] name  Category name.
 *
 *  @return Category elements.
 */
events::events_container events::get_events_by_category_name(
                                   std::string const& name) const {
  // Special category matching all registered events.
  if (name == "all") {
    events::events_container all;
    for (categories_container::const_iterator
           it1(_elements.begin()), end1(_elements.end());
         it1 != end1;
         ++it1)
      for (events_container::const_iterator
             it2(it1->second.events.begin()),
             end2(it1->second.events.end());
           it2 != end2;
           ++it2)
        all.insert(*it2);
    return (all);
  }
  // Category name.
  else {
    for (categories_container::const_iterator
           it(_elements.begin()), end(_elements.end());
         it != end;
         ++it) {
      if (it->second.name == name)
        return (it->second.events);
    }
  }
  throw (exceptions::msg() << "core: cannot find event category '"
         << name << "'");
}

/**
 *  Get an event information structure.
 *
 *  @param[in] type  Event type ID.
 *
 *  @return Event information structure if found, NULL otherwise.
 */
event_info const* events::get_event_info(unsigned int type) {
  umap<unsigned short, category_info>::const_iterator
    itc(_elements.find(category_of_type(type)));
  if (itc != _elements.end()) {
    umap<unsigned int, event_info>::const_iterator
      ite(itc->second.events.find(type));
    if (ite != itc->second.events.end())
      return (&ite->second);
  }
  return (NULL);
}

/**
 *  Get all the events matching this name.
 *
 *  If it's a category name, get the content of the category.
 *  If it's a category name followed by : and the name of an event,
 *  get this event.
 *
 *  @param[in] name  The name.
 *
 *  @return  A list of all the matching events.
 */
events::events_container events::get_matching_events(
                                   std::string const& name) const {
  size_t num = std::count(name.begin(), name.end(), ':');
  if (num == 0)
    return (get_events_by_category_name(name));
  else if (num == 1) {
    size_t place = name.find_first_of(':');
    std::string category_name = name.substr(0, place);
    events::events_container const &events = get_events_by_category_name(
                                               category_name);
    std::string event_name = name.substr(place + 1);
    for (events::events_container::const_iterator
           it(events.begin()),
           end(events.end());
         it != end;
         ++it) {
      if (it->second.get_name() == event_name) {
        events::events_container res;
        res[it->first] = it->second;
        return (res);
      }
    }
    throw (exceptions::msg() << "core: cannot find event '"
           << event_name << "' in '" << name << "'");
  }
  else
    throw (exceptions::msg() << "core: too many ':' in '"
           << name << "'");
}

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Default constructor.
 */
events::events() {
  // Register internal category.
  register_category("internal", io::events::internal);
}

/**
 *  Destructor.
 */
events::~events() {
  unregister_category(io::events::internal);
}
<|endoftext|>


<commit_before>#include "amuse/AudioGroupData.hpp"

namespace amuse
{

IntrusiveAudioGroupData::~IntrusiveAudioGroupData()
{
    if (m_owns)
    {
        delete m_pool;
        delete m_proj;
        delete m_sdir;
        delete m_samp;
    }
}

IntrusiveAudioGroupData::IntrusiveAudioGroupData(IntrusiveAudioGroupData&& other)
: AudioGroupData(other.m_proj, other.m_pool, other.m_sdir, other.m_samp, other.m_fmt)
{
    m_owns = other.m_owns;
    other.m_owns = false;
}

IntrusiveAudioGroupData& IntrusiveAudioGroupData::operator=(IntrusiveAudioGroupData&& other)
{
    if (m_owns)
    {
        delete m_pool;
        delete m_proj;
        delete m_sdir;
        delete m_samp;
    }

    m_owns = other.m_owns;
    other.m_owns = false;

    m_proj = other.m_proj;
    m_pool = other.m_pool;
    m_sdir = other.m_sdir;
    m_samp = other.m_samp;

    return *this;
}

}
<commit_msg>Update AudioGroupData.cpp<commit_after>#include "amuse/AudioGroupData.hpp"

namespace amuse
{

IntrusiveAudioGroupData::~IntrusiveAudioGroupData()
{
    if (m_owns)
    {
        delete m_pool;
        delete m_proj;
        delete m_sdir;
        delete m_samp;
    }
}

IntrusiveAudioGroupData::IntrusiveAudioGroupData(IntrusiveAudioGroupData&& other)
: AudioGroupData(other.m_proj, other.m_pool, other.m_sdir, other.m_samp, other.m_fmt)
{
    m_owns = other.m_owns;
    other.m_owns = false;
}

IntrusiveAudioGroupData& IntrusiveAudioGroupData::operator=(IntrusiveAudioGroupData&& other)
{
    if (m_owns)
    {
        delete m_pool;
        delete m_proj;
        delete m_sdir;
        delete m_samp;
    }

    m_owns = other.m_owns;
    other.m_owns = false;

    m_proj = other.m_proj;
    m_pool = other.m_pool;
    m_sdir = other.m_sdir;
    m_samp = other.m_samp;
    m_fmt = other.m_fmt;

    return *this;
}

}
<|endoftext|>


<commit_before>#include "utils.hpp"
#include "libdnf/dnf-sack-private.hpp"
#include "libdnf/sack/advisorymodule.hpp"

#include <tinyformat/tinyformat.hpp>

#include <algorithm>
#include <sys/stat.h>
#include <dirent.h>
#include <cstring>
#include <stdexcept>

extern "C" {
#include <solv/solv_xfopen.h>
};

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

namespace libdnf {

bool isAdvisoryApplicable(libdnf::Advisory & advisory, DnfSack * sack)
{
    auto moduleContainer = dnf_sack_get_module_container(sack);
    if (!moduleContainer) {
        return true;
    }
    auto moduleAdvisories = advisory.getModules();
    if (moduleAdvisories.empty()) {
        return true;
    }
    for (auto & moduleAdvisory: moduleAdvisories) {
        if (const char * name = moduleAdvisory.getName()) {
            if (const char * stream = moduleAdvisory.getStream()) {
                try {
                    if (moduleContainer->isEnabled(name, stream)) {
                        return true;
                    }
                } catch (std::out_of_range &) {
                    continue;
                }
            }
        }
    }
    return false;
}

namespace string {

std::vector<std::string> split(const std::string &source, const char *delimiter, int maxSplit)
{
    if (source.empty())
        throw std::runtime_error{"Source cannot be empty"};

    std::string::size_type tokenBeginIndex = 0;
    std::vector<std::string> container;

    while ((tokenBeginIndex = source.find_first_not_of(delimiter, tokenBeginIndex)) != source.npos) {
        if (maxSplit != -1 && ((int) (container.size() + 1 )) == maxSplit) {
            container.emplace_back(source.substr(tokenBeginIndex));
            break;
        }

        auto tokenEndIndex = source.find_first_of(delimiter, tokenBeginIndex);
        container.emplace_back(source.substr(tokenBeginIndex, tokenEndIndex - tokenBeginIndex));
        tokenBeginIndex = tokenEndIndex;
    }

    if (container.empty()) {
        throw std::runtime_error{"No delimiter found in source: " + source};
    }

    return container;
}

std::vector<std::string> rsplit(const std::string &source, const char *delimiter, int maxSplit)
{
    if (source.empty())
        throw std::runtime_error{"Source cannot be empty"};

    std::string sequence = source;
    std::string::size_type tokenBeginIndex = 0;
    std::vector<std::string> container;

    while ((tokenBeginIndex = sequence.find_last_of(delimiter)) != sequence.npos) {
        if (maxSplit != -1 && ((int) (container.size() + 1 )) == maxSplit) {
            container.emplace_back(source.substr(0, tokenBeginIndex));
            break;
        }

        container.emplace(container.begin(), source.substr(tokenBeginIndex + 1));
        sequence = sequence.substr(0, tokenBeginIndex);
    }

    if (container.empty()) {
        throw std::runtime_error{"No delimiter found in source: " + source};
    }

    return container;
}

std::string trimSuffix(const std::string &source, const std::string &suffix)
{
    if (source.length() < suffix.length())
        throw std::runtime_error{"Suffix cannot be longer than source"};

    if (endsWith(source, suffix))
        return source.substr(0, source.length() - suffix.length());

    throw std::runtime_error{"Suffix '" + suffix + "' not found"};
}

std::string trimPrefix(const std::string &source, const std::string &prefix)
{
    if (source.length() < prefix.length())
        throw std::runtime_error{"Prefix cannot be longer than source"};

    if (startsWith(source, prefix))
        return source.substr(prefix.length() - 1);

    throw std::runtime_error{"Prefix '" + prefix + "' not found"};
}

bool startsWith(const std::string &source, const std::string &toMatch)
{
    return source.find(toMatch) == 0;
}

bool endsWith(const std::string &source, const std::string &toMatch)
{
    auto it = toMatch.begin();
    return source.size() >= toMatch.size() &&
           std::all_of(std::next(source.begin(), source.size() - toMatch.size()), source.end(), [&it](const char &c) {
               return c == *(it++);
           });
}

}

bool haveFilesSameContent(const char * filePath1, const char * filePath2)
{
    static constexpr int BLOCK_SIZE = 4096;
    bool ret = false;
    int fd1 = -1;
    int fd2 = -1;
    do {
        if ((fd1 = open(filePath1, 0)) == -1)
            break;
        if ((fd2 = open(filePath2, 0)) == -1)
            break;
        auto len1 = lseek(fd1, 0, SEEK_END);
        auto len2 = lseek(fd2, 0, SEEK_END);
        if (len1 != len2)
            break;
        ret = true;
        if (len1 == 0)
            break;
        lseek(fd1, 0, SEEK_SET);
        lseek(fd2, 0, SEEK_SET);
        char buf1[BLOCK_SIZE], buf2[BLOCK_SIZE];
        ssize_t readed;
        do {
            readed = read(fd1, buf1, BLOCK_SIZE);
            auto readed2 = read(fd2, buf2, BLOCK_SIZE);
            if (readed2 != readed || memcmp(buf1, buf2, readed) != 0) {
                ret = false;
                break;
            }
        } while (readed > BLOCK_SIZE);
    } while (false);

    if (fd1 != -1)
        close(fd1);
    if (fd2 != -1)
        close(fd2);
    return ret;
}

namespace filesystem {

bool exists(const std::string &name)
{
    struct stat buffer;
    return stat(name.c_str(), &buffer) == 0;
}

bool isDIR(const std::string& dirPath)
{
    struct stat buf;
    lstat(dirPath.c_str(), &buf);
    return S_ISDIR(buf.st_mode);
}

std::vector<std::string> getDirContent(const std::string &dirPath)
{
    std::vector<std::string> content{};
    struct dirent *ent;
    DIR *dir = opendir(dirPath.c_str());

    if (dir != nullptr) {
        while ((ent = readdir(dir)) != nullptr) {
            if (strcmp(ent->d_name, "..") == 0 ||
                    strcmp(ent->d_name, ".") == 0 )
                continue;

            auto fullPath = dirPath;
            if (!string::endsWith(fullPath, "/"))
                fullPath += "/";
            fullPath += ent->d_name;

            content.emplace_back(fullPath);
        }
        closedir (dir);
    }

    return content;
}

void decompress(const char * inPath, const char * outPath, mode_t outMode, const char * compressType)
{
    auto inFd = open(inPath, O_RDONLY);
    if (inFd == -1)
        throw std::runtime_error(tfm::format("open: %s", strerror(errno)));
    if (!compressType)
        compressType = inPath;
    auto inFile = solv_xfopen_fd(compressType, inFd, "r");
    if (inFile == NULL) {
        close(inFd);
        throw std::runtime_error("solv_xfopen_fd: Can't open stream");
    }
    auto outFd = open(outPath, O_WRONLY | O_CREAT | O_TRUNC, outMode);
    if (outFd == -1) {
        int err = errno;
        fclose(inFile);
        throw std::runtime_error(tfm::format("open: %s", strerror(err)));
    }
    char buf[4096];
    while (auto readBytes = fread(buf, 1, sizeof(buf), inFile)) {
        auto writtenBytes = write(outFd, buf, readBytes);
        if (writtenBytes == -1) {
            int err = errno;
            close(outFd);
            fclose(inFile);
            throw std::runtime_error(tfm::format("write: %s", strerror(err)));
        }
        if (writtenBytes != static_cast<int>(readBytes)) {
            close(outFd);
            fclose(inFile);
            throw std::runtime_error("write: Problem during writing data");
        }
    }
    if (!feof(inFile)) {
        close(outFd);
        fclose(inFile);
        throw std::runtime_error("fread: Problem during reading data");
    }
    close(outFd);
    fclose(inFile);
}

}

}
<commit_msg>Change an implementation of string.startwith and endwith<commit_after>#include "utils.hpp"
#include "libdnf/dnf-sack-private.hpp"
#include "libdnf/sack/advisorymodule.hpp"

#include <tinyformat/tinyformat.hpp>

#include <algorithm>
#include <sys/stat.h>
#include <dirent.h>
#include <cstring>
#include <stdexcept>

extern "C" {
#include <solv/solv_xfopen.h>
};

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

namespace libdnf {

bool isAdvisoryApplicable(libdnf::Advisory & advisory, DnfSack * sack)
{
    auto moduleContainer = dnf_sack_get_module_container(sack);
    if (!moduleContainer) {
        return true;
    }
    auto moduleAdvisories = advisory.getModules();
    if (moduleAdvisories.empty()) {
        return true;
    }
    for (auto & moduleAdvisory: moduleAdvisories) {
        if (const char * name = moduleAdvisory.getName()) {
            if (const char * stream = moduleAdvisory.getStream()) {
                try {
                    if (moduleContainer->isEnabled(name, stream)) {
                        return true;
                    }
                } catch (std::out_of_range &) {
                    continue;
                }
            }
        }
    }
    return false;
}

namespace string {

std::vector<std::string> split(const std::string &source, const char *delimiter, int maxSplit)
{
    if (source.empty())
        throw std::runtime_error{"Source cannot be empty"};

    std::string::size_type tokenBeginIndex = 0;
    std::vector<std::string> container;

    while ((tokenBeginIndex = source.find_first_not_of(delimiter, tokenBeginIndex)) != source.npos) {
        if (maxSplit != -1 && ((int) (container.size() + 1 )) == maxSplit) {
            container.emplace_back(source.substr(tokenBeginIndex));
            break;
        }

        auto tokenEndIndex = source.find_first_of(delimiter, tokenBeginIndex);
        container.emplace_back(source.substr(tokenBeginIndex, tokenEndIndex - tokenBeginIndex));
        tokenBeginIndex = tokenEndIndex;
    }

    if (container.empty()) {
        throw std::runtime_error{"No delimiter found in source: " + source};
    }

    return container;
}

std::vector<std::string> rsplit(const std::string &source, const char *delimiter, int maxSplit)
{
    if (source.empty())
        throw std::runtime_error{"Source cannot be empty"};

    std::string sequence = source;
    std::string::size_type tokenBeginIndex = 0;
    std::vector<std::string> container;

    while ((tokenBeginIndex = sequence.find_last_of(delimiter)) != sequence.npos) {
        if (maxSplit != -1 && ((int) (container.size() + 1 )) == maxSplit) {
            container.emplace_back(source.substr(0, tokenBeginIndex));
            break;
        }

        container.emplace(container.begin(), source.substr(tokenBeginIndex + 1));
        sequence = sequence.substr(0, tokenBeginIndex);
    }

    if (container.empty()) {
        throw std::runtime_error{"No delimiter found in source: " + source};
    }

    return container;
}

std::string trimSuffix(const std::string &source, const std::string &suffix)
{
    if (source.length() < suffix.length())
        throw std::runtime_error{"Suffix cannot be longer than source"};

    if (endsWith(source, suffix))
        return source.substr(0, source.length() - suffix.length());

    throw std::runtime_error{"Suffix '" + suffix + "' not found"};
}

std::string trimPrefix(const std::string &source, const std::string &prefix)
{
    if (source.length() < prefix.length())
        throw std::runtime_error{"Prefix cannot be longer than source"};

    if (startsWith(source, prefix))
        return source.substr(prefix.length() - 1);

    throw std::runtime_error{"Prefix '" + prefix + "' not found"};
}

bool startsWith(const std::string & source, const std::string & toMatch)
{
    return source.compare(0, toMatch.size(), toMatch) == 0;
}

bool endsWith(const std::string & source, const std::string & toMatch)
{
    auto toMatchSize = toMatch.size();
    return source.size() >= toMatchSize && source.compare(
        source.size() - toMatchSize, toMatchSize, toMatch) == 0;
}

}

bool haveFilesSameContent(const char * filePath1, const char * filePath2)
{
    static constexpr int BLOCK_SIZE = 4096;
    bool ret = false;
    int fd1 = -1;
    int fd2 = -1;
    do {
        if ((fd1 = open(filePath1, 0)) == -1)
            break;
        if ((fd2 = open(filePath2, 0)) == -1)
            break;
        auto len1 = lseek(fd1, 0, SEEK_END);
        auto len2 = lseek(fd2, 0, SEEK_END);
        if (len1 != len2)
            break;
        ret = true;
        if (len1 == 0)
            break;
        lseek(fd1, 0, SEEK_SET);
        lseek(fd2, 0, SEEK_SET);
        char buf1[BLOCK_SIZE], buf2[BLOCK_SIZE];
        ssize_t readed;
        do {
            readed = read(fd1, buf1, BLOCK_SIZE);
            auto readed2 = read(fd2, buf2, BLOCK_SIZE);
            if (readed2 != readed || memcmp(buf1, buf2, readed) != 0) {
                ret = false;
                break;
            }
        } while (readed > BLOCK_SIZE);
    } while (false);

    if (fd1 != -1)
        close(fd1);
    if (fd2 != -1)
        close(fd2);
    return ret;
}

namespace filesystem {

bool exists(const std::string &name)
{
    struct stat buffer;
    return stat(name.c_str(), &buffer) == 0;
}

bool isDIR(const std::string& dirPath)
{
    struct stat buf;
    lstat(dirPath.c_str(), &buf);
    return S_ISDIR(buf.st_mode);
}

std::vector<std::string> getDirContent(const std::string &dirPath)
{
    std::vector<std::string> content{};
    struct dirent *ent;
    DIR *dir = opendir(dirPath.c_str());

    if (dir != nullptr) {
        while ((ent = readdir(dir)) != nullptr) {
            if (strcmp(ent->d_name, "..") == 0 ||
                    strcmp(ent->d_name, ".") == 0 )
                continue;

            auto fullPath = dirPath;
            if (!string::endsWith(fullPath, "/"))
                fullPath += "/";
            fullPath += ent->d_name;

            content.emplace_back(fullPath);
        }
        closedir (dir);
    }

    return content;
}

void decompress(const char * inPath, const char * outPath, mode_t outMode, const char * compressType)
{
    auto inFd = open(inPath, O_RDONLY);
    if (inFd == -1)
        throw std::runtime_error(tfm::format("open: %s", strerror(errno)));
    if (!compressType)
        compressType = inPath;
    auto inFile = solv_xfopen_fd(compressType, inFd, "r");
    if (inFile == NULL) {
        close(inFd);
        throw std::runtime_error("solv_xfopen_fd: Can't open stream");
    }
    auto outFd = open(outPath, O_WRONLY | O_CREAT | O_TRUNC, outMode);
    if (outFd == -1) {
        int err = errno;
        fclose(inFile);
        throw std::runtime_error(tfm::format("open: %s", strerror(err)));
    }
    char buf[4096];
    while (auto readBytes = fread(buf, 1, sizeof(buf), inFile)) {
        auto writtenBytes = write(outFd, buf, readBytes);
        if (writtenBytes == -1) {
            int err = errno;
            close(outFd);
            fclose(inFile);
            throw std::runtime_error(tfm::format("write: %s", strerror(err)));
        }
        if (writtenBytes != static_cast<int>(readBytes)) {
            close(outFd);
            fclose(inFile);
            throw std::runtime_error("write: Problem during writing data");
        }
    }
    if (!feof(inFile)) {
        close(outFd);
        fclose(inFile);
        throw std::runtime_error("fread: Problem during reading data");
    }
    close(outFd);
    fclose(inFile);
}

}

}
<|endoftext|>


<commit_before>/*
 * GStreamer
 * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <GL/gl.h>
#include <GL/glu.h>
#if __WIN32__ || _WIN32
# include <GL/glext.h>
#endif
#include <gst/gst.h>

#include <iostream>
#include <string>

static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
    GMainLoop *loop = (GMainLoop*)data;

    switch (GST_MESSAGE_TYPE (msg))
    {
        case GST_MESSAGE_EOS:
              g_print ("End-of-stream\n");
              g_main_loop_quit (loop);
              break;
        case GST_MESSAGE_ERROR:
          {
              gchar *debug = NULL;
              GError *err = NULL;

              gst_message_parse_error (msg, &err, &debug);

              g_print ("Error: %s\n", err->message);
              g_error_free (err);

              if (debug)
              {
                  g_print ("Debug deails: %s\n", debug);
                  g_free (debug);
              }

              g_main_loop_quit (loop);
              break;
          }
        default:
          break;
    }

    return TRUE;
}

//client reshape callback
void reshapeCallback (GLuint width, GLuint height, gpointer data)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
    glMatrixMode(GL_MODELVIEW);
}

//client draw callback
gboolean drawCallback (GLuint texture, GLuint width, GLuint height, gpointer data)
{
    static GLfloat	xrot = 0;
    static GLfloat	yrot = 0;
    static GLfloat	zrot = 0;
    static GTimeVal current_time;
    static glong last_sec = current_time.tv_sec;
    static gint nbFrames = 0;

    g_get_current_time (&current_time);
    nbFrames++ ;

    if ((current_time.tv_sec - last_sec) >= 1)
    {
        std::cout << "GRPHIC FPS = " << nbFrames << std::endl;
        nbFrames = 0;
        last_sec = current_time.tv_sec;
    }

    glEnable(GL_DEPTH_TEST);

    glEnable (GL_TEXTURE_RECTANGLE_ARB);
    glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
    glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glTranslatef(0.0f,0.0f,-5.0f);

    glRotatef(xrot,1.0f,0.0f,0.0f);
    glRotatef(yrot,0.0f,1.0f,0.0f);
    glRotatef(zrot,0.0f,0.0f,1.0f);

    glBegin(GL_QUADS);
	      // Front Face
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
	      glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f,  1.0f,  1.0f);
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
	      // Back Face
	      glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f,  1.0f, -1.0f);
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	      // Top Face
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
	      glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f,  1.0f, -1.0f);
	      // Bottom Face
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, -1.0f,  1.0f);
	      glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f,  1.0f);
	      // Right face
	      glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f,  1.0f, -1.0f);
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f,  1.0f,  1.0f);
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
	      // Left Face
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
    glEnd();

    xrot+=0.3f;
    yrot+=0.2f;
    zrot+=0.4f;

    //return TRUE causes a postRedisplay
    return TRUE;
}

//gst-launch-1.0 videotestsrc num_buffers=400 ! video/x-raw, width=320, height=240 !
//glgraphicmaker ! glfiltercube ! video/x-raw, width=800, height=600 ! glimagesink
gint main (gint argc, gchar *argv[])
{
    GstStateChangeReturn ret;
    GstElement *pipeline, *videosrc, *glupload, *glimagesink;

    GMainLoop *loop;
    GstBus *bus;

    /* initialization */
    gst_init (&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    /* create elements */
    pipeline = gst_pipeline_new ("pipeline");

    /* watch for messages on the pipeline's bus (note that this will only
     * work like this when a GLib main loop is running) */
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    /* create elements */
    videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc0");
    glupload  = gst_element_factory_make ("glupload", "glupload0");
    glimagesink  = gst_element_factory_make ("glimagesink", "glimagesink0");

    if (!videosrc || !glupload || !glimagesink)
    {
        g_print ("one element could not be found \n");
        return -1;
    }

    /* change video source caps */
    GstCaps *caps = gst_caps_new_simple("video/x-raw",
                                        "format", G_TYPE_STRING, "RGB",
                                        "width", G_TYPE_INT, 320,
                                        "height", G_TYPE_INT, 240,
                                        "framerate", GST_TYPE_FRACTION, 25, 1,
                                        NULL) ;

    GstCaps *outcaps = gst_caps_new_simple("video/x-raw",
                                        "width", G_TYPE_INT, 800,
                                        "height", G_TYPE_INT, 600,
                                        NULL) ;

    /* configure elements */
    g_object_set(G_OBJECT(videosrc), "num-buffers", 400, NULL);
    g_object_set(G_OBJECT(glimagesink), "client-reshape-callback", reshapeCallback, NULL);
    g_object_set(G_OBJECT(glimagesink), "client-draw-callback", drawCallback, NULL);
    g_object_set(G_OBJECT(glimagesink), "client-data", NULL, NULL);

    /* add elements */
    gst_bin_add_many (GST_BIN (pipeline), videosrc, glupload, glimagesink, NULL);

    /* link elements */
    gboolean link_ok = gst_element_link_filtered(videosrc, glupload, caps) ;
    gst_caps_unref(caps) ;
    if(!link_ok)
    {
        g_warning("Failed to link videosrc to glupload!\n") ;
        return -1 ;
    }
    link_ok = gst_element_link_filtered(glupload, glimagesink, outcaps) ;
    gst_caps_unref(outcaps) ;
    if(!link_ok)
    {
        g_warning("Failed to link glupload to glimagesink!\n") ;
        return -1 ;
    }

    /* run */
    ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
    if (ret == GST_STATE_CHANGE_FAILURE)
    {
        g_print ("Failed to start up pipeline!\n");

        /* check if there is an error message with details on the bus */
        GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
        if (msg)
        {
          GError *err = NULL;

          gst_message_parse_error (msg, &err, NULL);
          g_print ("ERROR: %s\n", err->message);
          g_error_free (err);
          gst_message_unref (msg);
        }
        return -1;
    }

    g_main_loop_run (loop);

    /* clean up */
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);

    return 0;

}
<commit_msg>tests/check/generic/cube: remove the obsolete glupload element.<commit_after>/*
 * GStreamer
 * Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <GL/gl.h>
#include <GL/glu.h>
#if __WIN32__ || _WIN32
# include <GL/glext.h>
#endif
#include <gst/gst.h>

#include <iostream>
#include <string>

static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
    GMainLoop *loop = (GMainLoop*)data;

    switch (GST_MESSAGE_TYPE (msg))
    {
        case GST_MESSAGE_EOS:
              g_print ("End-of-stream\n");
              g_main_loop_quit (loop);
              break;
        case GST_MESSAGE_ERROR:
          {
              gchar *debug = NULL;
              GError *err = NULL;

              gst_message_parse_error (msg, &err, &debug);

              g_print ("Error: %s\n", err->message);
              g_error_free (err);

              if (debug)
              {
                  g_print ("Debug deails: %s\n", debug);
                  g_free (debug);
              }

              g_main_loop_quit (loop);
              break;
          }
        default:
          break;
    }

    return TRUE;
}

//client reshape callback
void reshapeCallback (GLuint width, GLuint height, gpointer data)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
    glMatrixMode(GL_MODELVIEW);
}

//client draw callback
gboolean drawCallback (GLuint texture, GLuint width, GLuint height, gpointer data)
{
    static GLfloat	xrot = 0;
    static GLfloat	yrot = 0;
    static GLfloat	zrot = 0;
    static GTimeVal current_time;
    static glong last_sec = current_time.tv_sec;
    static gint nbFrames = 0;

    g_get_current_time (&current_time);
    nbFrames++ ;

    if ((current_time.tv_sec - last_sec) >= 1)
    {
        std::cout << "GRPHIC FPS = " << nbFrames << std::endl;
        nbFrames = 0;
        last_sec = current_time.tv_sec;
    }

    glEnable(GL_DEPTH_TEST);

    glEnable (GL_TEXTURE_RECTANGLE_ARB);
    glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
    glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glTranslatef(0.0f,0.0f,-5.0f);

    glRotatef(xrot,1.0f,0.0f,0.0f);
    glRotatef(yrot,0.0f,1.0f,0.0f);
    glRotatef(zrot,0.0f,0.0f,1.0f);

    glBegin(GL_QUADS);
	      // Front Face
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
	      glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f,  1.0f,  1.0f);
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
	      // Back Face
	      glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f,  1.0f, -1.0f);
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	      // Top Face
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
	      glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f,  1.0f, -1.0f);
	      // Bottom Face
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, -1.0f,  1.0f);
	      glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f,  1.0f);
	      // Right face
	      glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f,  1.0f, -1.0f);
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f,  1.0f,  1.0f);
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
	      // Left Face
	      glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	      glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
	      glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f,  1.0f,  1.0f);
	      glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f,  1.0f, -1.0f);
    glEnd();

    xrot+=0.3f;
    yrot+=0.2f;
    zrot+=0.4f;

    //return TRUE causes a postRedisplay
    return TRUE;
}

//gst-launch-1.0 videotestsrc num_buffers=400 ! video/x-raw, width=320, height=240 !
//glgraphicmaker ! glfiltercube ! video/x-raw, width=800, height=600 ! glimagesink
gint main (gint argc, gchar *argv[])
{
    GstStateChangeReturn ret;
    GstElement *pipeline, *videosrc, *glimagesink;

    GMainLoop *loop;
    GstBus *bus;

    /* initialization */
    gst_init (&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    /* create elements */
    pipeline = gst_pipeline_new ("pipeline");

    /* watch for messages on the pipeline's bus (note that this will only
     * work like this when a GLib main loop is running) */
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    /* create elements */
    videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc0");
    glimagesink  = gst_element_factory_make ("glimagesink", "glimagesink0");

    if (!videosrc || !glimagesink)
    {
        g_print ("one element could not be found \n");
        return -1;
    }

    /* change video source caps */
    GstCaps *caps = gst_caps_new_simple("video/x-raw",
                                        "format", G_TYPE_STRING, "RGB",
                                        "width", G_TYPE_INT, 320,
                                        "height", G_TYPE_INT, 240,
                                        "framerate", GST_TYPE_FRACTION, 25, 1,
                                        NULL) ;

    /* configure elements */
    g_object_set(G_OBJECT(videosrc), "num-buffers", 400, NULL);
    g_object_set(G_OBJECT(glimagesink), "client-reshape-callback", reshapeCallback, NULL);
    g_object_set(G_OBJECT(glimagesink), "client-draw-callback", drawCallback, NULL);
    g_object_set(G_OBJECT(glimagesink), "client-data", NULL, NULL);

    /* add elements */
    gst_bin_add_many (GST_BIN (pipeline), videosrc, glimagesink, NULL);

    /* link elements */
    gboolean link_ok = gst_element_link_filtered(videosrc, glimagesink, caps) ;
    gst_caps_unref(caps) ;
    if(!link_ok)
    {
        g_warning("Failed to link videosrc to glimagesink!\n") ;
        return -1 ;
    }

    /* run */
    ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
    if (ret == GST_STATE_CHANGE_FAILURE)
    {
        g_print ("Failed to start up pipeline!\n");

        /* check if there is an error message with details on the bus */
        GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
        if (msg)
        {
          GError *err = NULL;

          gst_message_parse_error (msg, &err, NULL);
          g_print ("ERROR: %s\n", err->message);
          g_error_free (err);
          gst_message_unref (msg);
        }
        return -1;
    }

    g_main_loop_run (loop);

    /* clean up */
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);

    return 0;

}
<|endoftext|>


<commit_before>// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s

struct A { void operator delete(void*,__typeof(sizeof(int))); int x; };
void a(A* x) { delete x; }

// CHECK: call void @_ZN1AdlEPvj(i8* %0, i32 4)
<commit_msg>Fix for Release-Assert.<commit_after>// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s

struct A { void operator delete(void*,__typeof(sizeof(int))); int x; };
void a(A* x) { delete x; }

// CHECK: call void @_ZN1AdlEPvj(i8* %{{.*}}, i32 4)
<|endoftext|>


<commit_before>//Copyright (c) 2020 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include "Application.h" //To set up a slice with settings.
#include "Slice.h" //To set up a scene to slice.
#include "slicer.h" //Starts the slicing phase that we want to test.
#include "utils/FMatrix4x3.h" //To load STL files.
#include "utils/polygon.h" //Creating polygons to compare to sliced layers.
#include "utils/polygonUtils.h" //Comparing similarity of polygons.
#include <gtest/gtest.h>
#include <filesystem>

namespace cura
{

class AdaptiveLayer;

/*
 * Integration test on the slicing phase of CuraEngine. This tests if the
 * slicing algorithm correctly splits a 3D model up into 2D layers.
 */
class SlicePhaseTest : public testing::Test
{
    void SetUp()
    {
        // Start the thread pool
        Application::getInstance().startThreadPool();
        //Set up a scene so that we may request settings.
        Application::getInstance().current_slice = new Slice(1);

        //And a few settings that we want to default.
        Scene& scene = Application::getInstance().current_slice->scene;
        scene.settings.add("slicing_tolerance", "middle");
        scene.settings.add("layer_height_0", "0.2");
        scene.settings.add("layer_height", "0.1");
        scene.settings.add("magic_mesh_surface_mode", "normal");
        scene.settings.add("meshfix_extensive_stitching", "false");
        scene.settings.add("meshfix_keep_open_polygons", "false");
        scene.settings.add("minimum_polygon_circumference", "1");
        scene.settings.add("meshfix_maximum_resolution", "0.04");
        scene.settings.add("meshfix_maximum_deviation", "0.02");
        scene.settings.add("xy_offset", "0");
        scene.settings.add("xy_offset_layer_0", "0");
        scene.settings.add("support_mesh", "false");
        scene.settings.add("anti_overhang_mesh", "false");
        scene.settings.add("cutting_mesh", "false");
        scene.settings.add("infill_mesh", "false");
    }
};

TEST_F(SlicePhaseTest, Cube)
{
    Scene& scene = Application::getInstance().current_slice->scene;
    MeshGroup& mesh_group = scene.mesh_groups.back();

    const FMatrix4x3 transformation;
    //Path to cube.stl is relative to CMAKE_CURRENT_SOURCE_DIR/tests.
    ASSERT_TRUE(loadMeshIntoMeshGroup(&mesh_group, std::filesystem::path(__FILE__).parent_path().append("resources/cube.stl").c_str(), transformation, scene.settings));
    EXPECT_EQ(mesh_group.meshes.size(), 1);
    Mesh& cube_mesh = mesh_group.meshes[0];

    const coord_t layer_thickness = scene.settings.get<coord_t>("layer_height");
    const coord_t initial_layer_thickness = scene.settings.get<coord_t>("layer_height_0");
    constexpr bool variable_layer_height = false;
    constexpr std::vector<AdaptiveLayer>* variable_layer_height_values = nullptr;
    const size_t num_layers = (cube_mesh.getAABB().max.z - initial_layer_thickness) / layer_thickness + 1;
    Slicer slicer(&cube_mesh, layer_thickness, num_layers, variable_layer_height, variable_layer_height_values);

    ASSERT_EQ(slicer.layers.size(), num_layers) << "The number of layers in the output must equal the requested number of layers.";

    //Since a cube has the same slice at all heights, every layer must be the same square.
    Polygon square;
    square.emplace_back(0, 0);
    square.emplace_back(10000, 0); //10mm cube.
    square.emplace_back(10000, 10000);
    square.emplace_back(0, 10000);

    for(size_t layer_nr = 0; layer_nr < num_layers; layer_nr++)
    {
        const SlicerLayer& layer = slicer.layers[layer_nr];
        EXPECT_EQ(layer.polygons.size(), 1);
        if(layer.polygons.size() == 1)
        {
            Polygon sliced_polygon = layer.polygons[0];
            EXPECT_EQ(sliced_polygon.size(), square.size());
            if(sliced_polygon.size() == square.size())
            {
                int start_corner = -1;
                for(size_t corner_idx = 0; corner_idx < square.size(); corner_idx++) //Find the starting corner in the sliced layer.
                {
                    if(square[corner_idx] == sliced_polygon[0])
                    {
                        start_corner = corner_idx;
                        break;
                    }
                }
                EXPECT_NE(start_corner, -1) << "The first vertex of the sliced polygon must be one of the vertices of the ground truth square.";

                if(start_corner != -1)
                {
                    for(size_t corner_idx = 0; corner_idx < square.size(); corner_idx++) //Check if every subsequent corner is correct.
                    {
                        EXPECT_EQ(square[(corner_idx + start_corner) % square.size()], sliced_polygon[corner_idx]);
                    }
                }
            }
        }
    }
}

TEST_F(SlicePhaseTest, Cylinder1000)
{
    Scene& scene = Application::getInstance().current_slice->scene;
    MeshGroup& mesh_group = scene.mesh_groups.back();

    const FMatrix4x3 transformation;
    //Path to cylinder1000.stl is relative to CMAKE_CURRENT_SOURCE_DIR/tests.
    ASSERT_TRUE(loadMeshIntoMeshGroup(&mesh_group, std::filesystem::path(__FILE__).parent_path().append("resources/cylinder1000.stl").c_str(), transformation, scene.settings));
    EXPECT_EQ(mesh_group.meshes.size(), 1);
    Mesh& cylinder_mesh = mesh_group.meshes[0];

    const coord_t layer_thickness = scene.settings.get<coord_t>("layer_height");
    const coord_t initial_layer_thickness = scene.settings.get<coord_t>("layer_height_0");
    constexpr bool variable_layer_height = false;
    constexpr std::vector<AdaptiveLayer>* variable_layer_height_values = nullptr;
    const size_t num_layers = (cylinder_mesh.getAABB().max.z - initial_layer_thickness) / layer_thickness + 1;
    Slicer slicer(&cylinder_mesh, layer_thickness, num_layers, variable_layer_height, variable_layer_height_values);

    ASSERT_EQ(slicer.layers.size(), num_layers) << "The number of layers in the output must equal the requested number of layers.";

    //Since a cylinder has the same slice at all heights, every layer must be the same circle.
    constexpr size_t num_vertices = 1000; //Create a circle with this number of vertices (first vertex is in the +X direction).
    constexpr coord_t radius = 10000; //10mm radius.
    Polygon circle;
    circle.reserve(num_vertices);
    for(size_t i = 0; i < 1000; i++)
    {
        const coord_t x = std::cos(M_PI * 2 / num_vertices * i) * radius;
        const coord_t y = std::sin(M_PI * 2 / num_vertices * i) * radius;
        circle.emplace_back(x, y);
    }
    Polygons circles;
    circles.add(circle);

    for(size_t layer_nr = 0; layer_nr < num_layers; layer_nr++)
    {
        const SlicerLayer& layer = slicer.layers[layer_nr];
        EXPECT_EQ(layer.polygons.size(), 1);
        if(layer.polygons.size() == 1)
        {
            Polygon sliced_polygon = layer.polygons[0];
            //Due to the reduction in resolution, the final slice will not have the same vertices as the input.
            //Let's say that are allowed to be up to 1/500th of the surface area off.
            EXPECT_LE(PolygonUtils::relativeHammingDistance(layer.polygons, circles), 0.002);
        }
    }
}

} //namespace cura<commit_msg>Add missing setting `meshfix_maximum_extrusion_area_deviation`<commit_after>//Copyright (c) 2020 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include "Application.h" //To set up a slice with settings.
#include "Slice.h" //To set up a scene to slice.
#include "slicer.h" //Starts the slicing phase that we want to test.
#include "utils/FMatrix4x3.h" //To load STL files.
#include "utils/polygon.h" //Creating polygons to compare to sliced layers.
#include "utils/polygonUtils.h" //Comparing similarity of polygons.
#include <gtest/gtest.h>
#include <filesystem>

namespace cura
{

class AdaptiveLayer;

/*
 * Integration test on the slicing phase of CuraEngine. This tests if the
 * slicing algorithm correctly splits a 3D model up into 2D layers.
 */
class SlicePhaseTest : public testing::Test
{
    void SetUp()
    {
        // Start the thread pool
        Application::getInstance().startThreadPool();
        //Set up a scene so that we may request settings.
        Application::getInstance().current_slice = new Slice(1);

        //And a few settings that we want to default.
        Scene& scene = Application::getInstance().current_slice->scene;
        scene.settings.add("slicing_tolerance", "middle");
        scene.settings.add("layer_height_0", "0.2");
        scene.settings.add("layer_height", "0.1");
        scene.settings.add("magic_mesh_surface_mode", "normal");
        scene.settings.add("meshfix_extensive_stitching", "false");
        scene.settings.add("meshfix_keep_open_polygons", "false");
        scene.settings.add("minimum_polygon_circumference", "1");
        scene.settings.add("meshfix_maximum_resolution", "0.04");
        scene.settings.add("meshfix_maximum_deviation", "0.02");
        scene.settings.add("meshfix_maximum_extrusion_area_deviation", "2000");
        scene.settings.add("xy_offset", "0");
        scene.settings.add("xy_offset_layer_0", "0");
        scene.settings.add("support_mesh", "false");
        scene.settings.add("anti_overhang_mesh", "false");
        scene.settings.add("cutting_mesh", "false");
        scene.settings.add("infill_mesh", "false");
    }
};

TEST_F(SlicePhaseTest, Cube)
{
    Scene& scene = Application::getInstance().current_slice->scene;
    MeshGroup& mesh_group = scene.mesh_groups.back();

    const FMatrix4x3 transformation;
    //Path to cube.stl is relative to CMAKE_CURRENT_SOURCE_DIR/tests.
    ASSERT_TRUE(loadMeshIntoMeshGroup(&mesh_group, std::filesystem::path(__FILE__).parent_path().append("resources/cube.stl").c_str(), transformation, scene.settings));
    EXPECT_EQ(mesh_group.meshes.size(), 1);
    Mesh& cube_mesh = mesh_group.meshes[0];

    const coord_t layer_thickness = scene.settings.get<coord_t>("layer_height");
    const coord_t initial_layer_thickness = scene.settings.get<coord_t>("layer_height_0");
    constexpr bool variable_layer_height = false;
    constexpr std::vector<AdaptiveLayer>* variable_layer_height_values = nullptr;
    const size_t num_layers = (cube_mesh.getAABB().max.z - initial_layer_thickness) / layer_thickness + 1;
    Slicer slicer(&cube_mesh, layer_thickness, num_layers, variable_layer_height, variable_layer_height_values);

    ASSERT_EQ(slicer.layers.size(), num_layers) << "The number of layers in the output must equal the requested number of layers.";

    //Since a cube has the same slice at all heights, every layer must be the same square.
    Polygon square;
    square.emplace_back(0, 0);
    square.emplace_back(10000, 0); //10mm cube.
    square.emplace_back(10000, 10000);
    square.emplace_back(0, 10000);

    for(size_t layer_nr = 0; layer_nr < num_layers; layer_nr++)
    {
        const SlicerLayer& layer = slicer.layers[layer_nr];
        EXPECT_EQ(layer.polygons.size(), 1);
        if(layer.polygons.size() == 1)
        {
            Polygon sliced_polygon = layer.polygons[0];
            EXPECT_EQ(sliced_polygon.size(), square.size());
            if(sliced_polygon.size() == square.size())
            {
                int start_corner = -1;
                for(size_t corner_idx = 0; corner_idx < square.size(); corner_idx++) //Find the starting corner in the sliced layer.
                {
                    if(square[corner_idx] == sliced_polygon[0])
                    {
                        start_corner = corner_idx;
                        break;
                    }
                }
                EXPECT_NE(start_corner, -1) << "The first vertex of the sliced polygon must be one of the vertices of the ground truth square.";

                if(start_corner != -1)
                {
                    for(size_t corner_idx = 0; corner_idx < square.size(); corner_idx++) //Check if every subsequent corner is correct.
                    {
                        EXPECT_EQ(square[(corner_idx + start_corner) % square.size()], sliced_polygon[corner_idx]);
                    }
                }
            }
        }
    }
}

TEST_F(SlicePhaseTest, Cylinder1000)
{
    Scene& scene = Application::getInstance().current_slice->scene;
    MeshGroup& mesh_group = scene.mesh_groups.back();

    const FMatrix4x3 transformation;
    //Path to cylinder1000.stl is relative to CMAKE_CURRENT_SOURCE_DIR/tests.
    ASSERT_TRUE(loadMeshIntoMeshGroup(&mesh_group, std::filesystem::path(__FILE__).parent_path().append("resources/cylinder1000.stl").c_str(), transformation, scene.settings));
    EXPECT_EQ(mesh_group.meshes.size(), 1);
    Mesh& cylinder_mesh = mesh_group.meshes[0];

    const coord_t layer_thickness = scene.settings.get<coord_t>("layer_height");
    const coord_t initial_layer_thickness = scene.settings.get<coord_t>("layer_height_0");
    constexpr bool variable_layer_height = false;
    constexpr std::vector<AdaptiveLayer>* variable_layer_height_values = nullptr;
    const size_t num_layers = (cylinder_mesh.getAABB().max.z - initial_layer_thickness) / layer_thickness + 1;
    Slicer slicer(&cylinder_mesh, layer_thickness, num_layers, variable_layer_height, variable_layer_height_values);

    ASSERT_EQ(slicer.layers.size(), num_layers) << "The number of layers in the output must equal the requested number of layers.";

    //Since a cylinder has the same slice at all heights, every layer must be the same circle.
    constexpr size_t num_vertices = 1000; //Create a circle with this number of vertices (first vertex is in the +X direction).
    constexpr coord_t radius = 10000; //10mm radius.
    Polygon circle;
    circle.reserve(num_vertices);
    for(size_t i = 0; i < 1000; i++)
    {
        const coord_t x = std::cos(M_PI * 2 / num_vertices * i) * radius;
        const coord_t y = std::sin(M_PI * 2 / num_vertices * i) * radius;
        circle.emplace_back(x, y);
    }
    Polygons circles;
    circles.add(circle);

    for(size_t layer_nr = 0; layer_nr < num_layers; layer_nr++)
    {
        const SlicerLayer& layer = slicer.layers[layer_nr];
        EXPECT_EQ(layer.polygons.size(), 1);
        if(layer.polygons.size() == 1)
        {
            Polygon sliced_polygon = layer.polygons[0];
            //Due to the reduction in resolution, the final slice will not have the same vertices as the input.
            //Let's say that are allowed to be up to 1/500th of the surface area off.
            EXPECT_LE(PolygonUtils::relativeHammingDistance(layer.polygons, circles), 0.002);
        }
    }
}

} //namespace cura<|endoftext|>


<commit_before>// Test device data sharing codegen.
///==========================================================================///

// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1

// expected-no-diagnostics

#ifndef HEADER
#define HEADER

void test_ds(){
  #pragma omp target
  {
    int a = 10;
    #pragma omp parallel
    {
       a = 1000;
    }
  }
}

/// ========= In the worker function ========= ///

// CK1: define internal void @__omp_offloading_{{.*}}test_ds{{.*}}worker(){{.*}}{
// CK1: [[SHAREDARGS:%.+]] = alloca i8**
// CK1: call i1 @__kmpc_kernel_parallel(i8** %work_fn, i8*** [[SHAREDARGS]])
// CK1: [[SHARGSTMP:%.+]] = load i8**, i8*** [[SHAREDARGS]]
// CK1: call void @__omp_outlined___wrapper{{.*}}({{.*}}, i8** %5)

/// ========= In the kernel function ========= ///

// CK1: {{.*}}define void @__omp_offloading{{.*}}test_ds{{.*}}()
// CK1: [[SHAREDARGS1:%.+]] = alloca i8**
// CK1: call void @__kmpc_kernel_prepare_parallel({{.*}}, i8*** [[SHAREDARGS1]], i32 1)
// CK1: [[SHARGSTMP1:%.+]] = load i8**, i8*** [[SHAREDARGS1]]
// CK1: [[SHARGSTMP2:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP1]]
// CK1: [[SHAREDVAR:%.+]] = bitcast i32* {{.*}} to i8*
// CK1: store i8* [[SHAREDVAR]], i8** [[SHARGSTMP2]]

/// ========= In the data sharing wrapper function ========= ///

// CK1: {{.*}}define internal void @__omp_outlined___wrapper({{.*}}i8**){{.*}}{
// CK1: [[SHAREDARGS2:%.+]] = alloca i8**
// CK1: store i8** %2, i8*** [[SHAREDARGS2]]
// CK1: [[SHARGSTMP3:%.+]] = load i8**, i8*** [[SHAREDARGS2]]
// CK1: [[SHARGSTMP4:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP3]]
// CK1: [[SHARGSTMP5:%.+]] = bitcast i8** [[SHARGSTMP4]] to i32**
// CK1: [[SHARGSTMP6:%.+]] = load i32*, i32** [[SHARGSTMP5]]
// CK1: call void @__omp_outlined__({{.*}}, i32* [[SHARGSTMP6]])

#endif<commit_msg>Fix test/OpenMP/nvptx_data_sharing.cpp<commit_after>// Test device data sharing codegen.
///==========================================================================///

// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1

// expected-no-diagnostics

#ifndef HEADER
#define HEADER

void test_ds(){
  #pragma omp target
  {
    int a = 10;
    #pragma omp parallel
    {
       a = 1000;
    }
  }
}

/// ========= In the worker function ========= ///

// CK1: define internal void @__omp_offloading_{{.*}}test_ds{{.*}}worker(){{.*}}{
// CK1: [[SHAREDARGS:%.+]] = alloca i8**
// CK1: call i1 @__kmpc_kernel_parallel(i8** %work_fn, i8*** [[SHAREDARGS]])
// CK1: [[SHARGSTMP:%.+]] = load i8**, i8*** [[SHAREDARGS]]
// CK1: call void @__omp_outlined___wrapper{{.*}}({{.*}}, i8** [[SHARGSTMP]])

/// ========= In the kernel function ========= ///

// CK1: {{.*}}define void @__omp_offloading{{.*}}test_ds{{.*}}()
// CK1: [[SHAREDARGS1:%.+]] = alloca i8**
// CK1: call void @__kmpc_kernel_prepare_parallel({{.*}}, i8*** [[SHAREDARGS1]], i32 1)
// CK1: [[SHARGSTMP1:%.+]] = load i8**, i8*** [[SHAREDARGS1]]
// CK1: [[SHARGSTMP2:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP1]]
// CK1: [[SHAREDVAR:%.+]] = bitcast i32* {{.*}} to i8*
// CK1: store i8* [[SHAREDVAR]], i8** [[SHARGSTMP2]]

/// ========= In the data sharing wrapper function ========= ///

// CK1: {{.*}}define internal void @__omp_outlined___wrapper({{.*}}i8**){{.*}}{
// CK1: [[SHAREDARGS2:%.+]] = alloca i8**
// CK1: store i8** %2, i8*** [[SHAREDARGS2]]
// CK1: [[SHARGSTMP3:%.+]] = load i8**, i8*** [[SHAREDARGS2]]
// CK1: [[SHARGSTMP4:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP3]]
// CK1: [[SHARGSTMP5:%.+]] = bitcast i8** [[SHARGSTMP4]] to i32**
// CK1: [[SHARGSTMP6:%.+]] = load i32*, i32** [[SHARGSTMP5]]
// CK1: call void @__omp_outlined__({{.*}}, i32* [[SHARGSTMP6]])

#endif
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/QtCore>
#include <QtTest/QtTest>

class tst_Headers: public QObject
{
    Q_OBJECT
private slots:
    void initTestCase();

    void privateSlots_data() { allHeadersData(); }
    void privateSlots();

    void macros_data() { allHeadersData(); }
    void macros();

private:
    static QStringList getHeaders(const QString &path);
    static QString explainPrivateSlot(const QString &line);

    void allHeadersData();
    QStringList headers;
    QString qtModuleDir;
};

QStringList tst_Headers::getHeaders(const QString &path)
{
    QStringList result;

    QProcess git;
    git.setWorkingDirectory(path);
    git.start("git", QStringList() << "ls-files");

    // Wait for git to start
    if (!git.waitForStarted())
        qFatal("Error running 'git': %s", qPrintable(git.errorString()));

    // Continue reading the data until EOF reached
    QByteArray data;
    while (git.waitForReadyRead(-1))
        data.append(git.readAll());

    // wait until the process has finished
    if ((git.state() != QProcess::NotRunning) && !git.waitForFinished(30000))
        qFatal("'git ls-files' did not complete within 30 seconds: %s", qPrintable(git.errorString()));

    // Check for the git's exit code
    if (0 != git.exitCode())
        qFatal("Error running 'git ls-files': %s", qPrintable(git.readAllStandardError()));

    // Create a QStringList of files out of the standard output
    QString string(data);
    QStringList entries = string.split( "\n" );

    // We just want to check header files
    entries = entries.filter(QRegExp("\\.h$"));
    entries = entries.filter(QRegExp("^(?!ui_)"));

    // Recreate the whole file path so we can open the file from disk
    foreach (QString entry, entries)
        result += path + "/" + entry;

    return result;
}

void tst_Headers::initTestCase()
{
    qtModuleDir = QString::fromLocal8Bit(qgetenv("QT_MODULE_TO_TEST"));
    if (qtModuleDir.isEmpty()) {
        QSKIP("$QT_MODULE_TO_TEST is unset - nothing to test.  Set QT_MODULE_TO_TEST to the path "
              "of a Qt module to test.");
    }

    QDir dir(qtModuleDir);
    QString module = dir.dirName(); // git module name, e.g. qtbase, qtdeclarative

    if (module != "phonon" && module != "qttools") {
        if (dir.exists("src")) {

            /*
                Let all paths be relative to the directory containing the module.
                For example, if the full path is:

                    /home/qt/build/qt5/qtbase/src/corelib/tools/qstring.h

                ... the first part of the path is useless noise, and causes the
                test log to look different on different machines.
                Cut it down to only the important part:

                    qtbase/src/corelib/tools/qstring.h

            */

            QVERIFY(QDir::setCurrent(dir.absolutePath() + "/.."));

            headers = getHeaders(module + "/src");
        }
        if (headers.isEmpty()) {
            QSKIP("It seems there are no headers in this module; this test is "
                  "not applicable");
        }
    } else {
        QWARN("Some test functions will be skipped, because we ignore them for phonon and qttools.");
    }
}

void tst_Headers::allHeadersData()
{
    QTest::addColumn<QString>("header");

    if (headers.isEmpty())
        QSKIP("can't find any headers in your $QT_MODULE_TO_TEST/src.");

    foreach (QString hdr, headers) {
        if (hdr.contains("/3rdparty/") || hdr.endsWith("/src/tools/uic/qclass_lib_map.h"))
            continue;

        QTest::newRow(qPrintable(hdr)) << hdr;
    }
}

QString tst_Headers::explainPrivateSlot(const QString& line)
{
    // Extract private slot from a line like:
    //  Q_PRIVATE_SLOT(d_func(), void fooBar(...))
    QRegExp re("^\\s+Q_PRIVATE_SLOT\\([^,]+,\\s*(.+)\\)\\s*$");
    QString slot = line;
    if (re.indexIn(slot) != -1) {
        slot = re.cap(1).simplified();
    }

    return QString(
        "Private slot `%1' should be named starting with _q_, to reduce the risk of collisions "
        "with signals/slots in user classes"
    ).arg(slot);
}

void tst_Headers::privateSlots()
{
    QFETCH(QString, header);

    if (header.endsWith("/qobjectdefs.h"))
        return;

    QFile f(header);
    QVERIFY2(f.open(QIODevice::ReadOnly), qPrintable(f.errorString()));

    QStringList content = QString::fromLocal8Bit(f.readAll()).split("\n");
    foreach (QString line, content) {
        if (line.contains("Q_PRIVATE_SLOT("))
            QVERIFY2(line.contains("_q_"), qPrintable(explainPrivateSlot(line)));
    }
}

void tst_Headers::macros()
{
    QFETCH(QString, header);

    if (header.endsWith("_p.h") || header.endsWith("_pch.h")
        || header.contains("global/qconfig-") || header.endsWith("/qconfig.h")
        || header.contains("/src/tools/") || header.contains("/src/plugins/")
        || header.contains("/src/imports/")
        || header.contains("/src/uitools/")
        || header.endsWith("/qiconset.h") || header.endsWith("/qfeatures.h")
        || header.endsWith("qt_windows.h"))
        return;

    QFile f(header);
    QVERIFY2(f.open(QIODevice::ReadOnly), qPrintable(f.errorString()));

    QByteArray data = f.readAll();
    QStringList content = QString::fromLocal8Bit(data.replace('\r', "")).split("\n");

    int beginHeader = content.indexOf("QT_BEGIN_HEADER");
    int endHeader = content.lastIndexOf("QT_END_HEADER");

    QVERIFY(beginHeader >= 0);
    QVERIFY(endHeader >= 0);
    QVERIFY(beginHeader < endHeader);

    // "signals" and "slots" should be banned in public headers
    // headers which use signals/slots wouldn't compile if Qt is configured with QT_NO_KEYWORDS
    QVERIFY2(content.indexOf(QRegExp("\\bslots\\s*:")) == -1, "Header contains `slots' - use `Q_SLOTS' instead!");
    QVERIFY2(content.indexOf(QRegExp("\\bsignals\\s*:")) == -1, "Header contains `signals' - use `Q_SIGNALS' instead!");

    if (header.contains("/sql/drivers/") || header.contains("/arch/qatomic")
        || header.endsWith("qglobal.h")
        || header.endsWith("qwindowdefs_win.h"))
        return;

    int qtmodule = content.indexOf(QRegExp("^QT_MODULE\\(.*\\)$"));
    QVERIFY(qtmodule != -1);
    QVERIFY(qtmodule > beginHeader);
    QVERIFY(qtmodule < endHeader);

    int beginNamespace = content.indexOf("QT_BEGIN_NAMESPACE");
    int endNamespace = content.lastIndexOf("QT_END_NAMESPACE");
    QVERIFY(beginNamespace != -1);
    QVERIFY(endNamespace != -1);
    QVERIFY(beginHeader < beginNamespace);
    QVERIFY(beginNamespace < endNamespace);
    QVERIFY(endNamespace < endHeader);
}

QTEST_MAIN(tst_Headers)
#include "tst_headers.moc"
<commit_msg>tst_headers: remove the qobjectdefs.h special case<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/QtCore>
#include <QtTest/QtTest>

class tst_Headers: public QObject
{
    Q_OBJECT
private slots:
    void initTestCase();

    void privateSlots_data() { allHeadersData(); }
    void privateSlots();

    void macros_data() { allHeadersData(); }
    void macros();

private:
    static QStringList getHeaders(const QString &path);
    static QString explainPrivateSlot(const QString &line);

    void allHeadersData();
    QStringList headers;
    QString qtModuleDir;
};

QStringList tst_Headers::getHeaders(const QString &path)
{
    QStringList result;

    QProcess git;
    git.setWorkingDirectory(path);
    git.start("git", QStringList() << "ls-files");

    // Wait for git to start
    if (!git.waitForStarted())
        qFatal("Error running 'git': %s", qPrintable(git.errorString()));

    // Continue reading the data until EOF reached
    QByteArray data;
    while (git.waitForReadyRead(-1))
        data.append(git.readAll());

    // wait until the process has finished
    if ((git.state() != QProcess::NotRunning) && !git.waitForFinished(30000))
        qFatal("'git ls-files' did not complete within 30 seconds: %s", qPrintable(git.errorString()));

    // Check for the git's exit code
    if (0 != git.exitCode())
        qFatal("Error running 'git ls-files': %s", qPrintable(git.readAllStandardError()));

    // Create a QStringList of files out of the standard output
    QString string(data);
    QStringList entries = string.split( "\n" );

    // We just want to check header files
    entries = entries.filter(QRegExp("\\.h$"));
    entries = entries.filter(QRegExp("^(?!ui_)"));

    // Recreate the whole file path so we can open the file from disk
    foreach (QString entry, entries)
        result += path + "/" + entry;

    return result;
}

void tst_Headers::initTestCase()
{
    qtModuleDir = QString::fromLocal8Bit(qgetenv("QT_MODULE_TO_TEST"));
    if (qtModuleDir.isEmpty()) {
        QSKIP("$QT_MODULE_TO_TEST is unset - nothing to test.  Set QT_MODULE_TO_TEST to the path "
              "of a Qt module to test.");
    }

    QDir dir(qtModuleDir);
    QString module = dir.dirName(); // git module name, e.g. qtbase, qtdeclarative

    if (module != "phonon" && module != "qttools") {
        if (dir.exists("src")) {

            /*
                Let all paths be relative to the directory containing the module.
                For example, if the full path is:

                    /home/qt/build/qt5/qtbase/src/corelib/tools/qstring.h

                ... the first part of the path is useless noise, and causes the
                test log to look different on different machines.
                Cut it down to only the important part:

                    qtbase/src/corelib/tools/qstring.h

            */

            QVERIFY(QDir::setCurrent(dir.absolutePath() + "/.."));

            headers = getHeaders(module + "/src");
        }
        if (headers.isEmpty()) {
            QSKIP("It seems there are no headers in this module; this test is "
                  "not applicable");
        }
    } else {
        QWARN("Some test functions will be skipped, because we ignore them for phonon and qttools.");
    }
}

void tst_Headers::allHeadersData()
{
    QTest::addColumn<QString>("header");

    if (headers.isEmpty())
        QSKIP("can't find any headers in your $QT_MODULE_TO_TEST/src.");

    foreach (QString hdr, headers) {
        if (hdr.contains("/3rdparty/") || hdr.endsWith("/src/tools/uic/qclass_lib_map.h"))
            continue;

        QTest::newRow(qPrintable(hdr)) << hdr;
    }
}

QString tst_Headers::explainPrivateSlot(const QString& line)
{
    // Extract private slot from a line like:
    //  Q_PRIVATE_SLOT(d_func(), void fooBar(...))
    QRegExp re("^\\s+Q_PRIVATE_SLOT\\([^,]+,\\s*(.+)\\)\\s*$");
    QString slot = line;
    if (re.indexIn(slot) != -1) {
        slot = re.cap(1).simplified();
    }

    return QString(
        "Private slot `%1' should be named starting with _q_, to reduce the risk of collisions "
        "with signals/slots in user classes"
    ).arg(slot);
}

void tst_Headers::privateSlots()
{
    QFETCH(QString, header);

    QFile f(header);
    QVERIFY2(f.open(QIODevice::ReadOnly), qPrintable(f.errorString()));

    QStringList content = QString::fromLocal8Bit(f.readAll()).split("\n");
    foreach (QString line, content) {
        if (line.contains("Q_PRIVATE_SLOT(") && !line.contains("define Q_PRIVATE_SLOT"))
            QVERIFY2(line.contains("_q_"), qPrintable(explainPrivateSlot(line)));
    }
}

void tst_Headers::macros()
{
    QFETCH(QString, header);

    if (header.endsWith("_p.h") || header.endsWith("_pch.h")
        || header.contains("global/qconfig-") || header.endsWith("/qconfig.h")
        || header.contains("/src/tools/") || header.contains("/src/plugins/")
        || header.contains("/src/imports/")
        || header.contains("/src/uitools/")
        || header.endsWith("/qiconset.h") || header.endsWith("/qfeatures.h")
        || header.endsWith("qt_windows.h"))
        return;

    QFile f(header);
    QVERIFY2(f.open(QIODevice::ReadOnly), qPrintable(f.errorString()));

    QByteArray data = f.readAll();
    QStringList content = QString::fromLocal8Bit(data.replace('\r', "")).split("\n");

    int beginHeader = content.indexOf("QT_BEGIN_HEADER");
    int endHeader = content.lastIndexOf("QT_END_HEADER");

    QVERIFY(beginHeader >= 0);
    QVERIFY(endHeader >= 0);
    QVERIFY(beginHeader < endHeader);

    // "signals" and "slots" should be banned in public headers
    // headers which use signals/slots wouldn't compile if Qt is configured with QT_NO_KEYWORDS
    QVERIFY2(content.indexOf(QRegExp("\\bslots\\s*:")) == -1, "Header contains `slots' - use `Q_SLOTS' instead!");
    QVERIFY2(content.indexOf(QRegExp("\\bsignals\\s*:")) == -1, "Header contains `signals' - use `Q_SIGNALS' instead!");

    if (header.contains("/sql/drivers/") || header.contains("/arch/qatomic")
        || header.endsWith("qglobal.h")
        || header.endsWith("qwindowdefs_win.h"))
        return;

    int qtmodule = content.indexOf(QRegExp("^QT_MODULE\\(.*\\)$"));
    QVERIFY(qtmodule != -1);
    QVERIFY(qtmodule > beginHeader);
    QVERIFY(qtmodule < endHeader);

    int beginNamespace = content.indexOf("QT_BEGIN_NAMESPACE");
    int endNamespace = content.lastIndexOf("QT_END_NAMESPACE");
    QVERIFY(beginNamespace != -1);
    QVERIFY(endNamespace != -1);
    QVERIFY(beginHeader < beginNamespace);
    QVERIFY(beginNamespace < endNamespace);
    QVERIFY(endNamespace < endHeader);
}

QTEST_MAIN(tst_Headers)
#include "tst_headers.moc"
<|endoftext|>