<commit_before>#pragma once

#include <string>
#include <utility>
#include <ostream>
#include <vector>
#include <algorithm>

#include <integer_sequence.hpp>

#include "reflection_info.hpp"
#include "info_iterator.hpp"
#include "exceptions.hpp"

namespace shadow
{
class reflection_manager;

template <class InfoType, template <class> class... Policies>
class api_type_aggregator
    : public Policies<api_type_aggregator<InfoType, Policies...>>...
{
    friend class variable;

public:
    api_type_aggregator() : info_(nullptr), manager_(nullptr)
    {
    }

    api_type_aggregator(const InfoType* info, const reflection_manager* manager)
        : info_(info), manager_(manager)
    {
    }

    api_type_aggregator* operator->()
    {
        return this;
    }

    const api_type_aggregator* operator->() const
    {
        return this;
    }

public:
    const InfoType* info_;
    const reflection_manager* manager_;
};

template <class Derived>
class get_name_policy
{
public:
    std::string
    name() const
    {
        return (static_cast<const Derived*>(this))->info_->name;
    }
};

template <class Derived>
class get_size_policy
{
public:
    std::size_t
    size() const
    {
        return static_cast<const Derived*>(this)->info_->size;
    }
};

typedef api_type_aggregator<type_info, get_name_policy, get_size_policy> type_;

inline std::ostream&
operator<<(std::ostream& out, const type_& tp)
{
    out << tp.name();
    return out;
}

template <class Derived>
class get_type_policy
{
public:
    type_
    get_type() const
    {
        // retrieve type index
        const auto type_index =
            static_cast<const Derived*>(this)->info_->type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            type_index);
    }
};

template <class Derived>
class get_num_parameters_policy
{
public:
    std::size_t
    num_parameters() const
    {
        return static_cast<const Derived*>(this)->info_->num_parameters;
    }
};

template <class Derived>
class get_parameter_types_policy
{
public:
    typedef indexed_info_iterator_<const type_info, const type_>
        const_parameter_type_iterator;

public:
    std::pair<const_parameter_type_iterator, const_parameter_type_iterator>
    parameter_types() const;
};

typedef api_type_aggregator<constructor_info,
                            get_type_policy,
                            get_num_parameters_policy,
                            get_parameter_types_policy>
    constructor_;

inline std::ostream&
operator<<(std::ostream& out, const constructor_& con)
{
    out << con.get_type().name() << '(';

    const auto num_params = con.num_parameters();

    if(num_params > 0)
    {
        auto param_pair = con.parameter_types();
        out << *param_pair.first;

        for(++param_pair.first; param_pair.first != param_pair.second;
            ++param_pair.first)
        {
            out << ", " << *param_pair.first;
        }
    }

    out << ')';

    return out;
}

template <class Derived>
class get_from_type_policy
{
public:
    type_
    from_type() const
    {
        const auto from_type_index =
            static_cast<const Derived*>(this)->info_->from_type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            from_type_index);
    }
};

template <class Derived>
class get_to_type_policy
{
public:
    type_
    to_type() const
    {
        const auto to_type_index =
            static_cast<const Derived*>(this)->info_->to_type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            to_type_index);
    }
};

typedef api_type_aggregator<conversion_info,
                            get_from_type_policy,
                            get_to_type_policy>
    type_conversion_;

template <class Derived>
class get_return_type_policy
{
public:
    type_
    return_type() const
    {
        const auto ret_type_index =
            static_cast<const Derived*>(this)->info_->return_type_index;
        return static_cast<const Derived*>(this)->manager_->type_by_index(
            ret_type_index);
    }
};

template <class Derived>
class get_object_type_policy
{
public:
    type_
    object_type() const
    {
        const auto object_type_index =
            static_cast<const Derived*>(this)->info_->object_type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            object_type_index);
    }
};

typedef api_type_aggregator<member_function_info,
                            get_name_policy,
                            get_num_parameters_policy,
                            get_parameter_types_policy,
                            get_return_type_policy,
                            get_object_type_policy>
    member_function_;

inline std::ostream&
operator<<(std::ostream& out, const member_function_& mf)
{
    out << mf.return_type() << " " << mf.object_type() << "::" << mf.name()
        << "(";

    if(mf.num_parameters() > 0)
    {
        auto param_pair = mf.parameter_types();
        out << *param_pair.first;

        for(++param_pair.first; param_pair.first != param_pair.second;
            ++param_pair.first)
        {
            out << ", " << *param_pair.first;
        }
    }

    out << ')';

    return out;
}

typedef api_type_aggregator<member_variable_info,
                            get_name_policy,
                            get_object_type_policy,
                            get_type_policy>
    member_variable_;

inline std::ostream&
operator<<(std::ostream& out, const member_variable_& mv)
{
    out << mv.get_type() << " " << mv.object_type() << "::" << mv.name();

    return out;
}

typedef api_type_aggregator<string_serialization_info, get_type_policy>
    string_serializer_;

// holds one value with type/reflection information
class variable
{
    friend std::ostream& operator<<(std::ostream&, const variable&);
    friend std::istream& operator>>(std::istream&, variable&);

    template <class Derived>
    friend class call_free_function;

public:
    typedef indexed_info_iterator_<const member_function_info,
                                   const member_function_>
        member_function_iterator;

    typedef member_variable_ member_variable;
    typedef indexed_info_iterator_<const member_variable_info,
                                   const member_variable>
        member_variable_iterator;

public:
    variable() : value_(), type_index_(0), manager_(nullptr)
    {
    }

    variable(const any& value,
             std::size_t type_index,
             const reflection_manager* manager)
        : value_(value), type_index_(type_index), manager_(manager)
    {
    }

public:
    type_ type() const;

    std::pair<member_function_iterator, member_function_iterator>
    member_functions() const;

    std::pair<member_variable_iterator, member_variable_iterator>
    member_variables() const;

    variable
    get_member_variable(const member_variable& mv) const
    {
        auto bind_point = mv.info_->get_bind_point;

        return variable(bind_point(value_), mv.info_->type_index, manager_);
    }

    variable
    get_member_variable(member_variable_iterator mv_it) const
    {
        auto bind_point = mv_it->info_->get_bind_point;

        return variable(bind_point(value_), mv_it->info_->type_index, manager_);
    }

private:
    // holds type erased value
    any value_;
    // these identify the type erased value
    std::size_t type_index_;
    const reflection_manager* manager_;
};

template <class Derived>
class call_free_function
{
public:
    template <class... Args>
    variable
    call_static_unsafe(Args... args) const
    {
        const auto info = static_cast<const Derived*>(this)->info_;

        any arg_array[] = {args...};

        return variable(info->bind_point(arg_array),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    template <class TypeUniverseList, class... Args>
    variable
    call_static_safe(Args... args) const
    {
        const auto info = static_cast<const Derived*>(this)->info_;

        typedef metamusil::t_list::type_list<Args...> given_types;
        typedef metamusil::t_list::order_t<given_types, TypeUniverseList>
            given_types_indices;
        typedef metamusil::int_seq::integer_sequence_to_array<
            given_types_indices>
            given_types_index_array_holder;

        if(std::extent<decltype(
               given_types_index_array_holder::value)>::value !=
           info->num_parameters)
        {
            throw argument_error("wrong number of arguments");
        }

        for(auto i = 0; i < info->num_parameters; ++i)
        {
            if(given_types_index_array_holder::value[i] !=
               info->parameter_type_indices[i])
            {
                throw argument_error("wrong argument type");
            }
        }

        any arg_array[] = {args...};

        return variable(info->bind_point(arg_array),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    template <class Iterator>
    variable
    operator()(Iterator arg_begin, Iterator arg_end) const
    {

        const auto info = static_cast<const Derived*>(this)->info_;

        // construct argument buffer
        std::vector<any> arg_buffer;
        arg_buffer.reserve(info->num_parameters);

        std::transform(arg_begin,
                       arg_end,
                       std::back_inserter(arg_buffer),
                       [](const variable& var) { return var.value_; });

        // check arguments
        if(arg_buffer.size() != info->num_parameters)
        {
            throw argument_error("wrong number of arguments provided");
        }

        for(auto i = 0ul; i < info->num_parameters; ++i)
        {
            if(info->parameter_type_indices[i] != arg_begin->type_index_)
            {
                throw argument_error("wrong argument type");
            }

            ++arg_begin;
        }

        return variable(info->bind_point(arg_buffer.data()),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    variable
    operator()() const
    {
        const auto info = static_cast<const Derived*>(this)->info_;

        // check that function in fact takes no arguments
        if(info->num_parameters != 0)
        {
            throw argument_error("wrong number of arguments provided");
        }

        return variable(info->bind_point(nullptr),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    template <class Iterator>
    variable
    call_unsafe(Iterator arg_begin, Iterator arg_end) const
    {
        const auto info = static_cast<const Derived*>(this)->info_;
        std::vector<any> arg_buffer;
        arg_buffer.reserve(info->num_parameters);
        std::transform(arg_begin,
                       arg_end,
                       std::back_inserter(arg_buffer),
                       [](const variable& var) { return var.value_; });

        return variable(info->bind_point(arg_buffer.data()),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    template <class Iterator>
    variable
    call_with_conversion(Iterator arg_begin, Iterator arg_end) const
    {
        const auto info = static_cast<const Derived*>(this)->info_;

        const auto num_params = info->num_parameters;

        if(num_params != std::distance(arg_begin, arg_end))
        {
            throw argument_error("wrong number of arguments provided");
        }

        std::vector<any> arg_buffer;
        arg_buffer.reserve(num_params);

        std::transform(
            arg_begin,
            arg_end,
            info->parameter_type_indices,
            std::back_inserter(arg_buffer),
            [](const auto& var, const auto to_index) {
                const auto from_index = var.type_index_;
                const auto manager = var.manager_;

                auto found = std::find_if(
                    manager->conversion_info_indices_by_type_[from_index]
                        .begin(),
                    manager->conversion_info_indices_by_type_[from_index].end(),
                    [to_index, manager](auto converter_index) {
                        return manager->conversion_info_range_
                                   .first[converter_index]
                                   .to_type_index == to_index;
                    });

                if(found ==
                   manager->conversion_info_indices_by_type_[from_index].end())
                {
                    throw argument_error("conversion of argument not possible");
                }

                const auto found_conversion_index = *found;

                return manager->conversion_info_range_
                    .first[found_conversion_index]
                    .bind_point(var.value_);

            });

        return variable(info->bind_point(arg_buffer.data()),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }
};

typedef api_type_aggregator<free_function_info,
                            get_name_policy,
                            get_num_parameters_policy,
                            get_parameter_types_policy,
                            get_return_type_policy,
                            call_free_function>
    free_function_;

inline std::ostream&
operator<<(std::ostream& out, const free_function_& ff)
{
    out << ff.return_type() << ' ' << ff.name() << '(';

    if(ff.num_parameters() > 0)
    {
        auto param_pair = ff.parameter_types();
        out << *param_pair.first;

        for(++param_pair.first; param_pair.first != param_pair.second;
            ++param_pair.first)
        {
            out << ", " << *param_pair.first;
        }
    }

    out << ')';

    return out;
}
}
<commit_msg>Comment class 'variable' 	modified:   include/api_info_types.hpp<commit_after>#pragma once

#include <string>
#include <utility>
#include <ostream>
#include <vector>
#include <algorithm>

#include <integer_sequence.hpp>

#include "reflection_info.hpp"
#include "info_iterator.hpp"
#include "exceptions.hpp"

namespace shadow
{
class reflection_manager;

template <class InfoType, template <class> class... Policies>
class api_type_aggregator
    : public Policies<api_type_aggregator<InfoType, Policies...>>...
{
    friend class variable;

public:
    api_type_aggregator() : info_(nullptr), manager_(nullptr)
    {
    }

    api_type_aggregator(const InfoType* info, const reflection_manager* manager)
        : info_(info), manager_(manager)
    {
    }

    api_type_aggregator* operator->()
    {
        return this;
    }

    const api_type_aggregator* operator->() const
    {
        return this;
    }

public:
    const InfoType* info_;
    const reflection_manager* manager_;
};

template <class Derived>
class get_name_policy
{
public:
    std::string
    name() const
    {
        return (static_cast<const Derived*>(this))->info_->name;
    }
};

template <class Derived>
class get_size_policy
{
public:
    std::size_t
    size() const
    {
        return static_cast<const Derived*>(this)->info_->size;
    }
};

typedef api_type_aggregator<type_info, get_name_policy, get_size_policy> type_;

inline std::ostream&
operator<<(std::ostream& out, const type_& tp)
{
    out << tp.name();
    return out;
}

template <class Derived>
class get_type_policy
{
public:
    type_
    get_type() const
    {
        // retrieve type index
        const auto type_index =
            static_cast<const Derived*>(this)->info_->type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            type_index);
    }
};

template <class Derived>
class get_num_parameters_policy
{
public:
    std::size_t
    num_parameters() const
    {
        return static_cast<const Derived*>(this)->info_->num_parameters;
    }
};

template <class Derived>
class get_parameter_types_policy
{
public:
    typedef indexed_info_iterator_<const type_info, const type_>
        const_parameter_type_iterator;

public:
    std::pair<const_parameter_type_iterator, const_parameter_type_iterator>
    parameter_types() const;
};

typedef api_type_aggregator<constructor_info,
                            get_type_policy,
                            get_num_parameters_policy,
                            get_parameter_types_policy>
    constructor_;

inline std::ostream&
operator<<(std::ostream& out, const constructor_& con)
{
    out << con.get_type().name() << '(';

    const auto num_params = con.num_parameters();

    if(num_params > 0)
    {
        auto param_pair = con.parameter_types();
        out << *param_pair.first;

        for(++param_pair.first; param_pair.first != param_pair.second;
            ++param_pair.first)
        {
            out << ", " << *param_pair.first;
        }
    }

    out << ')';

    return out;
}

template <class Derived>
class get_from_type_policy
{
public:
    type_
    from_type() const
    {
        const auto from_type_index =
            static_cast<const Derived*>(this)->info_->from_type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            from_type_index);
    }
};

template <class Derived>
class get_to_type_policy
{
public:
    type_
    to_type() const
    {
        const auto to_type_index =
            static_cast<const Derived*>(this)->info_->to_type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            to_type_index);
    }
};

typedef api_type_aggregator<conversion_info,
                            get_from_type_policy,
                            get_to_type_policy>
    type_conversion_;

template <class Derived>
class get_return_type_policy
{
public:
    type_
    return_type() const
    {
        const auto ret_type_index =
            static_cast<const Derived*>(this)->info_->return_type_index;
        return static_cast<const Derived*>(this)->manager_->type_by_index(
            ret_type_index);
    }
};

template <class Derived>
class get_object_type_policy
{
public:
    type_
    object_type() const
    {
        const auto object_type_index =
            static_cast<const Derived*>(this)->info_->object_type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            object_type_index);
    }
};

typedef api_type_aggregator<member_function_info,
                            get_name_policy,
                            get_num_parameters_policy,
                            get_parameter_types_policy,
                            get_return_type_policy,
                            get_object_type_policy>
    member_function_;

inline std::ostream&
operator<<(std::ostream& out, const member_function_& mf)
{
    out << mf.return_type() << " " << mf.object_type() << "::" << mf.name()
        << "(";

    if(mf.num_parameters() > 0)
    {
        auto param_pair = mf.parameter_types();
        out << *param_pair.first;

        for(++param_pair.first; param_pair.first != param_pair.second;
            ++param_pair.first)
        {
            out << ", " << *param_pair.first;
        }
    }

    out << ')';

    return out;
}

typedef api_type_aggregator<member_variable_info,
                            get_name_policy,
                            get_object_type_policy,
                            get_type_policy>
    member_variable_;

inline std::ostream&
operator<<(std::ostream& out, const member_variable_& mv)
{
    out << mv.get_type() << " " << mv.object_type() << "::" << mv.name();

    return out;
}

typedef api_type_aggregator<string_serialization_info, get_type_policy>
    string_serializer_;

// holds one value with type/reflection information
class variable
{
    friend std::ostream& operator<<(std::ostream&, const variable&);
    friend std::istream& operator>>(std::istream&, variable&);

    template <class Derived>
    friend class call_free_function;

public:
    typedef indexed_info_iterator_<const member_function_info,
                                   const member_function_>
        member_function_iterator;

    typedef member_variable_ member_variable;
    typedef indexed_info_iterator_<const member_variable_info,
                                   const member_variable>
        member_variable_iterator;

public:
    // default constructor, constructs an empty variable of type index 0
    // corresponding to a type of 'void'
    variable() : value_(), type_index_(0), manager_(nullptr)
    {
    }

    // full constructor, typically invoked by reflection_manager or
    // static_create function template
    variable(const any& value,
             std::size_t type_index,
             const reflection_manager* manager)
        : value_(value), type_index_(type_index), manager_(manager)
    {
    }

public:
    // returns the type of the value held by the variable
    type_ type() const;

    // returns pair of iterators to all member functions of the type of value
    // held by variable
    std::pair<member_function_iterator, member_function_iterator>
    member_functions() const;

    // returns pair of iterators to all member variables of the type of value
    // held by the variable
    std::pair<member_variable_iterator, member_variable_iterator>
    member_variables() const;

    // return value of member variable represented by mv
    variable
    get_member_variable(const member_variable& mv) const
    {
        auto bind_point = mv.info_->get_bind_point;

        return variable(bind_point(value_), mv.info_->type_index, manager_);
    }

    // overload returns member variable represented by mv_it, an iterator to a
    // member_variable
    variable
    get_member_variable(member_variable_iterator mv_it) const
    {
        auto bind_point = mv_it->info_->get_bind_point;

        return variable(bind_point(value_), mv_it->info_->type_index, manager_);
    }

private:
    // holds type erased value
    any value_;
    // these identify the type erased value
    std::size_t type_index_;
    const reflection_manager* manager_;
};

template <class Derived>
class call_free_function
{
public:
    template <class... Args>
    variable
    call_static_unsafe(Args... args) const
    {
        const auto info = static_cast<const Derived*>(this)->info_;

        any arg_array[] = {args...};

        return variable(info->bind_point(arg_array),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    template <class TypeUniverseList, class... Args>
    variable
    call_static_safe(Args... args) const
    {
        const auto info = static_cast<const Derived*>(this)->info_;

        typedef metamusil::t_list::type_list<Args...> given_types;
        typedef metamusil::t_list::order_t<given_types, TypeUniverseList>
            given_types_indices;
        typedef metamusil::int_seq::integer_sequence_to_array<
            given_types_indices>
            given_types_index_array_holder;

        if(std::extent<decltype(
               given_types_index_array_holder::value)>::value !=
           info->num_parameters)
        {
            throw argument_error("wrong number of arguments");
        }

        for(auto i = 0; i < info->num_parameters; ++i)
        {
            if(given_types_index_array_holder::value[i] !=
               info->parameter_type_indices[i])
            {
                throw argument_error("wrong argument type");
            }
        }

        any arg_array[] = {args...};

        return variable(info->bind_point(arg_array),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    template <class Iterator>
    variable
    operator()(Iterator arg_begin, Iterator arg_end) const
    {

        const auto info = static_cast<const Derived*>(this)->info_;

        // construct argument buffer
        std::vector<any> arg_buffer;
        arg_buffer.reserve(info->num_parameters);

        std::transform(arg_begin,
                       arg_end,
                       std::back_inserter(arg_buffer),
                       [](const variable& var) { return var.value_; });

        // check arguments
        if(arg_buffer.size() != info->num_parameters)
        {
            throw argument_error("wrong number of arguments provided");
        }

        for(auto i = 0ul; i < info->num_parameters; ++i)
        {
            if(info->parameter_type_indices[i] != arg_begin->type_index_)
            {
                throw argument_error("wrong argument type");
            }

            ++arg_begin;
        }

        return variable(info->bind_point(arg_buffer.data()),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    variable
    operator()() const
    {
        const auto info = static_cast<const Derived*>(this)->info_;

        // check that function in fact takes no arguments
        if(info->num_parameters != 0)
        {
            throw argument_error("wrong number of arguments provided");
        }

        return variable(info->bind_point(nullptr),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    template <class Iterator>
    variable
    call_unsafe(Iterator arg_begin, Iterator arg_end) const
    {
        const auto info = static_cast<const Derived*>(this)->info_;
        std::vector<any> arg_buffer;
        arg_buffer.reserve(info->num_parameters);
        std::transform(arg_begin,
                       arg_end,
                       std::back_inserter(arg_buffer),
                       [](const variable& var) { return var.value_; });

        return variable(info->bind_point(arg_buffer.data()),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }

    template <class Iterator>
    variable
    call_with_conversion(Iterator arg_begin, Iterator arg_end) const
    {
        const auto info = static_cast<const Derived*>(this)->info_;

        const auto num_params = info->num_parameters;

        if(num_params != std::distance(arg_begin, arg_end))
        {
            throw argument_error("wrong number of arguments provided");
        }

        std::vector<any> arg_buffer;
        arg_buffer.reserve(num_params);

        std::transform(
            arg_begin,
            arg_end,
            info->parameter_type_indices,
            std::back_inserter(arg_buffer),
            [](const auto& var, const auto to_index) {
                const auto from_index = var.type_index_;
                const auto manager = var.manager_;

                auto found = std::find_if(
                    manager->conversion_info_indices_by_type_[from_index]
                        .begin(),
                    manager->conversion_info_indices_by_type_[from_index].end(),
                    [to_index, manager](auto converter_index) {
                        return manager->conversion_info_range_
                                   .first[converter_index]
                                   .to_type_index == to_index;
                    });

                if(found ==
                   manager->conversion_info_indices_by_type_[from_index].end())
                {
                    throw argument_error("conversion of argument not possible");
                }

                const auto found_conversion_index = *found;

                return manager->conversion_info_range_
                    .first[found_conversion_index]
                    .bind_point(var.value_);

            });

        return variable(info->bind_point(arg_buffer.data()),
                        info->return_type_index,
                        static_cast<const Derived*>(this)->manager_);
    }
};

typedef api_type_aggregator<free_function_info,
                            get_name_policy,
                            get_num_parameters_policy,
                            get_parameter_types_policy,
                            get_return_type_policy,
                            call_free_function>
    free_function_;

inline std::ostream&
operator<<(std::ostream& out, const free_function_& ff)
{
    out << ff.return_type() << ' ' << ff.name() << '(';

    if(ff.num_parameters() > 0)
    {
        auto param_pair = ff.parameter_types();
        out << *param_pair.first;

        for(++param_pair.first; param_pair.first != param_pair.second;
            ++param_pair.first)
        {
            out << ", " << *param_pair.first;
        }
    }

    out << ')';

    return out;
}
}
<|endoftext|>


<commit_before>#include "stdsneezy.h"
#include "database.h"

// create table poll (poll_id int primary key, descr varchar(127), status varchar(8));
// create table poll_option (option_id int, poll_id int, descr varchar(127), primary key (option_id, poll_id));
// create table poll_vote (account varchar(80), poll_id int, option_id int, primary key (account, poll_id, option_id));

int ballotBox(TBeing *ch, cmdTypeT cmd, const char *argument, TObj *o, TObj *)
{
  TDatabase db(DB_SNEEZY);
  sstring arg=argument;

  if(cmd==CMD_LIST){
    if(arg.empty()){
      /////////// list all polls
      ch->sendTo(COLOR_BASIC, fmt("You have a look at %s...\n\r") %
		 o->getName());

      db.query("select poll_id, descr from poll where status='open' order by poll_id");

      if(db.fetchRow()){
	ch->sendTo(COLOR_BASIC, "These polls are open:\n\r");
	do {
	  ch->sendTo(COLOR_BASIC, fmt("%-2i| <r>%s<1>\n\r") %
		     convertTo<int>(db["poll_id"]) % db["descr"]);
	} while(db.fetchRow());
	ch->sendTo("\n\r");
      }

      db.query("select poll_id,descr from poll where status='closed' order by poll_id");

      if(db.fetchRow()){
	ch->sendTo(COLOR_BASIC, "These polls are closed:\n\r");
	do {
	  ch->sendTo(COLOR_BASIC, fmt("%-2i| <r>%s<1>\n\r") %
		     convertTo<int>(db["poll_id"]) % db["descr"]);
	} while(db.fetchRow());
	ch->sendTo("\n\r");
      }
    } else {
      //////////// list details of specified poll
      int which=convertTo<int>(arg);
      sstring status="open";

      db.query("select poll_id, descr, status from poll where poll_id=%i",
	       which);

      if(db.fetchRow()){
	ch->sendTo(COLOR_BASIC, fmt("%-2i| <r>%s<1>\n\r") %
		   convertTo<int>(db["poll_id"]) % db["descr"]);
	ch->sendTo(COLOR_BASIC, fmt("Poll is <r>%s<1>.\n\r\n\r") %
		   db["status"]);
	status=db["status"];
      }

      if(status=="open"){
	db.query("select option_id, descr from poll_option where poll_id=%i",
		 which);

	while(db.fetchRow()){
	  ch->sendTo(COLOR_BASIC, fmt("%-2i| <b>%s<1>\n\r") %
		     convertTo<int>(db["option_id"]) % db["descr"]);
	}
      } else if(status=="closed"){
	db.query("select pv.option_id as option_id, po.descr as descr, count(pv.option_id) as count from poll_vote pv, poll_option po where pv.poll_id=%i and pv.poll_id=po.poll_id and pv.option_id=po.option_id group by pv.option_id, po.descr order by count desc", which);

	while(db.fetchRow()){
	  ch->sendTo(COLOR_BASIC, fmt("%-2i| <b>%s<1> (%i votes)\n\r") %
		     convertTo<int>(db["option_id"]) % db["descr"] %
		     convertTo<int>(db["count"]));
	}
      }
    }
    return true;
  } else if(cmd==CMD_VOTE){
    sstring usage="Usage: vote <poll_id> <option_id>";
    int poll_id, option_id;
    sstring tmp;
    arg=one_argument(arg, tmp);

    if(tmp.empty()){
      if(!ch->isImmortal()){
	ch->sendTo(fmt("%s\n\r") % usage);
      } else {
	ch->sendTo("Usage:\n\r");
	ch->sendTo("vote <poll_id> <option_id>\n\r");
	ch->sendTo("vote <poll_id> add <option_id> <descr>\n\r");
	ch->sendTo("vote <poll_id> remove <option_id>\n\r");
	ch->sendTo("vote add <poll_id> <descr>\n\r");
	ch->sendTo("vote close <poll_id>\n\r");
	ch->sendTo("vote open <poll_id>\n\r");
      }
      return true;
    } if(tmp == "add"){
      // vote add <poll_id> <descr>
      if(!ch->isImmortal()){
	ch->sendTo(fmt("%s\n\r") % usage);
	return true;
      }

      arg=one_argument(arg, tmp);

      db.query("insert into poll values (%i, '%s', 'open')",
	       convertTo<int>(tmp), arg.c_str());
      ch->sendTo("Done.\n\r");
    } else if(tmp == "close"){
      // vote close <poll_id>
      if(!ch->isImmortal()){
	ch->sendTo(fmt("%s\n\r") % usage);
	return true;
      }
      arg=one_argument(arg, tmp);

      db.query("update poll set status='closed' where poll_id=%i",
	       convertTo<int>(tmp));
      ch->sendTo("Done.\n\r");
    } else if(tmp == "open"){
      // vote open <poll_id>
      if(!ch->isImmortal()){
	ch->sendTo(fmt("%s\n\r") % usage);
	return true;
      }
      arg=one_argument(arg, tmp);

      db.query("update poll set status='open' where poll_id=%i",
	       convertTo<int>(tmp));
      ch->sendTo("Done.\n\r");
    } else {
      poll_id=convertTo<int>(tmp);
      arg=one_argument(arg, tmp);

      if(tmp == "add"){
	// vote <poll_id> add <option_id> <descr>
	if(!ch->isImmortal()){
	  ch->sendTo(fmt("%s\n\r") % usage);
	  return true;
	}
	arg=one_argument(arg, tmp);
	option_id=convertTo<int>(tmp);

	db.query("insert into poll_option values (%i, %i, '%s')",
		 option_id, poll_id, arg.c_str());
	ch->sendTo("Done.\n\r");
      } else if(tmp == "remove"){
	// vote <poll_id> remove <option_id>
	if(!ch->isImmortal()){
	  ch->sendTo(fmt("%s\n\r") % usage);
	  return true;
	}
	arg=one_argument(arg, tmp);
	option_id=convertTo<int>(tmp);

	db.query("delete from poll_option where option_id=%i",
		 option_id);
	ch->sendTo("Done.\n\r");
      } else {
	// vote <poll_id> <option_id>
	option_id=convertTo<int>(tmp);

	db.query("select 1 from poll_vote where poll_id=%i and account='%s'",
		 poll_id, ch->desc->account->name);

	if(db.fetchRow()){
	  ch->sendTo("You've already voted in that poll.\n\r");
	  return true;
	}

	db.query("select 1 from poll where poll_id=%i and status='open'",
		 poll_id);

	if(!db.fetchRow()){
	  ch->sendTo("That poll isn't open for voting.\n\r");
	  return true;
	}

	db.query("insert into poll_vote values ('%s', %i, %i)",
		 ch->desc->account->name, poll_id, option_id);

	db.query("select po.descr as descr from poll_option po, poll_vote pv where po.poll_id=%i and po.option_id=%i and pv.poll_id=%i and pv.option_id=%i and pv.account='%s'", poll_id, option_id, poll_id, option_id, ch->desc->account->name);

	if(db.fetchRow()){
	  ch->sendTo(fmt("You cast your vote for %s.\n\r") %
		     db["descr"]);
	} else {
	  ch->sendTo("There was an error - speak to an admin.\n\r");
	}
      }
    }

    return true;
  }

  return false;
}

int TBeing::doVote(const sstring &)
{
  sendTo(COLOR_BASIC, "There doesn't seem to be a ballot box around.\n\r");
  return true;
}
<commit_msg>crash bug fix<commit_after>#include "stdsneezy.h"
#include "database.h"

// create table poll (poll_id int primary key, descr varchar(127), status varchar(8));
// create table poll_option (option_id int, poll_id int, descr varchar(127), primary key (option_id, poll_id));
// create table poll_vote (account varchar(80), poll_id int, option_id int, primary key (account, poll_id, option_id));

int ballotBox(TBeing *ch, cmdTypeT cmd, const char *argument, TObj *o, TObj *)
{
  TDatabase db(DB_SNEEZY);

  if(cmd==CMD_LIST){
    sstring arg=argument;
    if(arg.empty()){
      /////////// list all polls
      ch->sendTo(COLOR_BASIC, fmt("You have a look at %s...\n\r") %
		 o->getName());

      db.query("select poll_id, descr from poll where status='open' order by poll_id");

      if(db.fetchRow()){
	ch->sendTo(COLOR_BASIC, "These polls are open:\n\r");
	do {
	  ch->sendTo(COLOR_BASIC, fmt("%-2i| <r>%s<1>\n\r") %
		     convertTo<int>(db["poll_id"]) % db["descr"]);
	} while(db.fetchRow());
	ch->sendTo("\n\r");
      }

      db.query("select poll_id,descr from poll where status='closed' order by poll_id");

      if(db.fetchRow()){
	ch->sendTo(COLOR_BASIC, "These polls are closed:\n\r");
	do {
	  ch->sendTo(COLOR_BASIC, fmt("%-2i| <r>%s<1>\n\r") %
		     convertTo<int>(db["poll_id"]) % db["descr"]);
	} while(db.fetchRow());
	ch->sendTo("\n\r");
      }
    } else {
      //////////// list details of specified poll
      int which=convertTo<int>(arg);
      sstring status="open";

      db.query("select poll_id, descr, status from poll where poll_id=%i",
	       which);

      if(db.fetchRow()){
	ch->sendTo(COLOR_BASIC, fmt("%-2i| <r>%s<1>\n\r") %
		   convertTo<int>(db["poll_id"]) % db["descr"]);
	ch->sendTo(COLOR_BASIC, fmt("Poll is <r>%s<1>.\n\r\n\r") %
		   db["status"]);
	status=db["status"];
      }

      if(status=="open"){
	db.query("select option_id, descr from poll_option where poll_id=%i",
		 which);

	while(db.fetchRow()){
	  ch->sendTo(COLOR_BASIC, fmt("%-2i| <b>%s<1>\n\r") %
		     convertTo<int>(db["option_id"]) % db["descr"]);
	}
      } else if(status=="closed"){
	db.query("select pv.option_id as option_id, po.descr as descr, count(pv.option_id) as count from poll_vote pv, poll_option po where pv.poll_id=%i and pv.poll_id=po.poll_id and pv.option_id=po.option_id group by pv.option_id, po.descr order by count desc", which);

	while(db.fetchRow()){
	  ch->sendTo(COLOR_BASIC, fmt("%-2i| <b>%s<1> (%i votes)\n\r") %
		     convertTo<int>(db["option_id"]) % db["descr"] %
		     convertTo<int>(db["count"]));
	}
      }
    }
    return true;
  } else if(cmd==CMD_VOTE){
    sstring arg=argument;
    sstring usage="Usage: vote <poll_id> <option_id>";
    int poll_id, option_id;
    sstring tmp;
    arg=one_argument(arg, tmp);

    if(tmp.empty()){
      if(!ch->isImmortal()){
	ch->sendTo(fmt("%s\n\r") % usage);
      } else {
	ch->sendTo("Usage:\n\r");
	ch->sendTo("vote <poll_id> <option_id>\n\r");
	ch->sendTo("vote <poll_id> add <option_id> <descr>\n\r");
	ch->sendTo("vote <poll_id> remove <option_id>\n\r");
	ch->sendTo("vote add <poll_id> <descr>\n\r");
	ch->sendTo("vote close <poll_id>\n\r");
	ch->sendTo("vote open <poll_id>\n\r");
      }
      return true;
    } if(tmp == "add"){
      // vote add <poll_id> <descr>
      if(!ch->isImmortal()){
	ch->sendTo(fmt("%s\n\r") % usage);
	return true;
      }

      arg=one_argument(arg, tmp);

      db.query("insert into poll values (%i, '%s', 'open')",
	       convertTo<int>(tmp), arg.c_str());
      ch->sendTo("Done.\n\r");
    } else if(tmp == "close"){
      // vote close <poll_id>
      if(!ch->isImmortal()){
	ch->sendTo(fmt("%s\n\r") % usage);
	return true;
      }
      arg=one_argument(arg, tmp);

      db.query("update poll set status='closed' where poll_id=%i",
	       convertTo<int>(tmp));
      ch->sendTo("Done.\n\r");
    } else if(tmp == "open"){
      // vote open <poll_id>
      if(!ch->isImmortal()){
	ch->sendTo(fmt("%s\n\r") % usage);
	return true;
      }
      arg=one_argument(arg, tmp);

      db.query("update poll set status='open' where poll_id=%i",
	       convertTo<int>(tmp));
      ch->sendTo("Done.\n\r");
    } else {
      poll_id=convertTo<int>(tmp);
      arg=one_argument(arg, tmp);

      if(tmp == "add"){
	// vote <poll_id> add <option_id> <descr>
	if(!ch->isImmortal()){
	  ch->sendTo(fmt("%s\n\r") % usage);
	  return true;
	}
	arg=one_argument(arg, tmp);
	option_id=convertTo<int>(tmp);

	db.query("insert into poll_option values (%i, %i, '%s')",
		 option_id, poll_id, arg.c_str());
	ch->sendTo("Done.\n\r");
      } else if(tmp == "remove"){
	// vote <poll_id> remove <option_id>
	if(!ch->isImmortal()){
	  ch->sendTo(fmt("%s\n\r") % usage);
	  return true;
	}
	arg=one_argument(arg, tmp);
	option_id=convertTo<int>(tmp);

	db.query("delete from poll_option where option_id=%i",
		 option_id);
	ch->sendTo("Done.\n\r");
      } else {
	// vote <poll_id> <option_id>
	option_id=convertTo<int>(tmp);

	db.query("select 1 from poll_vote where poll_id=%i and account='%s'",
		 poll_id, ch->desc->account->name);

	if(db.fetchRow()){
	  ch->sendTo("You've already voted in that poll.\n\r");
	  return true;
	}

	db.query("select 1 from poll where poll_id=%i and status='open'",
		 poll_id);

	if(!db.fetchRow()){
	  ch->sendTo("That poll isn't open for voting.\n\r");
	  return true;
	}

	db.query("insert into poll_vote values ('%s', %i, %i)",
		 ch->desc->account->name, poll_id, option_id);

	db.query("select po.descr as descr from poll_option po, poll_vote pv where po.poll_id=%i and po.option_id=%i and pv.poll_id=%i and pv.option_id=%i and pv.account='%s'", poll_id, option_id, poll_id, option_id, ch->desc->account->name);

	if(db.fetchRow()){
	  ch->sendTo(fmt("You cast your vote for %s.\n\r") %
		     db["descr"]);
	} else {
	  ch->sendTo("There was an error - speak to an admin.\n\r");
	}
      }
    }

    return true;
  }

  return false;
}

int TBeing::doVote(const sstring &)
{
  sendTo(COLOR_BASIC, "There doesn't seem to be a ballot box around.\n\r");
  return true;
}
<|endoftext|>


<commit_before>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * 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
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include "src/parser/driver.h"

#include "src/parser/seclang-parser.hh"
#include "modsecurity/audit_log.h"
#include "modsecurity/rules_properties.h"

using modsecurity::audit_log::AuditLog;
using modsecurity::Rule;

namespace modsecurity {
namespace Parser {

Driver::Driver()
  : RulesProperties(),
  trace_scanning(false),
  trace_parsing(false),
  lastRule(NULL) { }

Driver::~Driver() {
    while (loc.empty() == false) {
        yy::location *a = loc.back();
        loc.pop_back();
        delete a;
    }
}

int Driver::addSecMarker(std::string marker) {
    for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {
        Rule *rule = new Rule(marker);
        rule->m_phase = i;
        m_rules[i].push_back(rule);
    }
    return 0;
}

int Driver::addSecAction(Rule *rule) {
    if (rule->m_phase > modsecurity::Phases::NUMBER_OF_PHASES) {
        m_parserError << "Unknown phase: " << std::to_string(rule->m_phase);
        m_parserError << std::endl;
        return false;
    }

    m_rules[rule->m_phase].push_back(rule);

    return true;
}

int Driver::addSecRule(Rule *rule) {
    if (rule->m_phase > modsecurity::Phases::NUMBER_OF_PHASES) {
        m_parserError << "Unknown phase: " << std::to_string(rule->m_phase);
        m_parserError << std::endl;
        return false;
    }

    if (lastRule && lastRule->m_chained) {
        if (lastRule->m_chainedRule == NULL) {
            rule->m_phase = lastRule->m_phase;
            lastRule->m_chainedRule = rule;
            if (rule->containsDisruptiveAction()) {
                m_parserError << "Disruptive actions can only be specified by";
                m_parserError << " chain starter rules.";
                return false;
            }
            return true;
        } else {
            Rule *a = lastRule->m_chainedRule;
            while (a->m_chained && a->m_chainedRule != NULL) {
                a = a->m_chainedRule;
            }
            if (a->m_chained && a->m_chainedRule == NULL) {
                a->m_chainedRule = rule;
                if (a->containsDisruptiveAction()) {
                    m_parserError << "Disruptive actions can only be ";
                    m_parserError << "specified by chain starter rules.";
                    return false;
                }
                return true;
            }
        }
    }

    /*
     * Checking if the rule has an ID and also checking if this ID is not used
     * by other rule
     */
    if (rule->m_ruleId == 0) {
        m_parserError << "Rules must have an ID. File: ";
        m_parserError << rule->m_fileName << " at line: ";
        m_parserError << std::to_string(rule->m_lineNumber) << std::endl;
        return false;
    }
    for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {
        std::vector<Rule *> rules = m_rules[i];
        for (int j = 0; j < rules.size(); j++) {
            if (rules[j]->m_ruleId == rule->m_ruleId) {
                m_parserError << "Rule id: " << std::to_string(rule->m_ruleId) \
                    << " is duplicated" << std::endl;
                return false;
            }
        }
    }

    lastRule = rule;
    m_rules[rule->m_phase].push_back(rule);
    return true;
}

int Driver::parse(const std::string &f, const std::string &ref) {
    lastRule = NULL;
    loc.push_back(new yy::location());
    if (ref.empty()) {
        this->ref.push_back("<<reference missing or not informed>>");
    } else {
        this->ref.push_back(ref);
    }

    buffer = f;
    scan_begin();
    yy::seclang_parser parser(*this);
    parser.set_debug_level(trace_parsing);
    int res = parser.parse();
    scan_end();

    /*
    if (m_auditLog->init(&error) == false) {
        m_parserError << "Problems while initializing the audit logs: " \
            << error << std::endl;
        return false;
    }
    */

    return res == 0;
}

int Driver::parseFile(const std::string &f) {
    std::ifstream t(f);
    std::string str;

    if (utils::isFile(f) == false) {
        m_parserError << "Failed to open the file: " << f << std::endl;
        return false;
    }

    t.seekg(0, std::ios::end);
    str.reserve(t.tellg());
    t.seekg(0, std::ios::beg);

    str.assign((std::istreambuf_iterator<char>(t)),
        std::istreambuf_iterator<char>());

    return parse(str, f);
}

void Driver::error(const yy::location& l, const std::string& m) {
    error(l, m, "");
}

void Driver::error(const yy::location& l, const std::string& m,
    const std::string& c) {
    if (m_parserError.tellp() == 0) {
        m_parserError << "Rules error. ";
        if (ref.empty() == false) {
            m_parserError << "File: " << ref.back() << ". ";
        }
        m_parserError << "Line: " << l.end.line << ". ";
        m_parserError << "Column: " << l.end.column - 1 << ". ";
    }

    if (m.empty() == false) {
        m_parserError << "" << m << " ";
    }

    if (c.empty() == false) {
        m_parserError << c;
    }
}

}  // namespace Parser
}  // namespace modsecurity
<commit_msg>Handle zero byte rule files correctly.<commit_after>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * 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
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include "src/parser/driver.h"

#include "src/parser/seclang-parser.hh"
#include "modsecurity/audit_log.h"
#include "modsecurity/rules_properties.h"

using modsecurity::audit_log::AuditLog;
using modsecurity::Rule;

namespace modsecurity {
namespace Parser {

Driver::Driver()
  : RulesProperties(),
  trace_scanning(false),
  trace_parsing(false),
  lastRule(NULL) { }

Driver::~Driver() {
    while (loc.empty() == false) {
        yy::location *a = loc.back();
        loc.pop_back();
        delete a;
    }
}

int Driver::addSecMarker(std::string marker) {
    for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {
        Rule *rule = new Rule(marker);
        rule->m_phase = i;
        m_rules[i].push_back(rule);
    }
    return 0;
}

int Driver::addSecAction(Rule *rule) {
    if (rule->m_phase > modsecurity::Phases::NUMBER_OF_PHASES) {
        m_parserError << "Unknown phase: " << std::to_string(rule->m_phase);
        m_parserError << std::endl;
        return false;
    }

    m_rules[rule->m_phase].push_back(rule);

    return true;
}

int Driver::addSecRule(Rule *rule) {
    if (rule->m_phase > modsecurity::Phases::NUMBER_OF_PHASES) {
        m_parserError << "Unknown phase: " << std::to_string(rule->m_phase);
        m_parserError << std::endl;
        return false;
    }

    if (lastRule && lastRule->m_chained) {
        if (lastRule->m_chainedRule == NULL) {
            rule->m_phase = lastRule->m_phase;
            lastRule->m_chainedRule = rule;
            if (rule->containsDisruptiveAction()) {
                m_parserError << "Disruptive actions can only be specified by";
                m_parserError << " chain starter rules.";
                return false;
            }
            return true;
        } else {
            Rule *a = lastRule->m_chainedRule;
            while (a->m_chained && a->m_chainedRule != NULL) {
                a = a->m_chainedRule;
            }
            if (a->m_chained && a->m_chainedRule == NULL) {
                a->m_chainedRule = rule;
                if (a->containsDisruptiveAction()) {
                    m_parserError << "Disruptive actions can only be ";
                    m_parserError << "specified by chain starter rules.";
                    return false;
                }
                return true;
            }
        }
    }

    /*
     * Checking if the rule has an ID and also checking if this ID is not used
     * by other rule
     */
    if (rule->m_ruleId == 0) {
        m_parserError << "Rules must have an ID. File: ";
        m_parserError << rule->m_fileName << " at line: ";
        m_parserError << std::to_string(rule->m_lineNumber) << std::endl;
        return false;
    }
    for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {
        std::vector<Rule *> rules = m_rules[i];
        for (int j = 0; j < rules.size(); j++) {
            if (rules[j]->m_ruleId == rule->m_ruleId) {
                m_parserError << "Rule id: " << std::to_string(rule->m_ruleId) \
                    << " is duplicated" << std::endl;
                return false;
            }
        }
    }

    lastRule = rule;
    m_rules[rule->m_phase].push_back(rule);
    return true;
}

int Driver::parse(const std::string &f, const std::string &ref) {
    lastRule = NULL;
    loc.push_back(new yy::location());
    if (ref.empty()) {
        this->ref.push_back("<<reference missing or not informed>>");
    } else {
        this->ref.push_back(ref);
    }

    if (f.empty()) {
        return 1;
    }

    buffer = f;
    scan_begin();
    yy::seclang_parser parser(*this);
    parser.set_debug_level(trace_parsing);
    int res = parser.parse();
    scan_end();

    /*
    if (m_auditLog->init(&error) == false) {
        m_parserError << "Problems while initializing the audit logs: " \
            << error << std::endl;
        return false;
    }
    */

    return res == 0;
}

int Driver::parseFile(const std::string &f) {
    std::ifstream t(f);
    std::string str;

    if (utils::isFile(f) == false) {
        m_parserError << "Failed to open the file: " << f << std::endl;
        return false;
    }

    t.seekg(0, std::ios::end);
    str.reserve(t.tellg());
    t.seekg(0, std::ios::beg);

    str.assign((std::istreambuf_iterator<char>(t)),
        std::istreambuf_iterator<char>());

    return parse(str, f);
}

void Driver::error(const yy::location& l, const std::string& m) {
    error(l, m, "");
}

void Driver::error(const yy::location& l, const std::string& m,
    const std::string& c) {
    if (m_parserError.tellp() == 0) {
        m_parserError << "Rules error. ";
        if (ref.empty() == false) {
            m_parserError << "File: " << ref.back() << ". ";
        }
        m_parserError << "Line: " << l.end.line << ". ";
        m_parserError << "Column: " << l.end.column - 1 << ". ";
    }

    if (m.empty() == false) {
        m_parserError << "" << m << " ";
    }

    if (c.empty() == false) {
        m_parserError << c;
    }
}

}  // namespace Parser
}  // namespace modsecurity
<|endoftext|>


<commit_before>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <iostream>
#include <iomanip>
#include <Input/vjPosition/aMotionStar.h>

int
main () {
  std::string addr;
  unsigned short port;
  unsigned int birdsRequired;
  double measurement_rate;

  // Get configuration information
  std::cerr << "-------- MotionStar Test program -------\n"
            << "First we need some config info:\n"
            << "NOTE: Sample values are in ()'s\n" << std::flush;

  std::cout << "\nEnter address: " << std::flush;
  std::cin >> addr;
  std::cout << "Enter port number (5000, 6000): " << std::flush;
  std::cin >> port;
  std::cout << "How many birds: " << std::flush;
  std::cin >> birdsRequired;
  std::cout << "Measurement rate: " << std::flush;
  std::cin >> measurement_rate;
  std::cout << "\nUsing FRONT_HEMISPHERE" << std::flush;
  std::cout << "\nRequesting POSITION_ANGLES data" << std::flush;
  std::cout << "\nReading continuous data" << std::flush;

  aMotionStar* motionstar = new aMotionStar(addr.c_str(), port, BIRDNET::TCP,
                                            true, FLOCK::FRONT_HEMISPHERE,
                                            FLOCK::POSITION_ANGLES,
                                            BIRDNET::CONTINUOUS, 1,
                                            measurement_rate, birdsRequired);

   char achar;
   bool birds_running(false);      // Are the birds currently running

   do
   {
      std::cerr << "\n----- MotionStar Test Program ----\n"
                << "----- Main Menu ----\n"
                << "Cur State:\n"
                << "   running:" << birds_running
                << "\n\nCommands:\n"
                << "   U - Update\n"
                << "   S - Start\n"
                << "   X - Stop\n"
                << "   Q - Quit\n"
                << "   O - Output\n"
                << "\nCommand: " << std::flush;
      std::cin >> achar;        // Get next command

      std::cerr << "\nGot command: " << achar << std::endl << std::flush;
      switch (achar)
      {
      case 'u':
      case 'U':
         std::cerr << "---- Updating (not implemented) ---\n" << std::flush;
         break;
      case 's':
      case 'S':
         std::cerr << "---- Starting MotionStar ---\n" << std::flush;
         motionstar->start();
         birds_running = true;
         break;
      case 'x':
      case 'X':
         std::cerr << "---- Stoping motionstar ---\n" << std::flush;
         motionstar->stop();
         birds_running = false;
         break;
      case 'o':
      case 'O':
         long num_samples;
         std::cerr << "Number of samples? ";
         std::cin >> num_samples;

         for (long z = 0; z < num_samples; z++)
         {
            motionstar->sample();
            //std::cout << "-------- aMotionStar: Sampling (" << z << " of " << num_samples << ") -------" << std::endl;
            std::cout << z << ":\n";
            std::cout << "\t      X\t\t  Y\t     Z\t\tA\t    E\t\tR\n";
            for ( int bird=0; bird < motionstar->getNumBirds(); bird++ ) {
            //   vjVec3 pos0 = vjCoord( *motionstar->getPosData(bird) ).pos;
            //   vjVec3 ori0 = vjCoord( *motionstar->getPosData(bird) ).orient;
               /*
               std::cout << "Bird " << bird << ":\n"
                 << setiosflags(ios::right | ios::fixed | ios::showpoint)
                 << "Data: x:" << setprecision(2) << setw(10) << motionstar->getXPos(bird) << std::endl
                 << "      y:" << setprecision(2) << setw(10) << motionstar->getYPos(bird) << std::endl
                 << "      z:" << setprecision(2) << setw(10) << motionstar->getZPos(bird) << std::endl
                 << "    azi:" << setprecision(2) << setw(10) << motionstar->getXRot(bird) << std::endl
                 << "   elev:" << setprecision(2) << setw(10) << motionstar->getYRot(bird) << std::endl
                 << "   roll:" << setprecision(2) << setw(10) << motionstar->getZRot(bird) << std::endl << std::endl;
                 */
                  std::cout << " Bird " << bird << ":";
                  std::cout << "  " << std::setprecision(8) << motionstar->getXPos(bird)
                            << "  " << std::setprecision(8) << motionstar->getYPos(bird)
                            << "  " << std::setprecision(8) << motionstar->getZPos(bird)
                            << "  " << std::setprecision(8) << motionstar->getZRot(bird)
                            << "  " << std::setprecision(8) << motionstar->getYRot(bird)
                            << "  " << std::setprecision(8) << motionstar->getXRot(bird)
                            << std::endl;
            }
            std::cout << std::endl;
            //sleep(2);
         }
         break;
      }
   } while ((achar != 'q') && (achar != 'Q'));

   std::cerr << "---- Quiting -----\n";

   if ( motionstar->isActive() ) {
      std::cerr << "Stoping MotionStar ...\n" << std::flush;

      motionstar->stop();
   }

   delete motionstar;
   return 0;
}
<commit_msg>Include sys/types.h so that this will compile on FreeBSD.<commit_after>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <iostream>
#include <iomanip>
#include <sys/types.h>
#include <Input/vjPosition/aMotionStar.h>

int
main () {
  std::string addr;
  unsigned short port;
  unsigned int birdsRequired;
  double measurement_rate;

  // Get configuration information
  std::cerr << "-------- MotionStar Test program -------\n"
            << "First we need some config info:\n"
            << "NOTE: Sample values are in ()'s\n" << std::flush;

  std::cout << "\nEnter address: " << std::flush;
  std::cin >> addr;
  std::cout << "Enter port number (5000, 6000): " << std::flush;
  std::cin >> port;
  std::cout << "How many birds: " << std::flush;
  std::cin >> birdsRequired;
  std::cout << "Measurement rate: " << std::flush;
  std::cin >> measurement_rate;
  std::cout << "\nUsing FRONT_HEMISPHERE" << std::flush;
  std::cout << "\nRequesting POSITION_ANGLES data" << std::flush;
  std::cout << "\nReading continuous data" << std::flush;

  aMotionStar* motionstar = new aMotionStar(addr.c_str(), port, BIRDNET::TCP,
                                            true, FLOCK::FRONT_HEMISPHERE,
                                            FLOCK::POSITION_ANGLES,
                                            BIRDNET::CONTINUOUS, 1,
                                            measurement_rate, birdsRequired);

   char achar;
   bool birds_running(false);      // Are the birds currently running

   do
   {
      std::cerr << "\n----- MotionStar Test Program ----\n"
                << "----- Main Menu ----\n"
                << "Cur State:\n"
                << "   running:" << birds_running
                << "\n\nCommands:\n"
                << "   U - Update\n"
                << "   S - Start\n"
                << "   X - Stop\n"
                << "   Q - Quit\n"
                << "   O - Output\n"
                << "\nCommand: " << std::flush;
      std::cin >> achar;        // Get next command

      std::cerr << "\nGot command: " << achar << std::endl << std::flush;
      switch (achar)
      {
      case 'u':
      case 'U':
         std::cerr << "---- Updating (not implemented) ---\n" << std::flush;
         break;
      case 's':
      case 'S':
         std::cerr << "---- Starting MotionStar ---\n" << std::flush;
         motionstar->start();
         birds_running = true;
         break;
      case 'x':
      case 'X':
         std::cerr << "---- Stoping motionstar ---\n" << std::flush;
         motionstar->stop();
         birds_running = false;
         break;
      case 'o':
      case 'O':
         long num_samples;
         std::cerr << "Number of samples? ";
         std::cin >> num_samples;

         for (long z = 0; z < num_samples; z++)
         {
            motionstar->sample();
            //std::cout << "-------- aMotionStar: Sampling (" << z << " of " << num_samples << ") -------" << std::endl;
            std::cout << z << ":\n";
            std::cout << "\t      X\t\t  Y\t     Z\t\tA\t    E\t\tR\n";
            for ( int bird=0; bird < motionstar->getNumBirds(); bird++ ) {
            //   vjVec3 pos0 = vjCoord( *motionstar->getPosData(bird) ).pos;
            //   vjVec3 ori0 = vjCoord( *motionstar->getPosData(bird) ).orient;
               /*
               std::cout << "Bird " << bird << ":\n"
                 << setiosflags(ios::right | ios::fixed | ios::showpoint)
                 << "Data: x:" << setprecision(2) << setw(10) << motionstar->getXPos(bird) << std::endl
                 << "      y:" << setprecision(2) << setw(10) << motionstar->getYPos(bird) << std::endl
                 << "      z:" << setprecision(2) << setw(10) << motionstar->getZPos(bird) << std::endl
                 << "    azi:" << setprecision(2) << setw(10) << motionstar->getXRot(bird) << std::endl
                 << "   elev:" << setprecision(2) << setw(10) << motionstar->getYRot(bird) << std::endl
                 << "   roll:" << setprecision(2) << setw(10) << motionstar->getZRot(bird) << std::endl << std::endl;
                 */
                  std::cout << " Bird " << bird << ":";
                  std::cout << "  " << std::setprecision(8) << motionstar->getXPos(bird)
                            << "  " << std::setprecision(8) << motionstar->getYPos(bird)
                            << "  " << std::setprecision(8) << motionstar->getZPos(bird)
                            << "  " << std::setprecision(8) << motionstar->getZRot(bird)
                            << "  " << std::setprecision(8) << motionstar->getYRot(bird)
                            << "  " << std::setprecision(8) << motionstar->getXRot(bird)
                            << std::endl;
            }
            std::cout << std::endl;
            //sleep(2);
         }
         break;
      }
   } while ((achar != 'q') && (achar != 'Q'));

   std::cerr << "---- Quiting -----\n";

   if ( motionstar->isActive() ) {
      std::cerr << "Stoping MotionStar ...\n" << std::flush;

      motionstar->stop();
   }

   delete motionstar;
   return 0;
}
<|endoftext|>


<commit_before>#include "testing/testing.hpp"

#include "routing/routing_integration_tests/routing_test_tools.hpp"

#include "geometry/mercator.hpp"

using namespace routing;
using namespace routing::turns;

UNIT_TEST(RussiaMoscowSevTushinoParkPreferingBicycleWay)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetBicycleComponents(), MercatorBounds::FromLatLon(55.87445, 37.43711), {0., 0.},
      MercatorBounds::FromLatLon(55.87203, 37.44274), 460.0);
}

UNIT_TEST(RussiaMoscowNahimovskyLongRoute)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetBicycleComponents(), MercatorBounds::FromLatLon(55.66151, 37.63320), {0., 0.},
      MercatorBounds::FromLatLon(55.67695, 37.56220), 7570.0);
}

UNIT_TEST(RussiaDomodedovoSteps)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetBicycleComponents(), MercatorBounds::FromLatLon(55.44020, 37.77409), {0., 0.},
      MercatorBounds::FromLatLon(55.43972, 37.77254), 123.0);
}
<commit_msg>[bicycle routing] Test on correct default bicycle speed limit.<commit_after>#include "testing/testing.hpp"

#include "routing/routing_integration_tests/routing_test_tools.hpp"

#include "geometry/mercator.hpp"

using namespace routing;
using namespace routing::turns;

UNIT_TEST(RussiaMoscowSevTushinoParkPreferingBicycleWay)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetBicycleComponents(), MercatorBounds::FromLatLon(55.87445, 37.43711), {0., 0.},
      MercatorBounds::FromLatLon(55.87203, 37.44274), 460.0);
}

UNIT_TEST(RussiaMoscowNahimovskyLongRoute)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetBicycleComponents(), MercatorBounds::FromLatLon(55.66151, 37.63320), {0., 0.},
      MercatorBounds::FromLatLon(55.67695, 37.56220), 7570.0);
}

UNIT_TEST(RussiaDomodedovoSteps)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetBicycleComponents(), MercatorBounds::FromLatLon(55.44020, 37.77409), {0., 0.},
      MercatorBounds::FromLatLon(55.43972, 37.77254), 123.0);
}

UNIT_TEST(SwedenStockholmCyclewayPriority)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetBicycleComponents(), MercatorBounds::FromLatLon(59.33151, 18.09347), {0., 0.},
      MercatorBounds::FromLatLon(59.33052, 18.09391), 113.0);
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#if     defined (__GCC__)
#include    <cxxabi.h>
#elif   qPlatform_Windows
#include    <Windows.h>
#include    <Dbghelp.h>
#endif

#include    "../Execution/Finally.h"

#include    "Demangle.h"

using   namespace   Stroika::Foundation;

#if     qPlatform_Windows
// otherwise modules linking with this code will tend to get link errors without explicitly linking
// to this module...
#pragma comment (lib, "Dbghelp.lib")
#endif

/*
 ********************************************************************************
 ************************ Debug::DropIntoDebuggerIfPresent **********************
 ********************************************************************************
 */
Characters::String    Debug::Demangle (const Characters::String& originalName)
{
#if     defined (__GCC__)
    int     status {};
    char*   realname = abi::__cxa_demangle (originalName.AsNarrowSDKString ().c_str (), 0, 0, &status);
    auto&&  cleanup = Execution::Finally ([&realname]() { if (realname != nullptr) { ::free (realname); } });
    if (status == 0) {
        return Characters::String::FromNarrowSDKString (realname);
    }
#elif   qPlatform_Windows
    char    resultBuf[10 * 1024];
    if (::UnDecorateSymbolName (originalName.AsNarrowSDKString ().c_str (), resultBuf, sizeof (resultBuf), UNDNAME_COMPLETE) != 0) {
        return Characters::String::FromNarrowSDKString (resultBuf);
    }
#endif
    return originalName;
}
<commit_msg>fixed typo in gnuc demangle code<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#if     defined (__GNUC__)
#include    <cxxabi.h>
#elif   qPlatform_Windows
#include    <Windows.h>
#include    <Dbghelp.h>
#endif

#include    "../Execution/Finally.h"

#include    "Demangle.h"

using   namespace   Stroika::Foundation;

#if     qPlatform_Windows
// otherwise modules linking with this code will tend to get link errors without explicitly linking
// to this module...
#pragma comment (lib, "Dbghelp.lib")
#endif

/*
 ********************************************************************************
 ************************ Debug::DropIntoDebuggerIfPresent **********************
 ********************************************************************************
 */
Characters::String    Debug::Demangle (const Characters::String& originalName)
{
#if     defined (__GNUC__)
    int     status {};
    char*   realname = abi::__cxa_demangle (originalName.AsNarrowSDKString ().c_str (), 0, 0, &status);
    auto&&  cleanup = Execution::Finally ([&realname]() { if (realname != nullptr) { ::free (realname); } });
    if (status == 0) {
        return Characters::String::FromNarrowSDKString (realname);
    }
#elif   qPlatform_Windows
    char    resultBuf[10 * 1024];
    if (::UnDecorateSymbolName (originalName.AsNarrowSDKString ().c_str (), resultBuf, sizeof (resultBuf), UNDNAME_COMPLETE) != 0) {
        return Characters::String::FromNarrowSDKString (resultBuf);
    }
#endif
    return originalName;
}
<|endoftext|>


<commit_before>#include "testing/testing.hpp"

#include "routing/routing_callbacks.hpp"

#include "routing/routing_integration_tests/routing_test_tools.hpp"

#include "geometry/mercator.hpp"

#include "base/math.hpp"

using namespace integration;
using namespace routing;
using namespace routing::turns;

UNIT_TEST(RussiaMoscowSevTushinoParkPreferingBicycleWay)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(55.87445, 37.43711), {0., 0.},
      mercator::FromLatLon(55.87203, 37.44274), 460.0);
}

UNIT_TEST(RussiaMoscowNahimovskyLongRoute)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(55.66151, 37.63320), {0., 0.},
      mercator::FromLatLon(55.67695, 37.56220), 5670.0);
}

UNIT_TEST(RussiaDomodedovoSteps)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(55.44010, 37.77416), {0., 0.},
      mercator::FromLatLon(55.43975, 37.77272), 100.0);
}

UNIT_TEST(SwedenStockholmCyclewayPriority)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(59.33151, 18.09347), {0., 0.},
      mercator::FromLatLon(59.33052, 18.09391), 113.0);
}

// Note. If the closest to start or finish road has "bicycle=no" tag the closest road where
// it's allowed to ride bicycle will be found.
UNIT_TEST(NetherlandsAmsterdamBicycleNo)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(52.32716, 5.05932), {0., 0.},
      mercator::FromLatLon(52.32587, 5.06121), 338.0);
}

UNIT_TEST(NetherlandsAmsterdamBicycleYes)
{
  TRouteResult const routeResult =
      CalculateRoute(GetVehicleComponents(VehicleType::Bicycle),
                     mercator::FromLatLon(52.32872, 5.07527), {0.0, 0.0},
                     mercator::FromLatLon(52.33853, 5.08941));

  Route const & route = *routeResult.first;
  RouterResultCode const result = routeResult.second;
  TEST_EQUAL(result, RouterResultCode::NoError, ());
  TEST(base::AlmostEqualAbs(route.GetTotalTimeSec(), 304.2, 1.0), (route.GetTotalTimeSec()));
}

// This test on tag cycleway=opposite for a streets which have oneway=yes.
// It means bicycles may go in the both directions.
UNIT_TEST(NetherlandsAmsterdamSingelStCyclewayOpposite)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(52.37571, 4.88591), {0., 0.},
      mercator::FromLatLon(52.37736, 4.88744), 212.8);
}

UNIT_TEST(RussiaMoscowKashirskoe16ToCapLongRoute)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(55.66230, 37.63214), {0., 0.},
      mercator::FromLatLon(55.68927, 37.70356), 7075.0);
}

// Passing through living_street and service are allowed in Russia
UNIT_TEST(RussiaMoscowServicePassThrough1)
{
  TRouteResult route =
        integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
                                    mercator::FromLatLon(55.66230, 37.63214), {0., 0.},
                                    mercator::FromLatLon(55.68895, 37.70286));
  TEST_EQUAL(route.second, RouterResultCode::NoError, ());
}

UNIT_TEST(RussiaMoscowServicePassThrough2)
{
  TRouteResult route =
      integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
                                  mercator::FromLatLon(55.69038, 37.70015), {0., 0.},
                                  mercator::FromLatLon(55.69123, 37.6953));
  TEST_EQUAL(route.second, RouterResultCode::NoError, ());
}

UNIT_TEST(RussiaMoscowServicePassThrough3)
{
  TRouteResult route =
      integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
                                  mercator::FromLatLon(55.79649, 37.53738), {0., 0.},
                                  mercator::FromLatLon(55.79618, 37.54071));
  TEST_EQUAL(route.second, RouterResultCode::NoError, ());
}

// TODO: This test doesn't pass because routing::RouteWeight::operator<
// prefer roads with less number of barriers. It will be more useful to consider
// barriers only with access=no/private/etc tag.

//UNIT_TEST(RussiaKerchStraitFerryRoute)
//{
//  CalculateRouteAndTestRouteLength(
//      GetVehicleComponents(VehicleType::Bicycle),
//      mercator::FromLatLon(45.4167, 36.7658), {0.0, 0.0},
//      mercator::FromLatLon(45.3653, 36.6161), 18000.0);
//}

// Test on building bicycle route past ferry.
UNIT_TEST(SwedenStockholmBicyclePastFerry)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(59.4725, 18.51355), {0.0, 0.0},
      mercator::FromLatLon(59.32967, 18.075), 46163.7);
}

// Test on cross mwm bicycle routing.
UNIT_TEST(CrossMwmKaliningradRegionToLiepaja)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(54.63519, 21.80749), {0., 0.},
      mercator::FromLatLon(56.51119, 21.01847), 295241);
}

// Test on riding up from Adeje (sea level) to Vilaflor (altitude 1400 meters).
UNIT_TEST(SpainTenerifeAdejeVilaflor)
{
  integration::CalculateRouteAndTestRouteTime(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(28.11984, -16.72592), {0.0, 0.0},
      mercator::FromLatLon(28.15865, -16.63704), 10787.6 /* expectedTimeSeconds */);
}

// Test on riding down from Vilaflor (altitude 1400 meters) to Adeje (sea level).
UNIT_TEST(SpainTenerifeVilaflorAdeje)
{
  integration::CalculateRouteAndTestRouteTime(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(28.15865, -16.63704), {0.0, 0.0},
      mercator::FromLatLon(28.11984, -16.72592), 7979.9 /* expectedTimeSeconds */);
}

// Two tests on not building route against traffic on road with oneway:bicycle=yes.
UNIT_TEST(MunichRoadWithOnewayBicycleYes1)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(48.15995, 11.56296), {0.0, 0.0},
      mercator::FromLatLon(48.16027, 11.56306), 262.1 /* expectedRouteMeters */);
}

UNIT_TEST(MunichRoadWithOnewayBicycleYes2)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(48.17819, 11.57286), {0.0, 0.0},
      mercator::FromLatLon(48.17867, 11.57303), 177.2 /* expectedRouteMeters */);
}
<commit_msg>[routing] Routing integration test fix for 200920: SwedenStockholmBicyclePastFerry.<commit_after>#include "testing/testing.hpp"

#include "routing/routing_callbacks.hpp"

#include "routing/routing_integration_tests/routing_test_tools.hpp"

#include "geometry/mercator.hpp"

#include "base/math.hpp"

using namespace integration;
using namespace routing;
using namespace routing::turns;

UNIT_TEST(RussiaMoscowSevTushinoParkPreferingBicycleWay)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(55.87445, 37.43711), {0., 0.},
      mercator::FromLatLon(55.87203, 37.44274), 460.0);
}

UNIT_TEST(RussiaMoscowNahimovskyLongRoute)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(55.66151, 37.63320), {0., 0.},
      mercator::FromLatLon(55.67695, 37.56220), 5670.0);
}

UNIT_TEST(RussiaDomodedovoSteps)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(55.44010, 37.77416), {0., 0.},
      mercator::FromLatLon(55.43975, 37.77272), 100.0);
}

UNIT_TEST(SwedenStockholmCyclewayPriority)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(59.33151, 18.09347), {0., 0.},
      mercator::FromLatLon(59.33052, 18.09391), 113.0);
}

// Note. If the closest to start or finish road has "bicycle=no" tag the closest road where
// it's allowed to ride bicycle will be found.
UNIT_TEST(NetherlandsAmsterdamBicycleNo)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(52.32716, 5.05932), {0., 0.},
      mercator::FromLatLon(52.32587, 5.06121), 338.0);
}

UNIT_TEST(NetherlandsAmsterdamBicycleYes)
{
  TRouteResult const routeResult =
      CalculateRoute(GetVehicleComponents(VehicleType::Bicycle),
                     mercator::FromLatLon(52.32872, 5.07527), {0.0, 0.0},
                     mercator::FromLatLon(52.33853, 5.08941));

  Route const & route = *routeResult.first;
  RouterResultCode const result = routeResult.second;
  TEST_EQUAL(result, RouterResultCode::NoError, ());
  TEST(base::AlmostEqualAbs(route.GetTotalTimeSec(), 304.2, 1.0), (route.GetTotalTimeSec()));
}

// This test on tag cycleway=opposite for a streets which have oneway=yes.
// It means bicycles may go in the both directions.
UNIT_TEST(NetherlandsAmsterdamSingelStCyclewayOpposite)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(52.37571, 4.88591), {0., 0.},
      mercator::FromLatLon(52.37736, 4.88744), 212.8);
}

UNIT_TEST(RussiaMoscowKashirskoe16ToCapLongRoute)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(55.66230, 37.63214), {0., 0.},
      mercator::FromLatLon(55.68927, 37.70356), 7075.0);
}

// Passing through living_street and service are allowed in Russia
UNIT_TEST(RussiaMoscowServicePassThrough1)
{
  TRouteResult route =
        integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
                                    mercator::FromLatLon(55.66230, 37.63214), {0., 0.},
                                    mercator::FromLatLon(55.68895, 37.70286));
  TEST_EQUAL(route.second, RouterResultCode::NoError, ());
}

UNIT_TEST(RussiaMoscowServicePassThrough2)
{
  TRouteResult route =
      integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
                                  mercator::FromLatLon(55.69038, 37.70015), {0., 0.},
                                  mercator::FromLatLon(55.69123, 37.6953));
  TEST_EQUAL(route.second, RouterResultCode::NoError, ());
}

UNIT_TEST(RussiaMoscowServicePassThrough3)
{
  TRouteResult route =
      integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
                                  mercator::FromLatLon(55.79649, 37.53738), {0., 0.},
                                  mercator::FromLatLon(55.79618, 37.54071));
  TEST_EQUAL(route.second, RouterResultCode::NoError, ());
}

// TODO: This test doesn't pass because routing::RouteWeight::operator<
// prefer roads with less number of barriers. It will be more useful to consider
// barriers only with access=no/private/etc tag.

//UNIT_TEST(RussiaKerchStraitFerryRoute)
//{
//  CalculateRouteAndTestRouteLength(
//      GetVehicleComponents(VehicleType::Bicycle),
//      mercator::FromLatLon(45.4167, 36.7658), {0.0, 0.0},
//      mercator::FromLatLon(45.3653, 36.6161), 18000.0);
//}

// Test on building bicycle route past ferry.
UNIT_TEST(SwedenStockholmBicyclePastFerry)
{
  CalculateRouteAndTestRouteLength(
      GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(59.4725, 18.51355), {0.0, 0.0},
      mercator::FromLatLon(59.42533, 18.35991), 14338.0);
}

// Test on cross mwm bicycle routing.
UNIT_TEST(CrossMwmKaliningradRegionToLiepaja)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(54.63519, 21.80749), {0., 0.},
      mercator::FromLatLon(56.51119, 21.01847), 295241);
}

// Test on riding up from Adeje (sea level) to Vilaflor (altitude 1400 meters).
UNIT_TEST(SpainTenerifeAdejeVilaflor)
{
  integration::CalculateRouteAndTestRouteTime(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(28.11984, -16.72592), {0.0, 0.0},
      mercator::FromLatLon(28.15865, -16.63704), 10787.6 /* expectedTimeSeconds */);
}

// Test on riding down from Vilaflor (altitude 1400 meters) to Adeje (sea level).
UNIT_TEST(SpainTenerifeVilaflorAdeje)
{
  integration::CalculateRouteAndTestRouteTime(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(28.15865, -16.63704), {0.0, 0.0},
      mercator::FromLatLon(28.11984, -16.72592), 7979.9 /* expectedTimeSeconds */);
}

// Two tests on not building route against traffic on road with oneway:bicycle=yes.
UNIT_TEST(MunichRoadWithOnewayBicycleYes1)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(48.15995, 11.56296), {0.0, 0.0},
      mercator::FromLatLon(48.16027, 11.56306), 262.1 /* expectedRouteMeters */);
}

UNIT_TEST(MunichRoadWithOnewayBicycleYes2)
{
  integration::CalculateRouteAndTestRouteLength(
      integration::GetVehicleComponents(VehicleType::Bicycle),
      mercator::FromLatLon(48.17819, 11.57286), {0.0, 0.0},
      mercator::FromLatLon(48.17867, 11.57303), 177.2 /* expectedRouteMeters */);
}
<|endoftext|>