<commit_before>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>

#include "blackhole/attribute.hpp"
#include "blackhole/detail/config/atomic.hpp"
#include "blackhole/detail/config/noncopyable.hpp"
#include "blackhole/detail/config/nullptr.hpp"
#include "blackhole/detail/util/unique.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/thread.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/tracebit.hpp"

#include "blackhole/config.hpp"

namespace blackhole {

class scoped_attributes_concept_t;

template<typename Level>
struct logger_verbosity_traits {
    typedef Level level_type;

    static
    inline
    bool
    passed(level_type logger_verbosity, level_type record_verbosity) {
        typedef typename aux::underlying_type<Level>::type underlying_type;

        return static_cast<underlying_type>(record_verbosity) >=
            static_cast<underlying_type>(logger_verbosity);
    }
};

class logger_base_t {
    friend class scoped_attributes_concept_t;
    friend void swap(logger_base_t& lhs, logger_base_t& rhs) BLACKHOLE_NOEXCEPT;

protected:
    typedef boost::shared_mutex rw_mutex_type;
    typedef boost::shared_lock<rw_mutex_type> reader_lock_type;
    typedef boost::unique_lock<rw_mutex_type> writer_lock_type;

    struct state_t {
        std::atomic<bool> enabled;
        std::atomic<bool> tracked;

        filter_t filter;
        struct attrbutes_t {
            boost::thread_specific_ptr<scoped_attributes_concept_t> scoped;

            attrbutes_t(void(*deleter)(scoped_attributes_concept_t*)) :
                scoped(deleter)
            {}
        } attributes;

        std::vector<std::unique_ptr<base_frontend_t>> frontends;
        log::exception_handler_t exception;

        struct {
            mutable rw_mutex_type open;
            mutable rw_mutex_type push;
        } lock;

        state_t();
    };

    state_t state;

public:
    logger_base_t();

    //! @compat GCC4.4
    //! Blaming GCC4.4 - it needs explicit move constructor definition,
    //! because it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) BLACKHOLE_NOEXCEPT;
    logger_base_t& operator=(logger_base_t&& other) BLACKHOLE_NOEXCEPT;

    bool enabled() const;
    void enabled(bool enable);

    bool tracked() const;
    void tracked(bool enable);

    void set_filter(filter_t&& filter);
    void add_frontend(std::unique_ptr<base_frontend_t> frontend);
    void set_exception_handler(log::exception_handler_t&& handler);

    record_t open_record() const;
    record_t open_record(attribute::pair_t attribute) const;
    record_t open_record(attribute::set_t attributes) const;

    void push(record_t&& record) const;

protected:
    record_t open_record(attribute::set_t internal, attribute::set_t external) const;
};

/// Concept form scoped attributes holder.
/*!
 * @note: It's not movable to avoid moving to another thread.
 */
class scoped_attributes_concept_t {
    BLACKHOLE_DECLARE_NONCOPYABLE(scoped_attributes_concept_t);

    logger_base_t *m_logger;
    scoped_attributes_concept_t *m_previous;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    scoped_attributes_concept_t(logger_base_t& log);
    virtual ~scoped_attributes_concept_t();

    virtual const attribute::set_t& attributes() const = 0;

protected:
    bool has_parent() const;
    const scoped_attributes_concept_t& parent() const;
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
public:
    typedef Level level_type;

    typedef std::function<
        bool(level_type, const attribute::combined_view_t&)
    > filter_type;

private:
    level_type level;
    filter_type filter;

    // TODO: Thread-safety.

public:
    explicit verbose_logger_t(level_type level) :
        logger_base_t(),
        level(level),
        filter(make_default_filter(level))
    {}

    //! @compat: GCC4.4
    //! GCC 4.4 doesn't create default copy/move constructor for derived
    //! classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT :
        logger_base_t(std::move(other)),
        level(static_cast<level_type>(other.level)),
        filter(other.filter)
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT {
        logger_base_t::operator=(std::move(other));
        level = other.level;
        filter = other.filter;
        return *this;
    }

    // Explicit import other overloaded methods.
    using logger_base_t::open_record;

    /*!
     * Gets the current upper verbosity bound.
     */
    level_type verbosity() const {
        return level;
    }

    /*!
     * Sets the upper verbosity bound.
     * Every log event with a verbosity less than `level` will be dropped.
     * @param[in] level - Upper verbosity value.
     */
    void verbosity(level_type level) {
        this->level = level;
        this->filter = make_default_filter(level);
    }

    void verbosity(filter_type filter) {
        this->filter = filter;
    }

    /*!
     * Tries to open log record with specific verbosity level.
     *
     * Internally this method compares desired verbosity level with the upper
     * one and checks for tracebit attribute (temporary until filter redesign).
     * Can return invalid log record if some conditions are not met.
     * @param[in] level - Desired verbosity level.
     * @return valid or invalid `record_t` object.
     * @todo: Replace with custom filter once a time.
     * @todo: Decompose.
     */
    record_t
    open_record(level_type level, attribute::set_t local = attribute::set_t()) const {
        bool passed = false;
        reader_lock_type lock(state.lock.open);
        if (auto scoped = state.attributes.scoped.get()) {
            const attribute::combined_view_t view(local, scoped->attributes());
            passed = filter(level, view);
        } else {
            const attribute::combined_view_t view(local);
            passed = filter(level, view);
        }

        if (passed) {
            attribute::set_t internal;
            internal.emplace_back(keyword::severity<Level>() = level);
            return logger_base_t::open_record(std::move(internal), std::move(local));
        }

        return record_t();
    }

private:
    static
    inline
    filter_type
    make_default_filter(level_type level) {
        return std::bind(
            &verbose_logger_t::default_filter,
            std::placeholders::_1,
            level,
            std::placeholders::_2
         );
    }

    static
    inline
    bool
    default_filter(level_type level,
                   level_type threshold,
                   const attribute::combined_view_t&)
    {
        return level >= threshold;
    }
};

} // namespace blackhole

#if defined(BLACKHOLE_HEADER_ONLY)
#include "blackhole/logger.ipp"
#endif
<commit_msg>[Code Clean] Refactoring.<commit_after>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>

#include "blackhole/attribute.hpp"
#include "blackhole/detail/config/atomic.hpp"
#include "blackhole/detail/config/noncopyable.hpp"
#include "blackhole/detail/config/nullptr.hpp"
#include "blackhole/detail/util/unique.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/thread.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/tracebit.hpp"

#include "blackhole/config.hpp"

namespace blackhole {

class scoped_attributes_concept_t;

template<typename Level>
struct logger_verbosity_traits {
    typedef Level level_type;

    static
    inline
    bool
    passed(level_type logger_verbosity, level_type record_verbosity) {
        typedef typename aux::underlying_type<Level>::type underlying_type;

        return static_cast<underlying_type>(record_verbosity) >=
            static_cast<underlying_type>(logger_verbosity);
    }
};

class logger_base_t {
    friend class scoped_attributes_concept_t;
    friend void swap(logger_base_t& lhs, logger_base_t& rhs) BLACKHOLE_NOEXCEPT;

protected:
    typedef boost::shared_mutex rw_mutex_type;
    typedef boost::shared_lock<rw_mutex_type> reader_lock_type;
    typedef boost::unique_lock<rw_mutex_type> writer_lock_type;

    struct state_t {
        std::atomic<bool> enabled;
        std::atomic<bool> tracked;

        filter_t filter;
        struct attrbutes_t {
            boost::thread_specific_ptr<scoped_attributes_concept_t> scoped;

            attrbutes_t(void(*deleter)(scoped_attributes_concept_t*)) :
                scoped(deleter)
            {}
        } attributes;

        std::vector<std::unique_ptr<base_frontend_t>> frontends;
        log::exception_handler_t exception;

        struct {
            mutable rw_mutex_type open;
            mutable rw_mutex_type push;
        } lock;

        state_t();
    };

    state_t state;

public:
    logger_base_t();

    //! @compat GCC4.4
    //! Blaming GCC4.4 - it needs explicit move constructor definition,
    //! because it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) BLACKHOLE_NOEXCEPT;
    logger_base_t& operator=(logger_base_t&& other) BLACKHOLE_NOEXCEPT;

    bool enabled() const;
    void enabled(bool enable);

    bool tracked() const;
    void tracked(bool enable);

    void set_filter(filter_t&& filter);
    void add_frontend(std::unique_ptr<base_frontend_t> frontend);
    void set_exception_handler(log::exception_handler_t&& handler);

    record_t open_record() const;
    record_t open_record(attribute::pair_t attribute) const;
    record_t open_record(attribute::set_t attributes) const;

    void push(record_t&& record) const;

protected:
    record_t open_record(attribute::set_t internal, attribute::set_t external) const;
};

/// Concept form scoped attributes holder.
/*!
 * @note: It's not movable to avoid moving to another thread.
 */
class scoped_attributes_concept_t {
    BLACKHOLE_DECLARE_NONCOPYABLE(scoped_attributes_concept_t);

    logger_base_t *m_logger;
    scoped_attributes_concept_t *m_previous;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    scoped_attributes_concept_t(logger_base_t& log);
    virtual ~scoped_attributes_concept_t();

    virtual const attribute::set_t& attributes() const = 0;

protected:
    bool has_parent() const;
    const scoped_attributes_concept_t& parent() const;
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
public:
    typedef Level level_type;

    typedef std::function<
        bool(level_type, const attribute::combined_view_t&)
    > filter_type;

private:
    level_type level;
    filter_type filter;

    // TODO: Thread-safety.

public:
    explicit verbose_logger_t(level_type level) :
        logger_base_t(),
        level(level),
        filter(default_filter { level })
    {}

    //! @compat: GCC4.4
    //! GCC 4.4 doesn't create default copy/move constructor for derived
    //! classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT :
        logger_base_t(std::move(other))
    {
        level = other.level;
        filter = other.filter;
    }

    verbose_logger_t& operator=(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT {
        logger_base_t::operator=(std::move(other));

        level = other.level;
        filter = other.filter;
        return *this;
    }

    // Explicit import other overloaded methods.
    using logger_base_t::open_record;

    /*!
     * Gets the current upper verbosity bound.
     */
    level_type verbosity() const {
        return level;
    }

    /*!
     * Sets the upper verbosity bound.
     * Every log event with a verbosity less than `level` will be dropped.
     * @param[in] level - Upper verbosity value.
     */
    void verbosity(level_type level) {
        this->level = level;
        this->filter = default_filter { level };
    }

    void verbosity(filter_type filter) {
        this->filter = filter;
    }

    /*!
     * Tries to open log record with specific verbosity level.
     *
     * Internally this method compares desired verbosity level with the upper
     * one and checks for tracebit attribute (temporary until filter redesign).
     * Can return invalid log record if some conditions are not met.
     * @param[in] level - Desired verbosity level.
     * @return valid or invalid `record_t` object.
     * @todo: Replace with custom filter once a time.
     * @todo: Decompose.
     */
    record_t
    open_record(level_type level, attribute::set_t local = attribute::set_t()) const {
        bool passed = false;
        reader_lock_type lock(state.lock.open);
        if (auto scoped = state.attributes.scoped.get()) {
            const attribute::combined_view_t view(local, scoped->attributes());
            passed = filter(level, view);
        } else {
            const attribute::combined_view_t view(local);
            passed = filter(level, view);
        }

        if (passed) {
            attribute::set_t internal;
            internal.emplace_back(keyword::severity<Level>() = level);
            return logger_base_t::open_record(std::move(internal), std::move(local));
        }

        return record_t();
    }

private:
    struct default_filter {
        level_type threshold;

        inline
        bool
        operator()(level_type level, const attribute::combined_view_t&) const {
            return level >= threshold;
        }
    };
};

} // namespace blackhole

#if defined(BLACKHOLE_HEADER_ONLY)
#include "blackhole/logger.ipp"
#endif
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2011
  \file      main.cpp
  \authors   Урусов Андрей (rdo@rk9.bmstu.ru)
  \authors   Клеванец Игорь (impus@hotbox.ru)
  \date      2.10.2011
  \brief     Тест законов распределения
  \indent    4T
*/

// ----------------------------------------------------------------------- PLATFORM
#include "utils/src/common/platform.h"
// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#define BOOST_TEST_MODULE RDOSequencesTest
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "utils/src/file/rdofile.h"
#include "utils/src/locale/rdolocale.h"
#include "simulator/runtime/rdo_random_distribution.h"
// --------------------------------------------------------------------------------

typedef std::vector<double> Container;
typedef std::vector<ruint>  ContainerInt;
typedef const tstring contstr;

const long int g_seed                 = 123456789;                  //!< база генератора
contstr        g_filePath             = "../../test/sequences/";//!< путь к файлам относительно проекта
contstr        g_fileNormalName       = "data_normal.txt";      //!< файл данных
contstr        g_fileUniformName      = "data_uniform.txt";     //!< файл данных
contstr        g_fileExponentialName  = "data_exponential.txt"; //!< файл данных
contstr        g_fileTriangularName   = "data_trinagular.txt";  //!< файл данных

const ruint    g_count                = 100000;                     //!< количество генерируемых данных
const double   g_main                 = 10.0;                       //!< параметр закона экспоненциального и нормального
const double   g_var                  = 1.0;                        //!< параметр закона нормального
const double   g_from                 = 1.0;                        //!< параметр закона равномерного и треугольного
const double   g_to                   = 7.0;                        //!< параметр закона равномерного и треугольного
const double   g_top                  = 5.0;                        //!< параметр закона треугольного
#if defined(ARCHITECTURE_X86)
const ruint    g_precision            = 20;                         //!< точность вещественного числа при выводе в поток
#elif defined(ARCHITECTURE_AMD64) || defined(ARCHITECTURE_ARM)
const ruint    g_precision            = 14;                         //!< точность вещественного числа при выводе в поток
#endif

const ruint    g_countOfExamples      = 2000;                       //!< количество чисел в выборке
const ruint    g_countOfR             = 39;                         //!< число разрядов
const double   pi                     = 3.141592653;                //!< фундаментальная константа
const double   g_ksiEtalon            = 50.9985;                    //!< табличное значение. 95% вероятность того, что это действительно тот самый закон распределения

// --------------------------------------------------------------------------------
// -------Templates
// --------------------------------------------------------------------------------
template <class T, class F, class contstr>
void onGenerateData(F binder, contstr g_fileName)
{
	if (rdo::File::exist(g_fileName))
		return;

	T sequence(g_seed);
	Container test;
	test.reserve(g_count);

	for (ruint i = 0; i < g_count; ++i)
	{
		test.push_back(binder.operator()(&sequence));
	}

	std::ofstream stream(g_fileName.c_str());
	stream.precision(g_precision);
	STL_FOR_ALL(test, it)
	{
		stream << *it << std::endl;
	}
}

template <class T, class F, class contstr>
void onCheckData(F binder, contstr g_fileName)
{
	std::ifstream stream(g_fileName.c_str());
	BOOST_CHECK(stream.good());
	Container orig;
	while (stream.good())
	{
		double value;
		stream >> value;
		std::stringstream s;
		s.precision(g_precision);
		s << value;
		s >> value;
		orig.push_back(value);
	}

	Container test;
	test.reserve(g_count);
	T sequence(g_seed);
	for (ruint i = 0; i < g_count; ++i)
	{
		std::stringstream s;
		s.precision(g_precision);
		s << binder.operator()(&sequence);
		double value;
		s >> value;
		test.push_back(value);
	}

	Container::const_iterator origIt = orig.begin();
	stream.precision(g_precision);
	STL_FOR_ALL(test, it)
	{
		BOOST_CHECK(origIt != orig.end());
		rbool check = *it == *origIt;
		BOOST_CHECK(check);
		if (!check)
		{
			std::cout.precision(g_precision);
			std::cout << *it << std::endl;
			std::cout << *origIt << std::endl;
		}
		++origIt;
	}
}

template <class T,class F>
double  area (F binder, double n, double m)
{
	double k = 1;
	double S1 = 1;
	double S2 = 0;
	ruint t = 10;
	while (fabs(S1-S2)/S1 > 0.01)
	{
		S2 = S1;
		S1 = 0;
		for (ruint g = 0; g < t + 1; ++g)
		{
			if ((g == 0) || (g == t - 1))
				k = 0.5;
			S1 += k*(binder.operator()(n + g*(m-n)/t));
			k = 1;
		}
		S1 *= (m-n)/t;
		t  *= 10;
	}
	return S1;
}

template <class T, class G, class F, class S>
void onCheckKsi(F binder, S binderSeq, double left, double right)
{
	Container x;
	x.reserve(g_countOfR + 1);
	double elem = (right-left)/(g_countOfR*1.0);	//расстояние между точками на прямой

	for (ruint i = 0; i < g_countOfR + 1; ++i)
	{
		x.push_back(left + elem*i);
	}

	Container vb;									//контейнер для хранения выборки
	vb.reserve(g_countOfExamples);

	G sequence(g_seed);								//выборка
	for (ruint i = 0; i < g_countOfExamples; ++i)
	{
		vb.push_back(binderSeq.operator()(&sequence));
	}

	Container f_vb;									//контейнер для храниения количества попаданий на интервал
	f_vb.reserve(g_countOfR);

	for(ruint i = 0; i < g_countOfR; ++i)			//нахождение количества попаданий на интервал
	{
		ruint freq = 0;
		for(ruint k = 0; k < g_countOfExamples; ++k)
		{
			if((vb[k] > x[i]) & (vb[k] <= x[i+1]))
			{
				++freq;
			}
		}
		f_vb.push_back(freq);
	}

	Container F_etalon;
	F_etalon.reserve(g_countOfR);

	for (ruint i = 0; i < g_countOfR; ++i)
	{
		F_etalon.push_back(area<T>(binder, x[i], x[i+1]));
	}

	double ksi = 0;
	for(ruint i = 0; i < g_countOfR; ++i)
	{
		double ksiTemp = F_etalon[i]*g_countOfExamples;
		ksi += (f_vb[i] - ksiTemp)*(f_vb[i] - ksiTemp)/ksiTemp;
	}
	BOOST_CHECK(ksi <= g_ksiEtalon);
			if (ksi >  g_ksiEtalon)
	{
		std::cout << ksi << std::endl;
	}
}
// --------------------------------------------------------------------------------

class SequenceNormal
{
public:
	SequenceNormal(double main, double var)
		: m_main(main)
		, m_var (var )
	{}

	double get(double x) const
	{
		return 1/(sqrt(2*pi)*m_var*exp((x - m_main)*(x - m_main)/(2*m_var*m_var)));
	}

private:
	double m_main;
	double m_var;
};

class SequenceExponential
{
public:
	SequenceExponential(double main)
		: m_main(main)
	{}

	double get(double x) const
	{
		return 1/(m_main*exp(x/m_main));
	}

private:
	double m_main;
};

class SequenceUniform
{
public:
	SequenceUniform(double min, double max)
		: m_min(min)
		, m_max(max)
	{}

	double get(double x) const
	{
		UNUSED(x);
		return 1/(m_max-m_min);
	}

private:
	double m_min;
	double m_max;
};

class SequenceTriangular
{
public:
	SequenceTriangular(double min, double top, double max)
		: m_min(min-top)
		, m_top(top)
		, m_max(max-top)
	{}

	double get(double x) const
	{
		x -= m_top;
		double temp;
		if (x < 0)
		{
			temp = -2*x/((m_max - m_min)*m_min) + 2/(m_max - m_min);
		}
		else
		{
			temp = -2*x/((m_max - m_min)*m_max) + 2/(m_max - m_min);
		}
		return temp;
	}

private:
	double m_min;
	double m_top;
	double m_max;
};

BOOST_AUTO_TEST_SUITE(RDOSequencesTest)

// --------------------------------------------------------------------------------
// -------Normal sequence
// --------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RDONormalTestCreate)
{
	rdo::locale::init();

	onGenerateData<rdo::runtime::RandGeneratorNormal>
		(boost::bind(&rdo::runtime::RandGeneratorNormal::next, _1, g_main, g_var), g_filePath + g_fileNormalName);
}

BOOST_AUTO_TEST_CASE(RDONormalTestCheck)
{
	onCheckData<rdo::runtime::RandGeneratorNormal>
		(boost::bind(&rdo::runtime::RandGeneratorNormal::next, _1, g_main, g_var), g_filePath + g_fileNormalName);

	SequenceNormal normal(g_main, g_var);
	onCheckKsi<SequenceNormal, rdo::runtime::RandGeneratorNormal>
		(boost::bind(&SequenceNormal::get, normal, _1),
		boost::bind(&rdo::runtime::RandGeneratorNormal::next, _1, g_main, g_var),
		g_main-4*g_var,
		g_main+4*g_var);
}
// --------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
// -------Uniform sequence
// --------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RDOUniformTestCreate)
{
	onGenerateData<rdo::runtime::RandGeneratorUniform>
		(boost::bind(&rdo::runtime::RandGeneratorUniform::next, _1, g_from, g_to), g_filePath + g_fileUniformName);
}

BOOST_AUTO_TEST_CASE(RDOUniformTestCheck)
{
	onCheckData<rdo::runtime::RandGeneratorUniform>
		(boost::bind(&rdo::runtime::RandGeneratorUniform::next, _1, g_from, g_to), g_filePath + g_fileUniformName);

	SequenceUniform uniform(g_from, g_to);
	onCheckKsi<SequenceUniform, rdo::runtime::RandGeneratorUniform>
		(boost::bind(&SequenceUniform::get, uniform, _1),
		boost::bind(&rdo::runtime::RandGeneratorUniform::next, _1, g_from, g_to),
		g_from,
		g_to);
}
// --------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
// -------Exponential sequence
// --------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RDOExponentialTestCreate)
{
	onGenerateData<rdo::runtime::RandGeneratorExponential>
		(boost::bind(&rdo::runtime::RandGeneratorExponential::next, _1, g_main), g_filePath + g_fileExponentialName);
}

BOOST_AUTO_TEST_CASE(RDOExponentialTestCheck)
{
	onCheckData<rdo::runtime::RandGeneratorExponential>
		(boost::bind(&rdo::runtime::RandGeneratorExponential::next, _1, g_main), g_filePath + g_fileExponentialName);

	SequenceExponential exponential(g_main);
	onCheckKsi<SequenceExponential, rdo::runtime::RandGeneratorExponential>
		(boost::bind(&SequenceExponential::get, exponential, _1),
		boost::bind(&rdo::runtime::RandGeneratorExponential::next, _1, g_main),
		0,
		7*g_main);
}
// --------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
// -------Triangular sequence
// --------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RDOTriangularTestCreate)
{
	onGenerateData<rdo::runtime::RandGeneratorTriangular>
		(boost::bind(&rdo::runtime::RandGeneratorTriangular::next, _1, g_from, g_top, g_to), g_filePath + g_fileTriangularName);
}

BOOST_AUTO_TEST_CASE(RDOTriangularTestCheck)
{
	onCheckData<rdo::runtime::RandGeneratorTriangular>
		(boost::bind(&rdo::runtime::RandGeneratorTriangular::next, _1, g_from, g_top, g_to), g_filePath + g_fileTriangularName);

	SequenceTriangular triangular(g_from, g_top, g_to);
	onCheckKsi<SequenceTriangular, rdo::runtime::RandGeneratorTriangular>
		(boost::bind(&SequenceTriangular::get, triangular, _1),
		boost::bind(&rdo::runtime::RandGeneratorTriangular::next, _1, g_from, g_top, g_to),
		g_from,
		g_to);
}
// --------------------------------------------------------------------------------

BOOST_AUTO_TEST_SUITE_END()
<commit_msg> - добавлено ограничение по времени<commit_after>/*!
  \copyright (c) RDO-Team, 2011
  \file      main.cpp
  \authors   Урусов Андрей (rdo@rk9.bmstu.ru)
  \authors   Клеванец Игорь (impus@hotbox.ru)
  \date      2.10.2011
  \brief     Тест законов распределения
  \indent    4T
*/

// ----------------------------------------------------------------------- PLATFORM
#include "utils/src/common/platform.h"
// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#define BOOST_TEST_MODULE RDOSequencesTest
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "utils/src/file/rdofile.h"
#include "utils/src/locale/rdolocale.h"
#include "simulator/runtime/rdo_random_distribution.h"
// --------------------------------------------------------------------------------

typedef std::vector<double> Container;
typedef std::vector<ruint>  ContainerInt;
typedef const tstring contstr;

const long int g_seed                 = 123456789;                  //!< база генератора
contstr        g_filePath             = "../../test/sequences/";    //!< путь к файлам относительно проекта
contstr        g_fileNormalName       = "data_normal.txt";          //!< файл данных
contstr        g_fileUniformName      = "data_uniform.txt";         //!< файл данных
contstr        g_fileExponentialName  = "data_exponential.txt";     //!< файл данных
contstr        g_fileTriangularName   = "data_trinagular.txt";      //!< файл данных

const ruint    g_count                = 100000;                     //!< количество генерируемых данных
const double   g_main                 = 10.0;                       //!< параметр закона экспоненциального и нормального
const double   g_var                  = 1.0;                        //!< параметр закона нормального
const double   g_from                 = 1.0;                        //!< параметр закона равномерного и треугольного
const double   g_to                   = 7.0;                        //!< параметр закона равномерного и треугольного
const double   g_top                  = 5.0;                        //!< параметр закона треугольного
#if defined(ARCHITECTURE_X86)
const ruint    g_precision            = 20;                         //!< точность вещественного числа при выводе в поток
#elif defined(ARCHITECTURE_AMD64) || defined(ARCHITECTURE_ARM)
const ruint    g_precision            = 14;                         //!< точность вещественного числа при выводе в поток
#endif

const ruint    g_countOfExamples      = 2000;                       //!< количество чисел в выборке
const ruint    g_countOfR             = 39;                         //!< число разрядов
const double   pi                     = 3.141592653;                //!< фундаментальная константа
const double   g_ksiEtalon            = 50.9985;                    //!< табличное значение. 95% вероятность того, что это действительно тот самый закон распределения

// --------------------------------------------------------------------------------
// -------Templates
// --------------------------------------------------------------------------------
template <class T, class F, class contstr>
void onGenerateData(F binder, contstr g_fileName)
{
	if (rdo::File::exist(g_fileName))
		return;

	T sequence(g_seed);
	Container test;
	test.reserve(g_count);

	for (ruint i = 0; i < g_count; ++i)
	{
		test.push_back(binder.operator()(&sequence));
	}

	std::ofstream stream(g_fileName.c_str());
	stream.precision(g_precision);
	STL_FOR_ALL(test, it)
	{
		stream << *it << std::endl;
	}
}

template <class T, class F>
void onCheckData(F binder, contstr& g_fileName)
{
	T sequence(g_seed);
	std::ifstream stream(g_fileName.c_str());

	const boost::posix_time::time_duration testDuration = boost::posix_time::microseconds(100000);
	unsigned int minTestCount = 100;

	boost::posix_time::ptime testStart = boost::posix_time::microsec_clock::local_time();
	while (boost::posix_time::microsec_clock::local_time() - testStart < testDuration)
	{
		for (unsigned int i = 0; i < minTestCount; ++i)
		{
			if (!stream.good())
				return;

			double valueOriginal;
			stream >> valueOriginal;

			if (!stream.good())
				return;

			qqq++;

			{
				std::stringstream s;
				s.precision(g_precision);
				s << valueOriginal;
				s >> valueOriginal;
			}

			double valueTest;

			{
				std::stringstream s;
				s.precision(g_precision);
				s << binder.operator()(&sequence);
				s >> valueTest;
			}

			rbool check = valueOriginal == valueTest;
			BOOST_CHECK(check);
			if (!check)
			{
				std::cout.precision(g_precision);
				std::cout << valueOriginal << " != " << valueTest << std::endl;
			}
		}
	}
}

template <class T,class F>
double  area (F binder, double n, double m)
{
	double k = 1;
	double S1 = 1;
	double S2 = 0;
	ruint t = 10;
	while (fabs(S1-S2)/S1 > 0.01)
	{
		S2 = S1;
		S1 = 0;
		for (ruint g = 0; g < t + 1; ++g)
		{
			if ((g == 0) || (g == t - 1))
				k = 0.5;
			S1 += k*(binder.operator()(n + g*(m-n)/t));
			k = 1;
		}
		S1 *= (m-n)/t;
		t  *= 10;
	}
	return S1;
}

template <class T, class G, class F, class S>
void onCheckKsi(F binder, S binderSeq, double left, double right)
{
	Container x;
	x.reserve(g_countOfR + 1);
	double elem = (right-left)/(g_countOfR*1.0);	//расстояние между точками на прямой

	for (ruint i = 0; i < g_countOfR + 1; ++i)
	{
		x.push_back(left + elem*i);
	}

	Container vb;									//контейнер для хранения выборки
	vb.reserve(g_countOfExamples);

	G sequence(g_seed);								//выборка
	for (ruint i = 0; i < g_countOfExamples; ++i)
	{
		vb.push_back(binderSeq.operator()(&sequence));
	}

	Container f_vb;									//контейнер для храниения количества попаданий на интервал
	f_vb.reserve(g_countOfR);

	for(ruint i = 0; i < g_countOfR; ++i)			//нахождение количества попаданий на интервал
	{
		ruint freq = 0;
		for(ruint k = 0; k < g_countOfExamples; ++k)
		{
			if((vb[k] > x[i]) & (vb[k] <= x[i+1]))
			{
				++freq;
			}
		}
		f_vb.push_back(freq);
	}

	Container F_etalon;
	F_etalon.reserve(g_countOfR);

	for (ruint i = 0; i < g_countOfR; ++i)
	{
		F_etalon.push_back(area<T>(binder, x[i], x[i+1]));
	}

	double ksi = 0;
	for(ruint i = 0; i < g_countOfR; ++i)
	{
		double ksiTemp = F_etalon[i]*g_countOfExamples;
		ksi += (f_vb[i] - ksiTemp)*(f_vb[i] - ksiTemp)/ksiTemp;
	}
	BOOST_CHECK(ksi <= g_ksiEtalon);
			if (ksi >  g_ksiEtalon)
	{
		std::cout << ksi << std::endl;
	}
}
// --------------------------------------------------------------------------------

class SequenceNormal
{
public:
	SequenceNormal(double main, double var)
		: m_main(main)
		, m_var (var )
	{}

	double get(double x) const
	{
		return 1/(sqrt(2*pi)*m_var*exp((x - m_main)*(x - m_main)/(2*m_var*m_var)));
	}

private:
	double m_main;
	double m_var;
};

class SequenceExponential
{
public:
	SequenceExponential(double main)
		: m_main(main)
	{}

	double get(double x) const
	{
		return 1/(m_main*exp(x/m_main));
	}

private:
	double m_main;
};

class SequenceUniform
{
public:
	SequenceUniform(double min, double max)
		: m_min(min)
		, m_max(max)
	{}

	double get(double x) const
	{
		UNUSED(x);
		return 1/(m_max-m_min);
	}

private:
	double m_min;
	double m_max;
};

class SequenceTriangular
{
public:
	SequenceTriangular(double min, double top, double max)
		: m_min(min-top)
		, m_top(top)
		, m_max(max-top)
	{}

	double get(double x) const
	{
		x -= m_top;
		double temp;
		if (x < 0)
		{
			temp = -2*x/((m_max - m_min)*m_min) + 2/(m_max - m_min);
		}
		else
		{
			temp = -2*x/((m_max - m_min)*m_max) + 2/(m_max - m_min);
		}
		return temp;
	}

private:
	double m_min;
	double m_top;
	double m_max;
};

BOOST_AUTO_TEST_SUITE(RDOSequencesTest)

// --------------------------------------------------------------------------------
// -------Normal sequence
// --------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RDONormalTestCreate)
{
	rdo::locale::init();

	onGenerateData<rdo::runtime::RandGeneratorNormal>
		(boost::bind(&rdo::runtime::RandGeneratorNormal::next, _1, g_main, g_var), g_filePath + g_fileNormalName);
}

BOOST_AUTO_TEST_CASE(RDONormalTestCheck)
{
	onCheckData<rdo::runtime::RandGeneratorNormal>
		(boost::bind(&rdo::runtime::RandGeneratorNormal::next, _1, g_main, g_var), g_filePath + g_fileNormalName);

	SequenceNormal normal(g_main, g_var);
	onCheckKsi<SequenceNormal, rdo::runtime::RandGeneratorNormal>
		(boost::bind(&SequenceNormal::get, normal, _1),
		boost::bind(&rdo::runtime::RandGeneratorNormal::next, _1, g_main, g_var),
		g_main-4*g_var,
		g_main+4*g_var);
}
// --------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
// -------Uniform sequence
// --------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RDOUniformTestCreate)
{
	onGenerateData<rdo::runtime::RandGeneratorUniform>
		(boost::bind(&rdo::runtime::RandGeneratorUniform::next, _1, g_from, g_to), g_filePath + g_fileUniformName);
}

BOOST_AUTO_TEST_CASE(RDOUniformTestCheck)
{
	onCheckData<rdo::runtime::RandGeneratorUniform>
		(boost::bind(&rdo::runtime::RandGeneratorUniform::next, _1, g_from, g_to), g_filePath + g_fileUniformName);

	SequenceUniform uniform(g_from, g_to);
	onCheckKsi<SequenceUniform, rdo::runtime::RandGeneratorUniform>
		(boost::bind(&SequenceUniform::get, uniform, _1),
		boost::bind(&rdo::runtime::RandGeneratorUniform::next, _1, g_from, g_to),
		g_from,
		g_to);
}
// --------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
// -------Exponential sequence
// --------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RDOExponentialTestCreate)
{
	onGenerateData<rdo::runtime::RandGeneratorExponential>
		(boost::bind(&rdo::runtime::RandGeneratorExponential::next, _1, g_main), g_filePath + g_fileExponentialName);
}

BOOST_AUTO_TEST_CASE(RDOExponentialTestCheck)
{
	onCheckData<rdo::runtime::RandGeneratorExponential>
		(boost::bind(&rdo::runtime::RandGeneratorExponential::next, _1, g_main), g_filePath + g_fileExponentialName);

	SequenceExponential exponential(g_main);
	onCheckKsi<SequenceExponential, rdo::runtime::RandGeneratorExponential>
		(boost::bind(&SequenceExponential::get, exponential, _1),
		boost::bind(&rdo::runtime::RandGeneratorExponential::next, _1, g_main),
		0,
		7*g_main);
}
// --------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
// -------Triangular sequence
// --------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(RDOTriangularTestCreate)
{
	onGenerateData<rdo::runtime::RandGeneratorTriangular>
		(boost::bind(&rdo::runtime::RandGeneratorTriangular::next, _1, g_from, g_top, g_to), g_filePath + g_fileTriangularName);
}

BOOST_AUTO_TEST_CASE(RDOTriangularTestCheck)
{
	onCheckData<rdo::runtime::RandGeneratorTriangular>
		(boost::bind(&rdo::runtime::RandGeneratorTriangular::next, _1, g_from, g_top, g_to), g_filePath + g_fileTriangularName);

	SequenceTriangular triangular(g_from, g_top, g_to);
	onCheckKsi<SequenceTriangular, rdo::runtime::RandGeneratorTriangular>
		(boost::bind(&SequenceTriangular::get, triangular, _1),
		boost::bind(&rdo::runtime::RandGeneratorTriangular::next, _1, g_from, g_top, g_to),
		g_from,
		g_to);
}
// --------------------------------------------------------------------------------

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexSQL.cxx
 ** Lexer for SQL.
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
	char s[100];
	bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
	for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
		s[i] = static_cast<char>(tolower(styler[start + i]));
		s[i + 1] = '\0';
	}
	char chAttr = SCE_C_IDENTIFIER;
	if (wordIsNumber)
		chAttr = SCE_C_NUMBER;
	else {
		if (keywords.InList(s))
			chAttr = SCE_C_WORD;
	}
	styler.ColourTo(end, chAttr);
}

static void ColouriseSQLDoc(unsigned int startPos, int length,
                            int initStyle, WordList *keywordlists[], Accessor &styler) {

	WordList &keywords = *keywordlists[0];

	styler.StartAt(startPos);

	bool fold = styler.GetPropertyInt("fold") != 0;
	int lineCurrent = styler.GetLine(startPos);
	int spaceFlags = 0;

	int state = initStyle;
	char chPrev = ' ';
	char chNext = styler[startPos];
	styler.StartSegment(startPos);
	unsigned int lengthDoc = startPos + length;
	for (unsigned int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
			int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
			int lev = indentCurrent;
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
				if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				}
			}
			if (fold) {
				styler.SetLevel(lineCurrent, lev);
			}
		}

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			chPrev = ' ';
			i += 1;
			continue;
		}

		if (state == SCE_C_DEFAULT) {
			if (iswordstart(ch)) {
				styler.ColourTo(i - 1, state);
				state = SCE_C_WORD;
			} else if (ch == '/' && chNext == '*') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENT;
			} else if (ch == '-' && chNext == '-') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENTLINE;
			} else if ((ch == '\'') || (ch == '"')) {
				styler.ColourTo(i - 1, state);
				state = SCE_C_STRING;
			} else if (isoperator(ch)) {
				styler.ColourTo(i - 1, state);
				styler.ColourTo(i, SCE_C_OPERATOR);
			}
		} else if (state == SCE_C_WORD) {
			if (!iswordchar(ch)) {
				classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler);
				state = SCE_C_DEFAULT;
				if (ch == '/' && chNext == '*') {
					state = SCE_C_COMMENT;
				} else if (ch == '-' && chNext == '-') {
					state = SCE_C_COMMENTLINE;
				} else if ((ch == '\'') || (ch == '"'))  {
					state = SCE_C_STRING;
				} else if (isoperator(ch)) {
					styler.ColourTo(i, SCE_C_OPERATOR);
				}
			}
		} else {
			if (state == SCE_C_COMMENT) {
				if (ch == '/' && chPrev == '*') {
					if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) &&
					    (styler.GetStartSegment() == startPos)))) {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
					}
				}
			} else if (state == SCE_C_COMMENTLINE) {
				if (ch == '\r' || ch == '\n') {
					styler.ColourTo(i - 1, state);
					state = SCE_C_DEFAULT;
				}
			} else if (state == SCE_C_STRING) {
				if (ch == '\'') {
					if ( chNext == '\'' ) {
						i++;
					} else {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
						i++;
					}
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				} else if (ch == '"') {
					if (chNext == '"') {
						i++;
					} else {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
						i++;
					}
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				}
			}
			if (state == SCE_C_DEFAULT) {    // One of the above succeeded
				if (ch == '/' && chNext == '*') {
					state = SCE_C_COMMENT;
				} else if (ch == '-' && chNext == '-') {
					state = SCE_C_COMMENTLINE;
				} else if ((ch == '\'') || (ch == '"')) {
					state = SCE_C_STRING;
				} else if (iswordstart(ch)) {
					state = SCE_C_WORD;
				} else if (isoperator(ch)) {
					styler.ColourTo(i, SCE_C_OPERATOR);
				}
			}
		}
		chPrev = ch;
	}
	styler.ColourTo(lengthDoc - 1, state);
}

static const char * const sqlWordListDesc[] = {
	"Keywords",
	0
};

LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc);
<commit_msg>Separated single quote and double quote string styles.<commit_after>// Scintilla source code edit control
/** @file LexSQL.cxx
 ** Lexer for SQL.
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
	char s[100];
	bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
	for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
		s[i] = static_cast<char>(tolower(styler[start + i]));
		s[i + 1] = '\0';
	}
	char chAttr = SCE_C_IDENTIFIER;
	if (wordIsNumber)
		chAttr = SCE_C_NUMBER;
	else {
		if (keywords.InList(s))
			chAttr = SCE_C_WORD;
	}
	styler.ColourTo(end, chAttr);
}

static void ColouriseSQLDoc(unsigned int startPos, int length,
                            int initStyle, WordList *keywordlists[], Accessor &styler) {

	WordList &keywords = *keywordlists[0];

	styler.StartAt(startPos);

	bool fold = styler.GetPropertyInt("fold") != 0;
	int lineCurrent = styler.GetLine(startPos);
	int spaceFlags = 0;

	int state = initStyle;
	char chPrev = ' ';
	char chNext = styler[startPos];
	styler.StartSegment(startPos);
	unsigned int lengthDoc = startPos + length;
	for (unsigned int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
			int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
			int lev = indentCurrent;
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
				if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				}
			}
			if (fold) {
				styler.SetLevel(lineCurrent, lev);
			}
		}

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			chPrev = ' ';
			i += 1;
			continue;
		}

		if (state == SCE_C_DEFAULT) {
			if (iswordstart(ch)) {
				styler.ColourTo(i - 1, state);
				state = SCE_C_WORD;
			} else if (ch == '/' && chNext == '*') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENT;
			} else if (ch == '-' && chNext == '-') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENTLINE;
			} else if (ch == '\'') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_CHARACTER;
			} else if (ch == '"') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_STRING;
			} else if (isoperator(ch)) {
				styler.ColourTo(i - 1, state);
				styler.ColourTo(i, SCE_C_OPERATOR);
			}
		} else if (state == SCE_C_WORD) {
			if (!iswordchar(ch)) {
				classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler);
				state = SCE_C_DEFAULT;
				if (ch == '/' && chNext == '*') {
					state = SCE_C_COMMENT;
				} else if (ch == '-' && chNext == '-') {
					state = SCE_C_COMMENTLINE;
				} else if (ch == '\'') {
					state = SCE_C_CHARACTER;
				} else if (ch == '"') {
					state = SCE_C_STRING;
				} else if (isoperator(ch)) {
					styler.ColourTo(i, SCE_C_OPERATOR);
				}
			}
		} else {
			if (state == SCE_C_COMMENT) {
				if (ch == '/' && chPrev == '*') {
					if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) &&
					    (styler.GetStartSegment() == startPos)))) {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
					}
				}
			} else if (state == SCE_C_COMMENTLINE) {
				if (ch == '\r' || ch == '\n') {
					styler.ColourTo(i - 1, state);
					state = SCE_C_DEFAULT;
				}
			} else if (state == SCE_C_CHARACTER) {
				if (ch == '\'') {
					if ( chNext == '\'' ) {
						i++;
					} else {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
						i++;
					}
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				}
			} else if (state == SCE_C_STRING) {
				if (ch == '"') {
					if (chNext == '"') {
						i++;
					} else {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
						i++;
					}
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				}
			}
			if (state == SCE_C_DEFAULT) {    // One of the above succeeded
				if (ch == '/' && chNext == '*') {
					state = SCE_C_COMMENT;
				} else if (ch == '-' && chNext == '-') {
					state = SCE_C_COMMENTLINE;
				} else if (ch == '\'') {
					state = SCE_C_CHARACTER;
				} else if (ch == '"') {
					state = SCE_C_STRING;
				} else if (iswordstart(ch)) {
					state = SCE_C_WORD;
				} else if (isoperator(ch)) {
					styler.ColourTo(i, SCE_C_OPERATOR);
				}
			}
		}
		chPrev = ch;
	}
	styler.ColourTo(lengthDoc - 1, state);
}

static const char * const sqlWordListDesc[] = {
	"Keywords",
	0
};

LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc);
<|endoftext|>


<commit_before>#include "Board.h"
#include "Pawn.h"
#include "Rook.h"
#include "Knight.h"
#include "Bishop.h"
#include "Queen.h"
#include "King.h"

namespace Chess {
	Board::Board() {
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				pieces[x][y] = nullptr;
			}
		}

		// Black pawns
		for (int x = 0; x < 8; x++) {
			pieces[x][6] = new Pawn(Position(x, 6), false);
		}

		// White pawns
		for (int x = 0; x < 8; x++) {
			pieces[x][1] = new Pawn(Position(x, 1), true);
		}

		// Rooks
		pieces[0][7] = new Rook(Position(0, 7), false);
		pieces[7][7] = new Rook(Position(7, 7), false);
		pieces[0][0] = new Rook(Position(0, 0), true);
		pieces[7][0] = new Rook(Position(7, 0), true);

		// Knights
		pieces[1][7] = new Knight(Position(1, 7), false);
		pieces[6][7] = new Knight(Position(6, 7), false);
		pieces[1][0] = new Knight(Position(1, 0), true);
		pieces[6][0] = new Knight(Position(6, 0), true);

		// Bishops
		pieces[2][7] = new Bishop(Position(2, 7), false);
		pieces[5][7] = new Bishop(Position(5, 7), false);
		pieces[2][0] = new Bishop(Position(2, 0), true);
		pieces[5][0] = new Bishop(Position(5, 0), true);

		// Queens
		pieces[3][7] = new Queen(Position(3, 7), false);
		pieces[3][0] = new Queen(Position(3, 0), true);

		// Kings
		blackKing = new King(Position(4, 7), false);
		pieces[4][7] = blackKing;
		whiteKing = new King(Position(4, 0), true);
		pieces[4][0] = whiteKing;
	}

	Board::~Board() {
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				if (pieces[x][y] != nullptr)
					delete pieces[x][y];
			}
		}
	}

	GameState Board::getState() const {
		return state;
	}

	Piece* Board::getPiece(const Position& position) const {
		return pieces[position.x][position.y];
	}

	bool Board::signalPromote() {
		bool temp = needsToPromote;
		needsToPromote = false;
		return temp;
	}

	bool Board::move(const Position& oldPosition, const Position& newPosition) {
		Piece* piece = getPiece(oldPosition);
		Piece* targetPiece = getPiece(newPosition);

		if (piece != nullptr) {
			// Check if the piece is of the right color.
			if (piece->isWhite() == (turn % 2 == 0)) {
				// Check if the move is legal.
				if (piece->isLegal(*this, newPosition)) {
					pieces[oldPosition.x][oldPosition.y] = nullptr;

					//En passant.
					if (pieces[newPosition.x][newPosition.y] == nullptr && (piece->notation() == 'p' || piece->notation() == 'P') && newPosition.x != oldPosition.x){
						if (piece->isWhite()){
							delete pieces[newPosition.x][newPosition.y - 1];
							pieces[newPosition.x][newPosition.y - 1] = nullptr;
						}
						else{
							delete pieces[newPosition.x][newPosition.y + 1];
							pieces[newPosition.x][newPosition.y + 1] = nullptr;
						}
					}

					//Castling
					if (piece->notation() == 'k' || piece->notation() == 'K'){
						if (newPosition.x - oldPosition.x == 2){
							Piece* tempPiece = getPiece(Position(7, newPosition.y));
							pieces[7][newPosition.y] = nullptr;
							pieces[5][newPosition.y] = tempPiece;
							tempPiece->move(Position(5, newPosition.y));
						}
						else if (newPosition.x - oldPosition.x == -2){
							Piece* tempPiece = getPiece(Position(0, newPosition.y));
							pieces[0][newPosition.y] = nullptr;
							pieces[3][newPosition.y] = tempPiece;
							tempPiece->move(Position(3, newPosition.y));
						}
					}
					// Delete captured enemy piece.
					if (pieces[newPosition.x][newPosition.y] != nullptr && piece->isWhite() != targetPiece->isWhite()){
						delete pieces[newPosition.x][newPosition.y];
					}

					// Update pieces and piece position
					pieces[newPosition.x][newPosition.y] = piece;
					piece->move(newPosition);

					//Promote pawns
					if(newPosition.y == 7 || newPosition.y == 0){
						if (piece->notation() == 'p' || piece->notation() == 'P'){
							needsToPromote = true;
						}
					}
					// Set and reset lastMovedPiece
					if (lastMovedPawn != nullptr){
						if (lastMovedPawn->getLastMoveWasDouble()){
							//lastMovedPawn->resetLastMoveWasDouble(); //orsakar krasch..
						}
					}
					lastMovedPawn = dynamic_cast<Pawn *>(getPiece(newPosition));

					turn++;
					if (state == GameState::BLACKPLAYS)
						state = GameState::WHITEPLAYS;
					else
						state = GameState::BLACKPLAYS;
					return true;
				}
			}
		}

		return false;
	}

	void Board::promotePawn(Piece* pawn, PromoteTypes type) {
		Position position = pawn->getPosition();
		bool white = pawn->isWhite();
		delete pawn;

		switch (type) {
		case PromoteTypes::QUEEN:
			pieces[position.x][position.y] = new Queen(position, white);
			break;
		case PromoteTypes::ROOK:
			pieces[position.x][position.y] = new Rook(position, white);
			break;
		case PromoteTypes::BISHOP:
			pieces[position.x][position.y] = new Bishop(position, white);
			break;
		case PromoteTypes::KNIGHT:
			pieces[position.x][position.y] = new Knight(position, white);
			break;
		}
	}

	King* Board::getKing(bool white) const {
		if (white) {
			return whiteKing;
		} else {
			return blackKing;
		}
	}
}<commit_msg>Removed unnecessary check<commit_after>#include "Board.h"
#include "Pawn.h"
#include "Rook.h"
#include "Knight.h"
#include "Bishop.h"
#include "Queen.h"
#include "King.h"

namespace Chess {
	Board::Board() {
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				pieces[x][y] = nullptr;
			}
		}

		// Black pawns
		for (int x = 0; x < 8; x++) {
			pieces[x][6] = new Pawn(Position(x, 6), false);
		}

		// White pawns
		for (int x = 0; x < 8; x++) {
			pieces[x][1] = new Pawn(Position(x, 1), true);
		}

		// Rooks
		pieces[0][7] = new Rook(Position(0, 7), false);
		pieces[7][7] = new Rook(Position(7, 7), false);
		pieces[0][0] = new Rook(Position(0, 0), true);
		pieces[7][0] = new Rook(Position(7, 0), true);

		// Knights
		pieces[1][7] = new Knight(Position(1, 7), false);
		pieces[6][7] = new Knight(Position(6, 7), false);
		pieces[1][0] = new Knight(Position(1, 0), true);
		pieces[6][0] = new Knight(Position(6, 0), true);

		// Bishops
		pieces[2][7] = new Bishop(Position(2, 7), false);
		pieces[5][7] = new Bishop(Position(5, 7), false);
		pieces[2][0] = new Bishop(Position(2, 0), true);
		pieces[5][0] = new Bishop(Position(5, 0), true);

		// Queens
		pieces[3][7] = new Queen(Position(3, 7), false);
		pieces[3][0] = new Queen(Position(3, 0), true);

		// Kings
		blackKing = new King(Position(4, 7), false);
		pieces[4][7] = blackKing;
		whiteKing = new King(Position(4, 0), true);
		pieces[4][0] = whiteKing;
	}

	Board::~Board() {
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				if (pieces[x][y] != nullptr)
					delete pieces[x][y];
			}
		}
	}

	GameState Board::getState() const {
		return state;
	}

	Piece* Board::getPiece(const Position& position) const {
		return pieces[position.x][position.y];
	}

	bool Board::signalPromote() {
		bool temp = needsToPromote;
		needsToPromote = false;
		return temp;
	}

	bool Board::move(const Position& oldPosition, const Position& newPosition) {
		Piece* piece = getPiece(oldPosition);
		Piece* targetPiece = getPiece(newPosition);

		if (piece != nullptr) {
			// Check if the piece is of the right color.
			if (piece->isWhite() == (turn % 2 == 0)) {
				// Check if the move is legal.
				if (piece->isLegal(*this, newPosition)) {
					pieces[oldPosition.x][oldPosition.y] = nullptr;

					// En passant.
					if (pieces[newPosition.x][newPosition.y] == nullptr && (piece->notation() == 'p' || piece->notation() == 'P') && newPosition.x != oldPosition.x){
						if (piece->isWhite()) {
							delete pieces[newPosition.x][newPosition.y - 1];
							pieces[newPosition.x][newPosition.y - 1] = nullptr;
						} else {
							delete pieces[newPosition.x][newPosition.y + 1];
							pieces[newPosition.x][newPosition.y + 1] = nullptr;
						}
					}

					//Castling
					if (piece->notation() == 'k' || piece->notation() == 'K') {
						if (newPosition.x - oldPosition.x == 2){
							Piece* tempPiece = getPiece(Position(7, newPosition.y));
							pieces[7][newPosition.y] = nullptr;
							pieces[5][newPosition.y] = tempPiece;
							tempPiece->move(Position(5, newPosition.y));
						} else if (newPosition.x - oldPosition.x == -2) {
							Piece* tempPiece = getPiece(Position(0, newPosition.y));
							pieces[0][newPosition.y] = nullptr;
							pieces[3][newPosition.y] = tempPiece;
							tempPiece->move(Position(3, newPosition.y));
						}
					}

					// Delete captured enemy piece.
					if (pieces[newPosition.x][newPosition.y] != nullptr)
						delete pieces[newPosition.x][newPosition.y];

					// Update pieces and piece position
					pieces[newPosition.x][newPosition.y] = piece;
					piece->move(newPosition);

					// Promote pawns
					if(newPosition.y == 7 || newPosition.y == 0){
						if (piece->notation() == 'p' || piece->notation() == 'P'){
							needsToPromote = true;
						}
					}

					// Set and reset lastMovedPiece
					if (lastMovedPawn != nullptr){
						if (lastMovedPawn->getLastMoveWasDouble()){
							//lastMovedPawn->resetLastMoveWasDouble(); //orsakar krasch..
						}
					}
					lastMovedPawn = dynamic_cast<Pawn*>(getPiece(newPosition));

					turn++;
					if (state == GameState::BLACKPLAYS)
						state = GameState::WHITEPLAYS;
					else
						state = GameState::BLACKPLAYS;
					return true;
				}
			}
		}

		return false;
	}

	void Board::promotePawn(Piece* pawn, PromoteTypes type) {
		Position position = pawn->getPosition();
		bool white = pawn->isWhite();
		delete pawn;

		switch (type) {
		case PromoteTypes::QUEEN:
			pieces[position.x][position.y] = new Queen(position, white);
			break;
		case PromoteTypes::ROOK:
			pieces[position.x][position.y] = new Rook(position, white);
			break;
		case PromoteTypes::BISHOP:
			pieces[position.x][position.y] = new Bishop(position, white);
			break;
		case PromoteTypes::KNIGHT:
			pieces[position.x][position.y] = new Knight(position, white);
			break;
		}
	}

	King* Board::getKing(bool white) const {
		if (white) {
			return whiteKing;
		} else {
			return blackKing;
		}
	}
}<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexSQL.cxx
 ** Lexer for SQL.
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
	char s[100];
	bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
	for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
		s[i] = static_cast<char>(tolower(styler[start + i]));
		s[i + 1] = '\0';
	}
	char chAttr = SCE_C_IDENTIFIER;
	if (wordIsNumber)
		chAttr = SCE_C_NUMBER;
	else {
		if (keywords.InList(s))
			chAttr = SCE_C_WORD;
	}
	styler.ColourTo(end, chAttr);
}

static void ColouriseSQLDoc(unsigned int startPos, int length,
                            int initStyle, WordList *keywordlists[], Accessor &styler) {

	WordList &keywords = *keywordlists[0];

	styler.StartAt(startPos);

	bool fold = styler.GetPropertyInt("fold") != 0;
	int lineCurrent = styler.GetLine(startPos);
	int spaceFlags = 0;

	int state = initStyle;
	char chPrev = ' ';
	char chNext = styler[startPos];
	styler.StartSegment(startPos);
	unsigned int lengthDoc = startPos + length;
	for (unsigned int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
			int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
			int lev = indentCurrent;
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
				if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				}
			}
			if (fold) {
				styler.SetLevel(lineCurrent, lev);
			}
		}

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			chPrev = ' ';
			i += 1;
			continue;
		}

		if (state == SCE_C_DEFAULT) {
			if (iswordstart(ch)) {
				styler.ColourTo(i - 1, state);
				state = SCE_C_WORD;
			} else if (ch == '/' && chNext == '*') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENT;
			} else if (ch == '-' && chNext == '-') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENTLINE;
			} else if (ch == '\'') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_CHARACTER;
			} else if (ch == '"') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_STRING;
			} else if (isoperator(ch)) {
				styler.ColourTo(i - 1, state);
				styler.ColourTo(i, SCE_C_OPERATOR);
			}
		} else if (state == SCE_C_WORD) {
			if (!iswordchar(ch)) {
				classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler);
				state = SCE_C_DEFAULT;
				if (ch == '/' && chNext == '*') {
					state = SCE_C_COMMENT;
				} else if (ch == '-' && chNext == '-') {
					state = SCE_C_COMMENTLINE;
				} else if (ch == '\'') {
					state = SCE_C_CHARACTER;
				} else if (ch == '"') {
					state = SCE_C_STRING;
				} else if (isoperator(ch)) {
					styler.ColourTo(i, SCE_C_OPERATOR);
				}
			}
		} else {
			if (state == SCE_C_COMMENT) {
				if (ch == '/' && chPrev == '*') {
					if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) &&
					    (styler.GetStartSegment() == startPos)))) {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
					}
				}
			} else if (state == SCE_C_COMMENTLINE) {
				if (ch == '\r' || ch == '\n') {
					styler.ColourTo(i - 1, state);
					state = SCE_C_DEFAULT;
				}
			} else if (state == SCE_C_CHARACTER) {
				if (ch == '\'') {
					if ( chNext == '\'' ) {
						i++;
					} else {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
						i++;
					}
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				}
			} else if (state == SCE_C_STRING) {
				if (ch == '"') {
					if (chNext == '"') {
						i++;
					} else {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
						i++;
					}
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				}
			}
			if (state == SCE_C_DEFAULT) {    // One of the above succeeded
				if (ch == '/' && chNext == '*') {
					state = SCE_C_COMMENT;
				} else if (ch == '-' && chNext == '-') {
					state = SCE_C_COMMENTLINE;
				} else if (ch == '\'') {
					state = SCE_C_CHARACTER;
				} else if (ch == '"') {
					state = SCE_C_STRING;
				} else if (iswordstart(ch)) {
					state = SCE_C_WORD;
				} else if (isoperator(ch)) {
					styler.ColourTo(i, SCE_C_OPERATOR);
				}
			}
		}
		chPrev = ch;
	}
	styler.ColourTo(lengthDoc - 1, state);
}

static const char * const sqlWordListDesc[] = {
	"Keywords",
	0
};

LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc);
<commit_msg>Allow backslash quoting in strings when sql.backslash.escapes turned on.<commit_after>// Scintilla source code edit control
/** @file LexSQL.cxx
 ** Lexer for SQL.
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
	char s[100];
	bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
	for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
		s[i] = static_cast<char>(tolower(styler[start + i]));
		s[i + 1] = '\0';
	}
	char chAttr = SCE_C_IDENTIFIER;
	if (wordIsNumber)
		chAttr = SCE_C_NUMBER;
	else {
		if (keywords.InList(s))
			chAttr = SCE_C_WORD;
	}
	styler.ColourTo(end, chAttr);
}

static void ColouriseSQLDoc(unsigned int startPos, int length,
                            int initStyle, WordList *keywordlists[], Accessor &styler) {

	WordList &keywords = *keywordlists[0];

	styler.StartAt(startPos);

	bool fold = styler.GetPropertyInt("fold") != 0;
	bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
	int lineCurrent = styler.GetLine(startPos);
	int spaceFlags = 0;

	int state = initStyle;
	char chPrev = ' ';
	char chNext = styler[startPos];
	styler.StartSegment(startPos);
	unsigned int lengthDoc = startPos + length;
	for (unsigned int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
			int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
			int lev = indentCurrent;
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
				if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				}
			}
			if (fold) {
				styler.SetLevel(lineCurrent, lev);
			}
		}

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			chPrev = ' ';
			i += 1;
			continue;
		}

		if (state == SCE_C_DEFAULT) {
			if (iswordstart(ch)) {
				styler.ColourTo(i - 1, state);
				state = SCE_C_WORD;
			} else if (ch == '/' && chNext == '*') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENT;
			} else if (ch == '-' && chNext == '-') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENTLINE;
			} else if (ch == '#') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_COMMENTLINEDOC;
			} else if (ch == '\'') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_CHARACTER;
			} else if (ch == '"') {
				styler.ColourTo(i - 1, state);
				state = SCE_C_STRING;
			} else if (isoperator(ch)) {
				styler.ColourTo(i - 1, state);
				styler.ColourTo(i, SCE_C_OPERATOR);
			}
		} else if (state == SCE_C_WORD) {
			if (!iswordchar(ch)) {
				classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler);
				state = SCE_C_DEFAULT;
				if (ch == '/' && chNext == '*') {
					state = SCE_C_COMMENT;
				} else if (ch == '-' && chNext == '-') {
					state = SCE_C_COMMENTLINE;
				} else if (ch == '#') {
					state = SCE_C_COMMENTLINEDOC;
				} else if (ch == '\'') {
					state = SCE_C_CHARACTER;
				} else if (ch == '"') {
					state = SCE_C_STRING;
				} else if (isoperator(ch)) {
					styler.ColourTo(i, SCE_C_OPERATOR);
				}
			}
		} else {
			if (state == SCE_C_COMMENT) {
				if (ch == '/' && chPrev == '*') {
					if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) &&
					    (styler.GetStartSegment() == startPos)))) {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
					}
				}
			} else if (state == SCE_C_COMMENTLINE || state == SCE_C_COMMENTLINEDOC) {
				if (ch == '\r' || ch == '\n') {
					styler.ColourTo(i - 1, state);
					state = SCE_C_DEFAULT;
				}
			} else if (state == SCE_C_CHARACTER) {
				if (sqlBackslashEscapes && ch == '\\') {
					i++;
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				} else if (ch == '\'') {
					if (chNext == '\'') {
						i++;
					} else {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
						i++;
					}
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				}
			} else if (state == SCE_C_STRING) {
				if (ch == '"') {
					if (chNext == '"') {
						i++;
					} else {
						styler.ColourTo(i, state);
						state = SCE_C_DEFAULT;
						i++;
					}
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				}
			}
			if (state == SCE_C_DEFAULT) {    // One of the above succeeded
				if (ch == '/' && chNext == '*') {
					state = SCE_C_COMMENT;
				} else if (ch == '-' && chNext == '-') {
					state = SCE_C_COMMENTLINE;
				} else if (ch == '#') {
					state = SCE_C_COMMENTLINEDOC;
				} else if (ch == '\'') {
					state = SCE_C_CHARACTER;
				} else if (ch == '"') {
					state = SCE_C_STRING;
				} else if (iswordstart(ch)) {
					state = SCE_C_WORD;
				} else if (isoperator(ch)) {
					styler.ColourTo(i, SCE_C_OPERATOR);
				}
			}
		}
		chPrev = ch;
	}
	styler.ColourTo(lengthDoc - 1, state);
}

static const char * const sqlWordListDesc[] = {
	"Keywords",
	0
};

LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc);
<|endoftext|>


<commit_before>// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_utils/posix_wrapper/file_lock.hpp"
#include "iceoryx_utils/cxx/smart_c.hpp"
#include "iceoryx_utils/platform/errno.hpp"
#include "iceoryx_utils/platform/fcntl.hpp"
#include "iceoryx_utils/platform/file.hpp"
#include "iceoryx_utils/platform/stat.hpp"
#include "iceoryx_utils/platform/unistd.hpp"

#include "iceoryx_utils/platform/platform_correction.hpp"

namespace iox
{
namespace posix
{
FileLock::FileLock(const FileName_t& name) noexcept
    : m_name(name)
{
    initializeFileLock().and_then([this]() { this->m_isInitialized = true; }).or_else([this](FileLockError& error) {
        this->m_isInitialized = false;
        this->m_errorValue = error;
    });
}

cxx::expected<FileLockError> FileLock::initializeFileLock() noexcept
{
    if (m_name.empty())
    {
        return cxx::error<FileLockError>(FileLockError::NO_FILE_NAME_PROVIDED);
    }
    PathName_t fullPath(PATH_PREFIX + m_name + ".lock");
    constexpr int createFileForReadWrite = O_CREAT | O_RDWR;
    mode_t userReadWriteAccess = S_IRUSR | S_IWUSR;

    auto openCall = cxx::makeSmartC(iox_open,
                                    cxx::ReturnMode::PRE_DEFINED_ERROR_CODE,
                                    {ERROR_CODE},
                                    {},
                                    fullPath.c_str(),
                                    createFileForReadWrite,
                                    userReadWriteAccess);

    if (openCall.hasErrors())
    {
        return cxx::error<FileLockError>(convertErrnoToFileLockError(openCall.getErrNum()));
    }
    else
    {
        m_fd = openCall.getReturnValue();

        auto lockCall = cxx::makeSmartC(
            iox_flock, cxx::ReturnMode::PRE_DEFINED_ERROR_CODE, {ERROR_CODE}, {EWOULDBLOCK}, m_fd, LOCK_EX | LOCK_NB);

        if (lockCall.hasErrors())
        {
            closeFileDescriptor().or_else([](auto) {
                std::cerr << "Unable to close file lock in error related cleanup during initialization." << std::endl;
            });
            // possible errors in closeFileDescriptor() are masked and we inform the user about the actual error
            return cxx::error<FileLockError>(convertErrnoToFileLockError(openCall.getErrNum()));
        }
        else if (lockCall.getErrNum() == EWOULDBLOCK)
        {
            closeFileDescriptor().or_else([](auto) {
                std::cerr << "Unable to close file lock in error related cleanup during initialization." << std::endl;
            });
            // possible errors in closeFileDescriptor() are masked and we inform the user about the actual error
            return cxx::error<FileLockError>(FileLockError::LOCKED_BY_OTHER_PROCESS);
        }
    }
    return cxx::success<>();
}

FileLock::FileLock(FileLock&& rhs) noexcept
{
    *this = std::move(rhs);
}

FileLock& FileLock::operator=(FileLock&& rhs) noexcept
{
    if (this != &rhs)
    {
        if (closeFileDescriptor().has_error())
        {
            std::cerr << "Unable to cleanup file lock \"" << m_name
                      << "\" in the move constructor/move assingment operator" << std::endl;
        }

        CreationPattern_t::operator=(std::move(rhs));

        m_name = std::move(rhs.m_name);
        m_fd = std::move(rhs.m_fd);

        rhs.m_name.assign("");
        rhs.m_fd = INVALID_FD;
    }

    return *this;
}

FileLock::~FileLock() noexcept
{
    if (closeFileDescriptor().has_error())
    {
        std::cerr << "unable to cleanup file lock \"" << m_name << "\" in the destructor" << std::endl;
    }
}

cxx::expected<FileLockError> FileLock::closeFileDescriptor() noexcept
{
    if (isInitialized() && (m_fd != INVALID_FD))
    {
        auto closeCall = cxx::makeSmartC(iox_close, cxx::ReturnMode::PRE_DEFINED_ERROR_CODE, {ERROR_CODE}, {}, m_fd);

        m_fd = INVALID_FD;
        m_isInitialized = false;

        if (!closeCall.hasErrors())
        {
            return cxx::success<void>();
        }
        else
        {
            return cxx::error<FileLockError>(convertErrnoToFileLockError(closeCall.getErrNum()));
        }
    }
    return cxx::success<>();
}

FileLockError FileLock::convertErrnoToFileLockError(const int32_t errnum) const noexcept
{
    switch (errnum)
    {
    case EACCES:
    {
        std::cerr << "permission to access file denied \"" << m_name << "\"" << std::endl;
        return FileLockError::ACCESS_DENIED;
    }
    case EDQUOT:
    {
        std::cerr << "user disk quota exhausted for file \"" << m_name << "\"" << std::endl;
        return FileLockError::QUOTA_EXHAUSTED;
    }
    case EFAULT:
    {
        std::cerr << "outside address space error for file \"" << m_name << "\"" << std::endl;
        return FileLockError::ACCESS_DENIED;
    }
    case EFBIG:
    case EOVERFLOW:
    {
        std::cerr << "file \"" << m_name << "\""
                  << " is too large to be openend" << std::endl;
        return FileLockError::FILE_TOO_LARGE;
    }
    case EINVAL:
    {
        std::cerr << "provided invalid characters in file \"" << m_name << "\"" << std::endl;
        return FileLockError::INVALID_CHARACTERS_IN_FILE_NAME;
    }
    case ELOOP:
    {
        std::cerr << "too many symbolic links for file \"" << m_name << "\"" << std::endl;
        return FileLockError::INVALID_FILE_NAME;
    }
    case EMFILE:
    {
        std::cerr << "process limit reached for file \"" << m_name << "\"" << std::endl;
        return FileLockError::PROCESS_LIMIT;
    }
    case ENFILE:
    {
        std::cerr << "system limit reached for file \"" << m_name << "\"" << std::endl;
        return FileLockError::SYSTEM_LIMIT;
    }
    case ENODEV:
    {
        std::cerr << "permission to access file denied \"" << m_name << "\"" << std::endl;
        return FileLockError::ACCESS_DENIED;
    }
    case ENOENT:
    {
        std::cerr << "directory \"" << PATH_PREFIX << "\""
                  << " does not exist. Please create it as described in the filesystem hierarchy standard."
                  << std::endl;
        return FileLockError::NO_SUCH_DIRECTORY;
    }
    case ENOMEM:
    {
        std::cerr << "out of memory for file \"" << m_name << "\"" << std::endl;
        return FileLockError::OUT_OF_MEMORY;
    }
    case ENOSPC:
    {
        std::cerr << "Device has no space for file \"" << m_name << "\"" << std::endl;
        return FileLockError::QUOTA_EXHAUSTED;
    }
    case ENOSYS:
    {
        std::cerr << "open() not implemented for filesystem to \"" << m_name << "\"" << std::endl;
        return FileLockError::SYS_CALL_NOT_IMPLEMENTED;
    }
    case ENXIO:
    {
        std::cerr << "\"" << m_name << "\""
                  << " is a special file and no corresponding device exists" << std::endl;
        return FileLockError::SPECIAL_FILE;
    }
    case EPERM:
    {
        std::cerr << "permission to access file denied \"" << m_name << "\"" << std::endl;
        return FileLockError::ACCESS_DENIED;
    }
    case EROFS:
    {
        std::cerr << "read only error for file \"" << m_name << "\"" << std::endl;
        return FileLockError::INVALID_FILE_NAME;
    }
    case ETXTBSY:
    {
        std::cerr << "write access requested for file \"" << m_name << "\""
                  << " in use" << std::endl;
        return FileLockError::FILE_IN_USE;
    }
    case EWOULDBLOCK:
    {
        // no error message needed since this is a normal use case
        return FileLockError::LOCKED_BY_OTHER_PROCESS;
    }
    case ENOLCK:
    {
        std::cerr << "system limit for locks reached for file \"" << m_name << "\"" << std::endl;
        return FileLockError::SYSTEM_LIMIT;
    }
    case EIO:
    {
        std::cerr << "I/O for file \"" << m_name << "\"" << std::endl;
        return FileLockError::I_O_ERROR;
    }
    default:
    {
        std::cerr << "internal logic error in file \"" << m_name << "\" occurred" << std::endl;
        return FileLockError::INTERNAL_LOGIC_ERROR;
    }
    }
}

} // namespace posix
} // namespace iox
<commit_msg>iox-#418 replaced smart_c with posixCall in file_lock<commit_after>// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_utils/posix_wrapper/file_lock.hpp"
#include "iceoryx_utils/platform/errno.hpp"
#include "iceoryx_utils/platform/fcntl.hpp"
#include "iceoryx_utils/platform/file.hpp"
#include "iceoryx_utils/platform/stat.hpp"
#include "iceoryx_utils/platform/unistd.hpp"
#include "iceoryx_utils/posix_wrapper/posix_call.hpp"

#include "iceoryx_utils/platform/platform_correction.hpp"

namespace iox
{
namespace posix
{
FileLock::FileLock(const FileName_t& name) noexcept
    : m_name(name)
{
    initializeFileLock().and_then([this]() { this->m_isInitialized = true; }).or_else([this](FileLockError& error) {
        this->m_isInitialized = false;
        this->m_errorValue = error;
    });
}

cxx::expected<FileLockError> FileLock::initializeFileLock() noexcept
{
    if (m_name.empty())
    {
        return cxx::error<FileLockError>(FileLockError::NO_FILE_NAME_PROVIDED);
    }
    PathName_t fullPath(PATH_PREFIX + m_name + ".lock");
    constexpr int createFileForReadWrite = O_CREAT | O_RDWR;
    mode_t userReadWriteAccess = S_IRUSR | S_IWUSR;

    auto openCall = posixCall(iox_open)(fullPath.c_str(), createFileForReadWrite, userReadWriteAccess)
                        .failureReturnValue(ERROR_CODE)
                        .evaluate()
                        .and_then([this](auto& r) { m_fd = r.value; });

    if (openCall.has_error())
    {
        return cxx::error<FileLockError>(convertErrnoToFileLockError(openCall.get_error().errnum));
    }

    auto lockCall = posixCall(iox_flock)(m_fd, LOCK_EX | LOCK_NB)
                        .failureReturnValue(ERROR_CODE)
                        .evaluateWithIgnoredErrnos(EWOULDBLOCK);

    if (lockCall.has_error())
    {
        closeFileDescriptor().or_else([](auto) {
            std::cerr << "Unable to close file lock in error related cleanup during initialization." << std::endl;
        });
        // possible errors in closeFileDescriptor() are masked and we inform the user about the actual error
        return cxx::error<FileLockError>(convertErrnoToFileLockError(openCall.get_error().errnum));
    }
    else if (lockCall->errnum == EWOULDBLOCK)
    {
        closeFileDescriptor().or_else([](auto) {
            std::cerr << "Unable to close file lock in error related cleanup during initialization." << std::endl;
        });
        // possible errors in closeFileDescriptor() are masked and we inform the user about the actual error
        return cxx::error<FileLockError>(FileLockError::LOCKED_BY_OTHER_PROCESS);
    }

    return cxx::success<>();
}

FileLock::FileLock(FileLock&& rhs) noexcept
{
    *this = std::move(rhs);
}

FileLock& FileLock::operator=(FileLock&& rhs) noexcept
{
    if (this != &rhs)
    {
        if (closeFileDescriptor().has_error())
        {
            std::cerr << "Unable to cleanup file lock \"" << m_name
                      << "\" in the move constructor/move assingment operator" << std::endl;
        }

        CreationPattern_t::operator=(std::move(rhs));

        m_name = std::move(rhs.m_name);
        m_fd = std::move(rhs.m_fd);

        rhs.m_name.assign("");
        rhs.m_fd = INVALID_FD;
    }

    return *this;
}

FileLock::~FileLock() noexcept
{
    if (closeFileDescriptor().has_error())
    {
        std::cerr << "unable to cleanup file lock \"" << m_name << "\" in the destructor" << std::endl;
    }
}

cxx::expected<FileLockError> FileLock::closeFileDescriptor() noexcept
{
    if (isInitialized() && (m_fd != INVALID_FD))
    {
        auto closeCall = posixCall(iox_close)(m_fd).failureReturnValue(ERROR_CODE).evaluate();

        m_fd = INVALID_FD;
        m_isInitialized = false;

        if (!closeCall.has_error())
        {
            return cxx::success<void>();
        }
        else
        {
            return cxx::error<FileLockError>(convertErrnoToFileLockError(closeCall.get_error().errnum));
        }
    }
    return cxx::success<>();
}

FileLockError FileLock::convertErrnoToFileLockError(const int32_t errnum) const noexcept
{
    switch (errnum)
    {
    case EACCES:
    {
        std::cerr << "permission to access file denied \"" << m_name << "\"" << std::endl;
        return FileLockError::ACCESS_DENIED;
    }
    case EDQUOT:
    {
        std::cerr << "user disk quota exhausted for file \"" << m_name << "\"" << std::endl;
        return FileLockError::QUOTA_EXHAUSTED;
    }
    case EFAULT:
    {
        std::cerr << "outside address space error for file \"" << m_name << "\"" << std::endl;
        return FileLockError::ACCESS_DENIED;
    }
    case EFBIG:
    case EOVERFLOW:
    {
        std::cerr << "file \"" << m_name << "\""
                  << " is too large to be openend" << std::endl;
        return FileLockError::FILE_TOO_LARGE;
    }
    case EINVAL:
    {
        std::cerr << "provided invalid characters in file \"" << m_name << "\"" << std::endl;
        return FileLockError::INVALID_CHARACTERS_IN_FILE_NAME;
    }
    case ELOOP:
    {
        std::cerr << "too many symbolic links for file \"" << m_name << "\"" << std::endl;
        return FileLockError::INVALID_FILE_NAME;
    }
    case EMFILE:
    {
        std::cerr << "process limit reached for file \"" << m_name << "\"" << std::endl;
        return FileLockError::PROCESS_LIMIT;
    }
    case ENFILE:
    {
        std::cerr << "system limit reached for file \"" << m_name << "\"" << std::endl;
        return FileLockError::SYSTEM_LIMIT;
    }
    case ENODEV:
    {
        std::cerr << "permission to access file denied \"" << m_name << "\"" << std::endl;
        return FileLockError::ACCESS_DENIED;
    }
    case ENOENT:
    {
        std::cerr << "directory \"" << PATH_PREFIX << "\""
                  << " does not exist. Please create it as described in the filesystem hierarchy standard."
                  << std::endl;
        return FileLockError::NO_SUCH_DIRECTORY;
    }
    case ENOMEM:
    {
        std::cerr << "out of memory for file \"" << m_name << "\"" << std::endl;
        return FileLockError::OUT_OF_MEMORY;
    }
    case ENOSPC:
    {
        std::cerr << "Device has no space for file \"" << m_name << "\"" << std::endl;
        return FileLockError::QUOTA_EXHAUSTED;
    }
    case ENOSYS:
    {
        std::cerr << "open() not implemented for filesystem to \"" << m_name << "\"" << std::endl;
        return FileLockError::SYS_CALL_NOT_IMPLEMENTED;
    }
    case ENXIO:
    {
        std::cerr << "\"" << m_name << "\""
                  << " is a special file and no corresponding device exists" << std::endl;
        return FileLockError::SPECIAL_FILE;
    }
    case EPERM:
    {
        std::cerr << "permission to access file denied \"" << m_name << "\"" << std::endl;
        return FileLockError::ACCESS_DENIED;
    }
    case EROFS:
    {
        std::cerr << "read only error for file \"" << m_name << "\"" << std::endl;
        return FileLockError::INVALID_FILE_NAME;
    }
    case ETXTBSY:
    {
        std::cerr << "write access requested for file \"" << m_name << "\""
                  << " in use" << std::endl;
        return FileLockError::FILE_IN_USE;
    }
    case EWOULDBLOCK:
    {
        // no error message needed since this is a normal use case
        return FileLockError::LOCKED_BY_OTHER_PROCESS;
    }
    case ENOLCK:
    {
        std::cerr << "system limit for locks reached for file \"" << m_name << "\"" << std::endl;
        return FileLockError::SYSTEM_LIMIT;
    }
    case EIO:
    {
        std::cerr << "I/O for file \"" << m_name << "\"" << std::endl;
        return FileLockError::I_O_ERROR;
    }
    default:
    {
        std::cerr << "internal logic error in file \"" << m_name << "\" occurred" << std::endl;
        return FileLockError::INTERNAL_LOGIC_ERROR;
    }
    }
}

} // namespace posix
} // namespace iox
<|endoftext|>


<commit_before>#ifndef INSTRUMENTS_POPULATION_CSVInstrument
#define INSTRUMENTS_POPULATION_CSVInstrument

#include "../../core/instruments/PopulationInstrument.hpp"
#include <vector>
#include <map>
#include <sstream>
#include <string>

class CSVInstrument: public PopulationInstrument {
	private:

	protected:
	std::vector<std::string> header;
	bool headerWritten;

	CSVInstrument(PopulationNode* target, std::string outFile);

	template <typename T>
	void write(std::vector<T> values, T defaultValue);

	template <typename Val>
	void write(std::map<std::string, Val> values, Val defaultValue);

	void setHeader(std::vector<std::string> values);
	void addToHeader(std::string value);
	void addToHeader(std::vector<std::string> values);

	public:
};

template <typename T>
void CSVInstrument::write(std::vector<T> values, T defaultValue) {
	if (!this->headerWritten) {
		this->write(this->header, std::string());
		this->headerWritten = true;
	}

	std::stringstream ss;

	for (unsigned int i = 0; i < values.size() - 1; i++)
		ss << values[i] << ",";
	ss << values[values.size() - 1];

	if (values.size() < this->header.size()) {
		for (
			unsigned int i = values.size();
			i < this->header.size() - 1;
			i++
		) ss << defaultValue << ",";
		ss << defaultValue;
	}

	HierInstrument::write(ss.str());
}

template <typename Val>
void CSVInstrument::write(std::map<std::string, Val> values, Val defaultValue) {
	std::vector<Val> valuesToWrite;

	for (unsigned int i = 0; i < this->header.size(); i++) {
		auto it = values.find(this->header[i]);
		if (it != values.end()) {
			valuesToWrite.push_back(it->second);
		} else {
			valuesToWrite.push_back(defaultValue);
		}
	}

	this->write(valuesToWrite, defaultValue);
}

#endif
<commit_msg>[CSVInstrument]: Fixed infinite recursion and no newlines<commit_after>#ifndef INSTRUMENTS_POPULATION_CSVInstrument
#define INSTRUMENTS_POPULATION_CSVInstrument

#include "../../core/instruments/PopulationInstrument.hpp"
#include <vector>
#include <map>
#include <sstream>
#include <string>

class CSVInstrument: public PopulationInstrument {
	private:

	protected:
	std::vector<std::string> header;
	bool headerWritten;

	CSVInstrument(PopulationNode* target, std::string outFile);

	template <typename T>
	void write(std::vector<T> values, T defaultValue);

	template <typename Val>
	void write(std::map<std::string, Val> values, Val defaultValue);

	void setHeader(std::vector<std::string> values);
	void addToHeader(std::string value);
	void addToHeader(std::vector<std::string> values);

	public:
};

template <typename T>
void CSVInstrument::write(std::vector<T> values, T defaultValue) {
	if (!this->headerWritten) {
		this->headerWritten = true;
		this->write(this->header, std::string());
	}

	std::stringstream ss;

	for (unsigned int i = 0; i < values.size() - 1; i++)
		ss << values[i] << ",";
	ss << values[values.size() - 1];

	if (values.size() < this->header.size()) {
		for (
			unsigned int i = values.size();
			i < this->header.size() - 1;
			i++
		) ss << defaultValue << ",";
		ss << defaultValue;
	}
	ss << "\n";

	HierInstrument::write(ss.str());
}

template <typename Val>
void CSVInstrument::write(std::map<std::string, Val> values, Val defaultValue) {
	std::vector<Val> valuesToWrite;

	for (unsigned int i = 0; i < this->header.size(); i++) {
		auto it = values.find(this->header[i]);
		if (it != values.end()) {
			valuesToWrite.push_back(it->second);
		} else {
			valuesToWrite.push_back(defaultValue);
		}
	}

	this->write(valuesToWrite, defaultValue);
}

#endif
<|endoftext|>