<commit_before>#ifndef VEXCL_PROFILER_HPP
#define VEXCL_PROFILER_HPP

/*
The MIT License

Copyright (c) 2012-2017 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   profiler.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  Simple OpenCL/Host profiler.
 */

#if defined(_MSC_VER) && ( defined(min) || defined(max) )
#  error Please define NOMINMAX macro globally in your project
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <memory>
#include <stack>
#include <vector>
#include <cassert>

#if defined(_MSC_VER) && (_MSC_VER < 1700)
#  define VEXCL_USE_BOOST_CHRONO
#  include <boost/chrono.hpp>
#else
#  include <chrono>
#endif

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/global_fun.hpp>
#include <boost/io/ios_state.hpp>

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/mean.hpp>

#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable: 4244)
#endif
#include <boost/accumulators/statistics/median.hpp>
#ifdef _MSC_VER
#  pragma warning(pop)
#endif

#include <vexcl/backend.hpp>

namespace vex {

/// A stopwatch that computes the median and mean of individual timings.
/**
 * \param Clock class that provides interface compatible with either
 *              boost::chrono or std::chrono clocks.
 */
template <
#ifdef VEXCL_USE_BOOST_CHRONO
    class Clock = boost::chrono::high_resolution_clock
#else
    class Clock = std::chrono::high_resolution_clock
#endif
    >
class stopwatch {
    boost::accumulators::accumulator_set<
        double,
        boost::accumulators::stats<
            boost::accumulators::tag::count,
            boost::accumulators::tag::sum,
            boost::accumulators::tag::mean,
            boost::accumulators::tag::median(boost::accumulators::with_p_square_quantile)
            >
        > acc;

    public:
        stopwatch() { tic(); }

        /// Start timer.
        inline void tic() {
            start = Clock::now();
        }

        /// Stop timer, return elapsed time in seconds.
        inline double toc() {
            const double delta = seconds(start, Clock::now());

            acc(delta);

            return delta;
        }

        /// Average time across tics.
        inline double average() const {
            namespace ba = boost::accumulators;

            return ba::count(acc) >= 3 ? ba::median(acc) : ba::mean(acc);
        }

        /// Total time spent in the timer.
        inline double total() const {
            return boost::accumulators::sum(acc);
        }

        /// Number of tics.
        inline size_t tics() const {
            return boost::accumulators::count(acc);
        }
    private:
        static double seconds(typename Clock::time_point begin, typename Clock::time_point end) {
            return typename Clock::duration(end - begin).count() *
                static_cast<double>(Clock::duration::period::num) /
                    Clock::duration::period::den;
        }

        typename Clock::time_point start;
};

/// Class for gathering and printing OpenCL and Host profiling info.
/**
 * \param Clock class that provides interface compatible with either
 *              boost::chrono or std::chrono clocks.
 * \param Avg   Kind of averaging used. AvgMedian is more stable, but may
 *              have high overhead when profiling is made in a loop.
 */
template <
#ifdef VEXCL_USE_BOOST_CHRONO
    class Clock = boost::chrono::high_resolution_clock
#else
    class Clock = std::chrono::high_resolution_clock
#endif
    >
class profiler {
    private:
        class profile_unit {
            public:
                profile_unit(std::string name) : watch(), name(name), children() {}
                virtual ~profile_unit() {}

                stopwatch<Clock> watch;
                std::string name;

                static std::string _name(const std::shared_ptr<profile_unit> &u) {
                    return u->name;
                }

                boost::multi_index_container<
                    std::shared_ptr<profile_unit>,
                    boost::multi_index::indexed_by<
                        boost::multi_index::sequenced<>,
                        boost::multi_index::ordered_unique<boost::multi_index::global_fun<
                                const std::shared_ptr<profile_unit> &, std::string, profiler::profile_unit::_name>>
                    >
                > children;

                virtual void tic() {
                    watch.tic();
                }

                virtual double toc() {
                    return watch.toc();
                }

                double children_time() const {
                    double tm = 0;

                    for(auto c = children.begin(); c != children.end(); c++)
                        tm += (*c)->watch.total();

                    return tm;
                }

                size_t max_line_width(size_t level) const {
                    size_t w = name.size() + level;

                    for(auto c = children.begin(); c != children.end(); c++)
                        w = std::max(w, (*c)->max_line_width(level + shift_width));

                    return w;
                }

                void print(std::ostream &out,
                        size_t level, double total, size_t width) const
                {
                    using namespace std;
                    print_line(out, name, watch.total(), 100 * watch.total() / total, width, level);

                    if (watch.tics() > 1) {
                        out << " (" << setw(6) << watch.tics()
                            << "x; avg: " << setprecision(6) << scientific
                            << (watch.average() * 1e6) << " usec.)";
                    }

                    out << endl;

                    if (!children.empty()) {
                        double sec = watch.total() - children_time();
                        double perc = 100 * sec / total;
                        if(perc > 1e-1) {
                            print_line(out, "self", sec, perc, width, level + 1);
                            out << endl;
                        }
                    }

                    for(auto c = children.begin(); c != children.end(); c++)
                        (*c)->print(out, level + shift_width, total, width);
                }

                void print_line(std::ostream &out, const std::string &name,
                        double time, double perc, size_t width, size_t indent) const {
                    using namespace std;
                    out << "[" << setw(indent) << "" << name << ":"
                        << setw(width - indent - name.size()) << ""
                        << fixed << setw(10) << setprecision(3) << time << " sec."
                        << "] (" << setprecision(2) << setw(6) << perc << "%)";
                }

            private:
                static const size_t shift_width = 2U;
        };

        class cl_profile_unit : public profile_unit {
            public:
                cl_profile_unit(const std::string &name, std::vector<backend::command_queue> &queue)
                    : profile_unit(name), queue(queue) {}

                void tic() {
                    for(auto q = queue.begin(); q != queue.end(); ++q)
                        q->finish();

                    profile_unit::tic();
                }

                double toc() {
                    for(auto q = queue.begin(); q != queue.end(); ++q)
                        q->finish();

                    return profile_unit::toc();
                }
            private:
                std::vector<backend::command_queue> &queue;
        };

    public:
        /// Constructor.
        /**
         * \param queue vector of command queues.
         * \param name  Optional name to be used when profiling info is printed.
         */
        profiler(
                const std::vector<backend::command_queue> &queue = std::vector<backend::command_queue>(),
                const std::string &name = "Profile"
                ) : queue(queue)
        {
            auto root = std::shared_ptr<profile_unit>(new profile_unit(name));
            root->tic();
            stack.push_back(root);
        }

    private:
        void tic(profile_unit *u) {
            assert(!stack.empty());
            auto top = stack.back();
            auto new_unit = std::shared_ptr<profile_unit>(u);
            auto unit = *top->children.push_back(new_unit).first;
            unit->tic();
            stack.push_back(unit);
        }

    public:
        /// Starts a CPU timer.
        /**
         * Also pushes named interval to the top of the profiler hierarchy.
         * \param name name of the measured interval.
         */
        void tic_cpu(const std::string &name) {
            tic(new profile_unit(name));
        }

        /// Enqueues a marker into each of the provided queues.
        /**
         * Also pushes named interval to the top of the profiler hierarchy.
         * \param name name of the measured interval.
         */
        void tic_cl(const std::string &name) {
            assert(!queue.empty());
            tic(new cl_profile_unit(name, queue));
        }

        /// Returns time since last tic.
        /**
         * Also removes interval from the top of the profiler hierarchy.
         */
        double toc(const std::string &) {
            assert(stack.size() > 1);

            double delta = stack.back()->toc();
            stack.pop_back();

            return delta;
        }

        /// Outputs profile to the provided stream.
        void print(std::ostream &out) {
            boost::io::ios_all_saver stream_state(out);

            if(stack.size() != 1)
                out << "Warning! Profile is incomplete." << std::endl;

            auto root = stack.front();
            double length = root->toc();
            out << std::endl;
            root->print(out, 0, length, root->max_line_width(0));
        }

    private:
        std::vector<backend::command_queue> queue;
        std::deque<std::shared_ptr<profile_unit>> stack;
};

} // namespace vex

namespace std {

/// Sends the profiler summary to the output stream.
template <class Clock>
inline std::ostream& operator<<(std::ostream &os, vex::profiler<Clock> &prof) {
    prof.print(os);
    return os;
}

}

#endif
<commit_msg>Implement profiler::reset<commit_after>#ifndef VEXCL_PROFILER_HPP
#define VEXCL_PROFILER_HPP

/*
The MIT License

Copyright (c) 2012-2017 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   profiler.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  Simple OpenCL/Host profiler.
 */

#if defined(_MSC_VER) && ( defined(min) || defined(max) )
#  error Please define NOMINMAX macro globally in your project
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <memory>
#include <stack>
#include <vector>
#include <cassert>

#if defined(_MSC_VER) && (_MSC_VER < 1700)
#  define VEXCL_USE_BOOST_CHRONO
#  include <boost/chrono.hpp>
#else
#  include <chrono>
#endif

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/global_fun.hpp>
#include <boost/io/ios_state.hpp>

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/mean.hpp>

#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable: 4244)
#endif
#include <boost/accumulators/statistics/median.hpp>
#ifdef _MSC_VER
#  pragma warning(pop)
#endif

#include <vexcl/backend.hpp>

namespace vex {

/// A stopwatch that computes the median and mean of individual timings.
/**
 * \param Clock class that provides interface compatible with either
 *              boost::chrono or std::chrono clocks.
 */
template <
#ifdef VEXCL_USE_BOOST_CHRONO
    class Clock = boost::chrono::high_resolution_clock
#else
    class Clock = std::chrono::high_resolution_clock
#endif
    >
class stopwatch {
    boost::accumulators::accumulator_set<
        double,
        boost::accumulators::stats<
            boost::accumulators::tag::count,
            boost::accumulators::tag::sum,
            boost::accumulators::tag::mean,
            boost::accumulators::tag::median(boost::accumulators::with_p_square_quantile)
            >
        > acc;

    public:
        stopwatch() { tic(); }

        /// Start timer.
        inline void tic() {
            start = Clock::now();
        }

        /// Stop timer, return elapsed time in seconds.
        inline double toc() {
            const double delta = seconds(start, Clock::now());

            acc(delta);

            return delta;
        }

        /// Average time across tics.
        inline double average() const {
            namespace ba = boost::accumulators;

            return ba::count(acc) >= 3 ? ba::median(acc) : ba::mean(acc);
        }

        /// Total time spent in the timer.
        inline double total() const {
            return boost::accumulators::sum(acc);
        }

        /// Number of tics.
        inline size_t tics() const {
            return boost::accumulators::count(acc);
        }
    private:
        static double seconds(typename Clock::time_point begin, typename Clock::time_point end) {
            return typename Clock::duration(end - begin).count() *
                static_cast<double>(Clock::duration::period::num) /
                    Clock::duration::period::den;
        }

        typename Clock::time_point start;
};

/// Class for gathering and printing OpenCL and Host profiling info.
/**
 * \param Clock class that provides interface compatible with either
 *              boost::chrono or std::chrono clocks.
 * \param Avg   Kind of averaging used. AvgMedian is more stable, but may
 *              have high overhead when profiling is made in a loop.
 */
template <
#ifdef VEXCL_USE_BOOST_CHRONO
    class Clock = boost::chrono::high_resolution_clock
#else
    class Clock = std::chrono::high_resolution_clock
#endif
    >
class profiler {
    private:
        class profile_unit {
            public:
                profile_unit(std::string name) : watch(), name(name), children() {}
                virtual ~profile_unit() {}

                stopwatch<Clock> watch;
                std::string name;

                static std::string _name(const std::shared_ptr<profile_unit> &u) {
                    return u->name;
                }

                boost::multi_index_container<
                    std::shared_ptr<profile_unit>,
                    boost::multi_index::indexed_by<
                        boost::multi_index::sequenced<>,
                        boost::multi_index::ordered_unique<boost::multi_index::global_fun<
                                const std::shared_ptr<profile_unit> &, std::string, profiler::profile_unit::_name>>
                    >
                > children;

                virtual void tic() {
                    watch.tic();
                }

                virtual double toc() {
                    return watch.toc();
                }

                double children_time() const {
                    double tm = 0;

                    for(auto c = children.begin(); c != children.end(); c++)
                        tm += (*c)->watch.total();

                    return tm;
                }

                size_t max_line_width(size_t level) const {
                    size_t w = name.size() + level;

                    for(auto c = children.begin(); c != children.end(); c++)
                        w = std::max(w, (*c)->max_line_width(level + shift_width));

                    return w;
                }

                void print(std::ostream &out,
                        size_t level, double total, size_t width) const
                {
                    using namespace std;
                    print_line(out, name, watch.total(), 100 * watch.total() / total, width, level);

                    if (watch.tics() > 1) {
                        out << " (" << setw(6) << watch.tics()
                            << "x; avg: " << setprecision(6) << scientific
                            << (watch.average() * 1e6) << " usec.)";
                    }

                    out << endl;

                    if (!children.empty()) {
                        double sec = watch.total() - children_time();
                        double perc = 100 * sec / total;
                        if(perc > 1e-1) {
                            print_line(out, "self", sec, perc, width, level + 1);
                            out << endl;
                        }
                    }

                    for(auto c = children.begin(); c != children.end(); c++)
                        (*c)->print(out, level + shift_width, total, width);
                }

                void print_line(std::ostream &out, const std::string &name,
                        double time, double perc, size_t width, size_t indent) const {
                    using namespace std;
                    out << "[" << setw(indent) << "" << name << ":"
                        << setw(width - indent - name.size()) << ""
                        << fixed << setw(10) << setprecision(3) << time << " sec."
                        << "] (" << setprecision(2) << setw(6) << perc << "%)";
                }

            private:
                static const size_t shift_width = 2U;
        };

        class cl_profile_unit : public profile_unit {
            public:
                cl_profile_unit(const std::string &name, std::vector<backend::command_queue> &queue)
                    : profile_unit(name), queue(queue) {}

                void tic() {
                    for(auto q = queue.begin(); q != queue.end(); ++q)
                        q->finish();

                    profile_unit::tic();
                }

                double toc() {
                    for(auto q = queue.begin(); q != queue.end(); ++q)
                        q->finish();

                    return profile_unit::toc();
                }
            private:
                std::vector<backend::command_queue> &queue;
        };

    public:
        /// Constructor.
        /**
         * \param queue vector of command queues.
         * \param name  Optional name to be used when profiling info is printed.
         */
        profiler(
                const std::vector<backend::command_queue> &queue = std::vector<backend::command_queue>(),
                const std::string &name = "Profile"
                ) : queue(queue)
        {
            auto root = std::shared_ptr<profile_unit>(new profile_unit(name));
            root->tic();
            stack.push_back(root);
        }

        void reset() {
            auto root = std::shared_ptr<profile_unit>(new profile_unit(stack.front()->name));
            stack.clear();
            root->tic();
            stack.push_back(root);
        }

    private:
        void tic(profile_unit *u) {
            assert(!stack.empty());
            auto top = stack.back();
            auto new_unit = std::shared_ptr<profile_unit>(u);
            auto unit = *top->children.push_back(new_unit).first;
            unit->tic();
            stack.push_back(unit);
        }

    public:
        /// Starts a CPU timer.
        /**
         * Also pushes named interval to the top of the profiler hierarchy.
         * \param name name of the measured interval.
         */
        void tic_cpu(const std::string &name) {
            tic(new profile_unit(name));
        }

        /// Enqueues a marker into each of the provided queues.
        /**
         * Also pushes named interval to the top of the profiler hierarchy.
         * \param name name of the measured interval.
         */
        void tic_cl(const std::string &name) {
            assert(!queue.empty());
            tic(new cl_profile_unit(name, queue));
        }

        /// Returns time since last tic.
        /**
         * Also removes interval from the top of the profiler hierarchy.
         */
        double toc(const std::string &) {
            assert(stack.size() > 1);

            double delta = stack.back()->toc();
            stack.pop_back();

            return delta;
        }

        /// Outputs profile to the provided stream.
        void print(std::ostream &out) {
            boost::io::ios_all_saver stream_state(out);

            if(stack.size() != 1)
                out << "Warning! Profile is incomplete." << std::endl;

            auto root = stack.front();
            double length = root->toc();
            out << std::endl;
            root->print(out, 0, length, root->max_line_width(0));
        }

    private:
        std::vector<backend::command_queue> queue;
        std::deque<std::shared_ptr<profile_unit>> stack;
};

} // namespace vex

namespace std {

/// Sends the profiler summary to the output stream.
template <class Clock>
inline std::ostream& operator<<(std::ostream &os, vex::profiler<Clock> &prof) {
    prof.print(os);
    return os;
}

}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <ParameterMgrFullConnector.h>
#include <Tokenizer.h>
#include <Utility.h>

#include <iostream>
#include <sstream>
#include <memory>
#include <string>
#include <limits>
#include <algorithm>
#include <stdexcept>

using std::string;

class MyLogger final : public CParameterMgrFullConnector::ILogger
{
public:
    void info(const std::string &log) override { std::cerr << "Info: " << log << std::endl; }

    void warning(const std::string &log) override { std::cerr << "Warning: " << log << std::endl; }
};

class XmlGenerator
{
public:
    using Exception = std::runtime_error;

    XmlGenerator(const string &toplevelConfig, bool validate, bool verbose, string schemasDir)
        : mConnector(toplevelConfig), mCommandHandler(mConnector.createCommandHandler())
    {
        if (verbose) {
            mLogger.reset(new MyLogger);
            mConnector.setLogger(mLogger.get());
        }

        mConnector.setSchemaUri(schemasDir);
        mConnector.setValidateSchemasOnStart(validate);

        // Disable irrelevant failure conditions
        mConnector.setFailureOnMissingSubsystem(false);
        mConnector.setFailureOnFailedSettingsLoad(false);

        // Disable the remote interface because we don't need it and it might
        // get in the way (e.g. the port is already in use)
        mConnector.setForceNoRemoteInterface(true);
    }

    /** Reads each line of the input stream and takes an action accordingly
     *
     * Returns when the input stream reaches end of file
     *
     * The commands are the usual PF tunning commands and some additional specials.
     * Special commands:
     *  - `createSelectionCriterion inclusive|exclusive <name> <value> [value, ...]`
     *    Create a criterion with the given properties.
     *  - `start` start the Parameter Framework. All criteria must have been created.
     *
     * @param[in] input The input stream to read from
     *
     * @return the number of error that occurred
     */
    size_t parse(std::istream &input);

    /** Prints the Parameter Framework's instance configuration
     *
     * @param[out] output The stream to which output the configuration
     */
    void exportDomains(std::ostream &output);

private:
    void addCriteria(std::vector<string> &tokens);
    void start();

    CParameterMgrFullConnector mConnector;
    std::unique_ptr<MyLogger> mLogger;
    std::unique_ptr<CommandHandlerInterface> mCommandHandler;
};

void XmlGenerator::addCriteria(std::vector<string> &tokens)
{
    if (tokens.size() < 3) {
        throw Exception("Not enough arguments to criterion creation request");
    }

    auto inclusiveness = tokens.front() == "inclusive";
    tokens.erase(begin(tokens));

    auto name = tokens.front();
    tokens.erase(begin(tokens));

    auto criterionType = mConnector.createSelectionCriterionType(inclusiveness);
    if (criterionType == nullptr) {
        throw Exception("Failed to create an " +
                        string(inclusiveness ? "inclusive" : "exclusive") + " criterion type");
    }

    int index = 0;
    for (const auto &literalValue : tokens) {
        // inclusive criteria are bitfields
        int numericalValue = inclusiveness ? 1 << index : index;
        string error;
        bool success = criterionType->addValuePair(numericalValue, literalValue, error);

        if (not success) {
            std::ostringstream message;
            message << "Valuepair (" << numericalValue << ", '" << literalValue
                    << "') rejected for " << name << ": " << error;
            throw Exception(message.str());
        }
        index++;
    }

    // We don't need to keep a reference to the criterion - no need to store
    // the returned pointer.
    if (mConnector.createSelectionCriterion(name, criterionType) == nullptr) {
        throw Exception("Failed to create criterion '" + name + "'");
    }
}

size_t XmlGenerator::parse(std::istream &input)
{
    string line;
    size_t errorNb = 0;
    while (not input.eof()) {
        std::getline(std::cin, line);

        auto tokens = Tokenizer(line, string(1, '\0')).split();
        if (tokens.empty()) {
            continue;
        }
        auto command = tokens.front();
        tokens.erase(begin(tokens)); // drop the command name

        if (command == "createSelectionCriterion") {
            addCriteria(tokens);
        } else if (command == "start") {
            start();
        } else {
            string output;
            if (not mCommandHandler->process(command, tokens, output)) {
                errorNb++;
                std::cerr << "Failed to executing command: "
                          << utility::join<string>(begin(tokens), end(tokens),
                                                   [](string l, string r) { return l + ' ' + r; })
                          << std::endl
                          << output << std::endl;
            }
        }
    }
    return errorNb;
}

void XmlGenerator::start()
{
    string error;
    if (not mConnector.start(error)) {
        throw Exception("Start failed: " + error);
    }

    error.clear();
    // Switch to tunning mode as the tunning commands
    // are the only commands possible with this connector.
    if (not mConnector.setTuningMode(true, error)) {
        throw Exception("Failed to turn tuning mode on: " + error);
    }
}

void XmlGenerator::exportDomains(std::ostream &output)
{
    string error;
    string domains;
    if (not mConnector.exportDomainsXml(domains, true, false, error)) {
        throw Exception("Export failed: " + error);
    } else {
        output << domains;
    }
}

static const char *usage =
    R"(Usage: domainGeneratorConnector <top-level config> <verbose> <validate> <path>

 <verbose>       '1': verbose,  else: terse
 <validate>      '1' validate, else: don't validate
 <path>          path to the schemas' directory

All arguments are mandatory. If no validation is required,
the path to the schemas can be an empty string.

Exit with the number of (recoverable or not error) that occured.

This program is not intended to be used standalone but rather called through
domainGenerator.py)";

/** On linux at least, a program can not exit with a value greater than 255.
 * @return min(code, 255);
 */
template <class T>
static inline int normalizeExitCode(T code)
{
    return int(std::min<T>(code, std::numeric_limits<uint8_t>::max()));
}

int main(int argc, char *argv[])
{
    using std::endl;

    if (argc <= 4) {
        std::cerr << usage << std::endl;
        return 1;
    }

    string toplevelConfig = argv[1];
    bool verbose = string(argv[2]) == "verbose";
    bool validate = string(argv[3]) == "validate";
    string schemasDir = argv[4];

    if (verbose) {
        std::cerr << "Domain generator config:" << endl
                  << "    toplevelConfig=" << toplevelConfig << endl
                  << "    verbose=" << verbose << endl
                  << "    validate=" << validate << endl
                  << "    schemasDir=" << schemasDir << endl;
    }

    try {
        XmlGenerator xmlGenerator(toplevelConfig, validate, verbose, schemasDir);
        auto errorNb = xmlGenerator.parse(std::cin);
        // TODO: add a check for conflicting elements
        xmlGenerator.exportDomains(std::cout);

        return normalizeExitCode(errorNb);
    } catch (std::exception &e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }
}
<commit_msg>domainGeneratorConnector: correct the 'usage' message<commit_after>/*
 * Copyright (c) 2015, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <ParameterMgrFullConnector.h>
#include <Tokenizer.h>
#include <Utility.h>

#include <iostream>
#include <sstream>
#include <memory>
#include <string>
#include <limits>
#include <algorithm>
#include <stdexcept>

using std::string;

class MyLogger final : public CParameterMgrFullConnector::ILogger
{
public:
    void info(const std::string &log) override { std::cerr << "Info: " << log << std::endl; }

    void warning(const std::string &log) override { std::cerr << "Warning: " << log << std::endl; }
};

class XmlGenerator
{
public:
    using Exception = std::runtime_error;

    XmlGenerator(const string &toplevelConfig, bool validate, bool verbose, string schemasDir)
        : mConnector(toplevelConfig), mCommandHandler(mConnector.createCommandHandler())
    {
        if (verbose) {
            mLogger.reset(new MyLogger);
            mConnector.setLogger(mLogger.get());
        }

        mConnector.setSchemaUri(schemasDir);
        mConnector.setValidateSchemasOnStart(validate);

        // Disable irrelevant failure conditions
        mConnector.setFailureOnMissingSubsystem(false);
        mConnector.setFailureOnFailedSettingsLoad(false);

        // Disable the remote interface because we don't need it and it might
        // get in the way (e.g. the port is already in use)
        mConnector.setForceNoRemoteInterface(true);
    }

    /** Reads each line of the input stream and takes an action accordingly
     *
     * Returns when the input stream reaches end of file
     *
     * The commands are the usual PF tunning commands and some additional specials.
     * Special commands:
     *  - `createSelectionCriterion inclusive|exclusive <name> <value> [value, ...]`
     *    Create a criterion with the given properties.
     *  - `start` start the Parameter Framework. All criteria must have been created.
     *
     * @param[in] input The input stream to read from
     *
     * @return the number of error that occurred
     */
    size_t parse(std::istream &input);

    /** Prints the Parameter Framework's instance configuration
     *
     * @param[out] output The stream to which output the configuration
     */
    void exportDomains(std::ostream &output);

private:
    void addCriteria(std::vector<string> &tokens);
    void start();

    CParameterMgrFullConnector mConnector;
    std::unique_ptr<MyLogger> mLogger;
    std::unique_ptr<CommandHandlerInterface> mCommandHandler;
};

void XmlGenerator::addCriteria(std::vector<string> &tokens)
{
    if (tokens.size() < 3) {
        throw Exception("Not enough arguments to criterion creation request");
    }

    auto inclusiveness = tokens.front() == "inclusive";
    tokens.erase(begin(tokens));

    auto name = tokens.front();
    tokens.erase(begin(tokens));

    auto criterionType = mConnector.createSelectionCriterionType(inclusiveness);
    if (criterionType == nullptr) {
        throw Exception("Failed to create an " +
                        string(inclusiveness ? "inclusive" : "exclusive") + " criterion type");
    }

    int index = 0;
    for (const auto &literalValue : tokens) {
        // inclusive criteria are bitfields
        int numericalValue = inclusiveness ? 1 << index : index;
        string error;
        bool success = criterionType->addValuePair(numericalValue, literalValue, error);

        if (not success) {
            std::ostringstream message;
            message << "Valuepair (" << numericalValue << ", '" << literalValue
                    << "') rejected for " << name << ": " << error;
            throw Exception(message.str());
        }
        index++;
    }

    // We don't need to keep a reference to the criterion - no need to store
    // the returned pointer.
    if (mConnector.createSelectionCriterion(name, criterionType) == nullptr) {
        throw Exception("Failed to create criterion '" + name + "'");
    }
}

size_t XmlGenerator::parse(std::istream &input)
{
    string line;
    size_t errorNb = 0;
    while (not input.eof()) {
        std::getline(std::cin, line);

        auto tokens = Tokenizer(line, string(1, '\0')).split();
        if (tokens.empty()) {
            continue;
        }
        auto command = tokens.front();
        tokens.erase(begin(tokens)); // drop the command name

        if (command == "createSelectionCriterion") {
            addCriteria(tokens);
        } else if (command == "start") {
            start();
        } else {
            string output;
            if (not mCommandHandler->process(command, tokens, output)) {
                errorNb++;
                std::cerr << "Failed to executing command: "
                          << utility::join<string>(begin(tokens), end(tokens),
                                                   [](string l, string r) { return l + ' ' + r; })
                          << std::endl
                          << output << std::endl;
            }
        }
    }
    return errorNb;
}

void XmlGenerator::start()
{
    string error;
    if (not mConnector.start(error)) {
        throw Exception("Start failed: " + error);
    }

    error.clear();
    // Switch to tunning mode as the tunning commands
    // are the only commands possible with this connector.
    if (not mConnector.setTuningMode(true, error)) {
        throw Exception("Failed to turn tuning mode on: " + error);
    }
}

void XmlGenerator::exportDomains(std::ostream &output)
{
    string error;
    string domains;
    if (not mConnector.exportDomainsXml(domains, true, false, error)) {
        throw Exception("Export failed: " + error);
    } else {
        output << domains;
    }
}

static const char *usage =
    R"(Usage: domainGeneratorConnector <top-level config> <verbose> <validate> <path>

 <verbose>       'verbose': verbose, else: terse
 <validate>      'validate': validate, else: don't validate
 <path>          path to the schemas' directory

All arguments are mandatory. If no validation is required,
the path to the schemas can be an empty string.

Exit with the number of (recoverable or not error) that occured.

This program is not intended to be used standalone but rather called through
domainGenerator.py)";

/** On linux at least, a program can not exit with a value greater than 255.
 * @return min(code, 255);
 */
template <class T>
static inline int normalizeExitCode(T code)
{
    return int(std::min<T>(code, std::numeric_limits<uint8_t>::max()));
}

int main(int argc, char *argv[])
{
    using std::endl;

    if (argc <= 4) {
        std::cerr << usage << std::endl;
        return 1;
    }

    string toplevelConfig = argv[1];
    bool verbose = string(argv[2]) == "verbose";
    bool validate = string(argv[3]) == "validate";
    string schemasDir = argv[4];

    if (verbose) {
        std::cerr << "Domain generator config:" << endl
                  << "    toplevelConfig=" << toplevelConfig << endl
                  << "    verbose=" << verbose << endl
                  << "    validate=" << validate << endl
                  << "    schemasDir=" << schemasDir << endl;
    }

    try {
        XmlGenerator xmlGenerator(toplevelConfig, validate, verbose, schemasDir);
        auto errorNb = xmlGenerator.parse(std::cin);
        // TODO: add a check for conflicting elements
        xmlGenerator.exportDomains(std::cout);

        return normalizeExitCode(errorNb);
    } catch (std::exception &e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }
}
<|endoftext|>


<commit_before>#include<bits/stdc++.h>
using namespace std;

int main(){
  char numbers[] = "0123456789";
  for(int i=1;i<1000000;i++)
    next_permutation(numbers,numbers+10);
  cout << numbers << endl;
}
<commit_msg>Update solution_1.cpp<commit_after>#include<bits/stdc++.h>
using namespace std;

int main(){
  char numbers[] = "0123456789";
  for(int i=1;i<1000000;i++){
    next_permutation(numbers,numbers+10);
  }
  cout << numbers << endl;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright (c) 2014-2015 Leandro T. C. Melo (ltcmelo@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 * USA
 *****************************************************************************/

/*--------------------------*/
/*--- The UaiSo! Project ---*/
/*--------------------------*/

#include "Python/PyIncrementalLexer.h"

using namespace uaiso;

PyIncrementalLexer::PyIncrementalLexer()
{}

PyIncrementalLexer::~PyIncrementalLexer()
{}

void PyIncrementalLexer::lex(const std::string& source)
{}
<commit_msg>Py: Incremental lexer<commit_after>/******************************************************************************
 * Copyright (c) 2014-2015 Leandro T. C. Melo (ltcmelo@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 * USA
 *****************************************************************************/

/*--------------------------*/
/*--- The UaiSo! Project ---*/
/*--------------------------*/

#include "Python/PyIncrementalLexer.h"
#include "Python/PyLexer.h"
#include "Parsing/ParsingContext.h"
#include "Parsing/IncrementalLexer__.h"

using namespace uaiso;

PyIncrementalLexer::PyIncrementalLexer()
{
    P->context_.reset(new ParsingContext);
    P->context_->setAllowComments(true);
}

PyIncrementalLexer::~PyIncrementalLexer()
{}

void PyIncrementalLexer::lex(const std::string& source)
{
    P->phrasing_.reset(new Phrasing);
    P->context_->collectPhrasing(P->phrasing_.get());

    PyLexer lexer;
    lexer.setContext(P->context_.get());
    lexer.setBuffer(source.c_str(), source.size());

    Token tk;
    do {
        tk = lexer.lex();
    } while (tk != TK_EOP);
    std::cout << std::endl;
}
<|endoftext|>


<commit_before>#include "shared.h"

int main(int argc, char *argv[]) {

  sink(_strdup(getenv("VAR")));
  sink(strdup(getenv("VAR")));
  sink(unmodeled_function(getenv("VAR")));

  char untainted_buf[100] = "";
  char buf[100] = "VAR = ";
  sink(strcat(buf, getenv("VAR")));

  sink(buf);
  sink(untainted_buf); // the two buffers would be conflated if we added flow through all partial chi inputs

  return 0;
}

typedef unsigned int inet_addr_retval;
inet_addr_retval inet_addr(const char *dotted_address);
void sink(inet_addr_retval);

void test_indirect_arg_to_model() {
    // This test is non-sensical but carefully arranged so we get data flow into
    // inet_addr not through the function argument but through its associated
    // read side effect.
    void *env_pointer = getenv("VAR"); // env_pointer is tainted, not its data.
    inet_addr_retval a = inet_addr((const char *)&env_pointer);
    sink(a);
}

class B {
    public:
    virtual void f(const char*) = 0;
};

class D1 : public B {};

class D2 : public D1 {
    public:
    void f(const char* p) override {}
};

class D3 : public D2 {
    public:
    void f(const char* p) override {
        sink(p);
    }
};

void test_dynamic_cast() {
    B* b = new D3();
    b->f(getenv("VAR")); // tainted

    ((D2*)b)->f(getenv("VAR")); // tainted
    static_cast<D2*>(b)->f(getenv("VAR")); // tainted
    dynamic_cast<D2*>(b)->f(getenv("VAR")); // tainted
    reinterpret_cast<D2*>(b)->f(getenv("VAR")); // tainted

    B* b2 = new D2();
    b2->f(getenv("VAR"));

    ((D2*)b2)->f(getenv("VAR"));
    static_cast<D2*>(b2)->f(getenv("VAR"));
    dynamic_cast<D2*>(b2)->f(getenv("VAR"));
    reinterpret_cast<D2*>(b2)->f(getenv("VAR"));

    dynamic_cast<D3*>(b2)->f(getenv("VAR")); // tainted [FALSE POSITIVE]
}

namespace std {
  template< class T >
  T&& move( T&& t ) noexcept;
}

void test_std_move() {
  sink(std::move(getenv("VAR")));
}

void flow_to_outparam(char ** ret, char *arg) {
    *ret = arg;
}

void test_outparams() {
    char *p2 = nullptr;
    flow_to_outparam(&p2, getenv("VAR"));
    sink(p2); // tainted
}

struct XY {
  int x;
  int y;
};

void taint_y(XY *xyp) {
  int tainted = getenv("VAR")[0];
  xyp->y = tainted;
}

void test_conflated_fields3() {
  XY xy;
  xy.x = 0;
  taint_y(&xy);
  sink(xy.x); // not tainted
}

struct Point {
  int x;
  int y;

  void callSink() {
    sink(this->x); // tainted
    sink(this->y); // not tainted
  }
};

void test_conflated_fields1() {
  Point p;
  p.x = getenv("VAR")[0];
  sink(p.x); // tainted
  sink(p.y); // not tainted
  p.callSink();
}

void taint_x(Point *pp) {
  pp->x = getenv("VAR")[0];
}

void y_to_sink(Point *pp) {
  sink(pp->y); // not tainted
}

void test_conflated_fields2() {
  Point p;
  taint_x(&p);
  y_to_sink(&p);
}

void sink(Point*);
void sink(Point);

void test_field_to_obj_taint_object(Point p) {
  p.x = getenv("VAR")[0];
  sink(p); // not tainted
  sink(p.x); // tainted
}

void test_field_to_obj_taint_object_addrof(Point p) {
  taint_x(&p);
  sink(p); // tainted
  sink(&p); // tainted
  sink(p.x); // tainted
}

void test_field_to_obj_taint_pointer(Point* pp) {
  pp->x = getenv("VAR")[0];
  sink(pp); // tainted
  sink(*pp); // not tainted
}

void call_sink_on_object(Point* pp) {
  sink(pp); // tainted
  sink(*pp); // tainted
}

void test_field_to_obj_taint_call_sink(Point* pp) {
  pp->x = getenv("VAR")[0];
  call_sink_on_object(pp);
}

void test_field_to_obj_taint_through_setter(Point* pp) {
  taint_x(pp);
  sink(pp); // tainted
  sink(*pp); // not tainted
}

Point* getPoint();

void test_field_to_obj_local_variable() {
  Point* pp = getPoint();
  pp->x = getenv("VAR")[0];
  sink(pp); // not tainted
  sink(*pp); // not tainted
}

void test_field_to_obj_taint_array(Point* pp, int i) {
  pp[0].x = getenv("VAR")[0];
  sink(pp[i]); // not tainted
  sink(pp); // tainted
  sink(*pp); // not tainted
}

void test_field_to_obj_test_pointer_arith(Point* pp) {
  (pp + sizeof(*pp))->x = getenv("VAR")[0];
  sink(pp); // tainted
  sink(pp + sizeof(*pp)); // tainted
}<commit_msg>C++: Add annotations describing whether the flow is an instance of field-to-object flow<commit_after>#include "shared.h"

int main(int argc, char *argv[]) {

  sink(_strdup(getenv("VAR")));
  sink(strdup(getenv("VAR")));
  sink(unmodeled_function(getenv("VAR")));

  char untainted_buf[100] = "";
  char buf[100] = "VAR = ";
  sink(strcat(buf, getenv("VAR")));

  sink(buf);
  sink(untainted_buf); // the two buffers would be conflated if we added flow through all partial chi inputs

  return 0;
}

typedef unsigned int inet_addr_retval;
inet_addr_retval inet_addr(const char *dotted_address);
void sink(inet_addr_retval);

void test_indirect_arg_to_model() {
    // This test is non-sensical but carefully arranged so we get data flow into
    // inet_addr not through the function argument but through its associated
    // read side effect.
    void *env_pointer = getenv("VAR"); // env_pointer is tainted, not its data.
    inet_addr_retval a = inet_addr((const char *)&env_pointer);
    sink(a);
}

class B {
    public:
    virtual void f(const char*) = 0;
};

class D1 : public B {};

class D2 : public D1 {
    public:
    void f(const char* p) override {}
};

class D3 : public D2 {
    public:
    void f(const char* p) override {
        sink(p);
    }
};

void test_dynamic_cast() {
    B* b = new D3();
    b->f(getenv("VAR")); // tainted

    ((D2*)b)->f(getenv("VAR")); // tainted
    static_cast<D2*>(b)->f(getenv("VAR")); // tainted
    dynamic_cast<D2*>(b)->f(getenv("VAR")); // tainted
    reinterpret_cast<D2*>(b)->f(getenv("VAR")); // tainted

    B* b2 = new D2();
    b2->f(getenv("VAR"));

    ((D2*)b2)->f(getenv("VAR"));
    static_cast<D2*>(b2)->f(getenv("VAR"));
    dynamic_cast<D2*>(b2)->f(getenv("VAR"));
    reinterpret_cast<D2*>(b2)->f(getenv("VAR"));

    dynamic_cast<D3*>(b2)->f(getenv("VAR")); // tainted [FALSE POSITIVE]
}

namespace std {
  template< class T >
  T&& move( T&& t ) noexcept;
}

void test_std_move() {
  sink(std::move(getenv("VAR")));
}

void flow_to_outparam(char ** ret, char *arg) {
    *ret = arg;
}

void test_outparams() {
    char *p2 = nullptr;
    flow_to_outparam(&p2, getenv("VAR"));
    sink(p2); // tainted
}

struct XY {
  int x;
  int y;
};

void taint_y(XY *xyp) {
  int tainted = getenv("VAR")[0];
  xyp->y = tainted;
}

void test_conflated_fields3() {
  XY xy;
  xy.x = 0;
  taint_y(&xy);
  sink(xy.x); // not tainted
}

struct Point {
  int x;
  int y;

  void callSink() {
    sink(this->x); // tainted
    sink(this->y); // not tainted
  }
};

void test_conflated_fields1() {
  Point p;
  p.x = getenv("VAR")[0];
  sink(p.x); // tainted
  sink(p.y); // not tainted
  p.callSink();
}

void taint_x(Point *pp) {
  pp->x = getenv("VAR")[0];
}

void y_to_sink(Point *pp) {
  sink(pp->y); // not tainted
}

void test_conflated_fields2() {
  Point p;
  taint_x(&p);
  y_to_sink(&p);
}

void sink(Point*);
void sink(Point);

void test_field_to_obj_taint_object(Point p) {
  p.x = getenv("VAR")[0];
  sink(p); // not tainted
  sink(p.x); // tainted
}

void test_field_to_obj_taint_object_addrof(Point p) {
  taint_x(&p);
  sink(p); // tainted [field -> object]
  sink(&p); // tainted [field -> object]
  sink(p.x); // tainted
}

void test_field_to_obj_taint_pointer(Point* pp) {
  pp->x = getenv("VAR")[0];
  sink(pp); // tainted [field -> object]
  sink(*pp); // not tainted
}

void call_sink_on_object(Point* pp) {
  sink(pp); // tainted [field -> object]
  sink(*pp); // tainted [field -> object]
}

void test_field_to_obj_taint_call_sink(Point* pp) {
  pp->x = getenv("VAR")[0];
  call_sink_on_object(pp);
}

void test_field_to_obj_taint_through_setter(Point* pp) {
  taint_x(pp);
  sink(pp); // tainted [field -> object]
  sink(*pp); // not tainted
}

Point* getPoint();

void test_field_to_obj_local_variable() {
  Point* pp = getPoint();
  pp->x = getenv("VAR")[0];
  sink(pp); // not tainted
  sink(*pp); // not tainted
}

void test_field_to_obj_taint_array(Point* pp, int i) {
  pp[0].x = getenv("VAR")[0];
  sink(pp[i]); // not tainted
  sink(pp); // tainted [field -> object]
  sink(*pp); // not tainted
}

void test_field_to_obj_test_pointer_arith(Point* pp) {
  (pp + sizeof(*pp))->x = getenv("VAR")[0];
  sink(pp); // tainted [field -> object]
  sink(pp + sizeof(*pp)); // tainted [field -> object]
}<|endoftext|>


<commit_before>#include "RulerWidget.h"
#include "QtGlSliceView.h"
#include <Qt>
#include <QtOpenGL/qgl.h>
#include <QMouseEvent>
#include <QGuiApplication>
#include <cmath>
#include "itkMath.h"

bool operator< (std::unique_ptr< RulerToolMetaData > const& lhs, std::unique_ptr< RulerToolMetaData > const& rhs) {
    return lhs->sortId < rhs->sortId;
}

RainbowMetaDataGenerator::RainbowMetaDataGenerator() {
    curColor = colors.begin();
}

std::unique_ptr< RulerToolMetaData > RainbowMetaDataGenerator::operator()(void) {
    std::string name = std::to_string(curId);
    QColor color = QColor(QString(curColor->c_str()));
    int id = curId;

    // wrap around to the beginning of the color list if at end
    ++curColor;
    if (curColor == colors.end()) {
        curColor = colors.begin();
    }

    ++curId;
    return std::unique_ptr< RulerToolMetaData >(new RulerToolMetaData{ id, name, color });
}

std::unique_ptr< RulerToolMetaData > ONSDMetaDataGenerator::operator()(void) {
    std::string name = flipper ? "R1" : "ONSD";
    QColor color = QColor(colors[(int)flipper].c_str());
    int id = curId;

    flipper = !flipper;
    ++curId;

    return std::unique_ptr< RulerToolMetaData >(new RulerToolMetaData{ id, name, color });
}

RulerToolMetaDataFactory::RulerToolMetaDataFactory(std::unique_ptr< MetaDataGenerator > generator) : generator{ std::move(generator) } { }

std::unique_ptr< RulerToolMetaData > RulerToolMetaDataFactory::getNext() {
    std::unique_ptr< RulerToolMetaData > ans;
    if (refunds.size() > 0) {
        ans = std::move(*(refunds.begin()));
        refunds.erase(refunds.begin());
    }
    else {
        ans = (*generator)();
    }
    return ans;
}

void RulerToolMetaDataFactory::refund(std::unique_ptr< RulerToolMetaData > ruler_meta) {
    refunds.push_back(std::move(ruler_meta));
    std::sort(refunds.begin(), refunds.end());
}

RulerTool::RulerTool(QtGlSliceView* parent0, PointType3D &index0, std::unique_ptr< RulerToolMetaData > metaData) :
    parent{ parent0 }, indices{ index0, index0 }, points{ parent0->indexToPhysicalPoint(index0), parent0->indexToPhysicalPoint(index0) }, metaData{ std::move(metaData) }, clickRadius{ 10.0 }, state{ RulerToolState::drawing }, floatingIndex{ 1 }, crossStart{ 18 }, crossEnd{ 3 }, lineWidth{ 4 }
{

}

RulerTool::~RulerTool() {}

int RulerTool::isOver(double index[]) const {
    int ans = -1;
    auto screenPt = parent->indexToScreenPoint(PointType3D(index));
    if (screenPt.EuclideanDistanceTo(parent->indexToScreenPoint(indices[0])) < clickRadius) {
        ans = 0;
    }
    else if (screenPt.EuclideanDistanceTo(parent->indexToScreenPoint(indices[1])) < clickRadius) {
        ans = 1;
    }
    return ans;
}

void RulerTool::updateFloatingIndex(double index[]) {
    this->indices[this->floatingIndex] = PointType3D(index);
    this->points[this->floatingIndex] = this->parent->indexToPhysicalPoint(index);
}

void RulerTool::setFloatingIndex(int id) {
    this->floatingIndex = id;
}

int RulerTool::getFloatingIndex() const {
    return this->floatingIndex;
}

double RulerTool::length() {
    return this->points[0].EuclideanDistanceTo(this->points[1]);
}

void RulerTool::paint() {

    QPainter painter(this->parent);
    QPen pen;

    // could optimize this by memoization and catching parent stage changes
    PointType2D screen0 = parent->indexToScreenPoint(indices[0]);
    PointType2D screen1 = parent->indexToScreenPoint(indices[1]);

    QColor color = metaData->color;
    color.setAlphaF(0.7);
    pen.setWidth(lineWidth);
    pen.setColor(color);
    painter.setPen(pen);

    // TODO make line dotted

    // crosshair1
    painter.drawLine(QLine(screen0[0] - crossStart, screen0[1] - crossStart, screen0[0] - crossEnd, screen0[1] - crossEnd));
    painter.drawLine(QLine(screen0[0] + crossStart, screen0[1] + crossStart, screen0[0] + crossEnd, screen0[1] + crossEnd));
    painter.drawLine(QLine(screen0[0] - crossStart, screen0[1] + crossStart, screen0[0] - crossEnd, screen0[1] + crossEnd));
    painter.drawLine(QLine(screen0[0] + crossStart, screen0[1] - crossStart, screen0[0] + crossEnd, screen0[1] - crossEnd));

    // crosshair2
    painter.drawLine(QLine(screen1[0] - crossStart, screen1[1] - crossStart, screen1[0] - crossEnd, screen1[1] - crossEnd));
    painter.drawLine(QLine(screen1[0] + crossStart, screen1[1] + crossStart, screen1[0] + crossEnd, screen1[1] + crossEnd));
    painter.drawLine(QLine(screen1[0] - crossStart, screen1[1] + crossStart, screen1[0] - crossEnd, screen1[1] + crossEnd));
    painter.drawLine(QLine(screen1[0] + crossStart, screen1[1] - crossStart, screen1[0] + crossEnd, screen1[1] - crossEnd));

    QPen pen2;
    pen2.setWidth(lineWidth);
    pen2.setColor(color);
    pen2.setStyle(Qt::DashDotLine);
    painter.setPen(pen2);

    //line
    painter.drawLine(QLine(screen0[0], screen0[1], screen1[0], screen1[1]));

}

std::string RulerTool::toJson() {
    char txt[256];

    int n = snprintf(txt, sizeof(txt),
        "{ \"name\" : \"%s\", \"indices\" : [ [%.4f, %.4f, %.4f], [%.4f, %.4f, %.4f] ], \"points\" : [ [%.4f, %.4f, %.4f], [%.4f, %.4f, %.4f] ], \"distance\" : %.4f}",
        metaData->name.c_str(),
        indices[0].GetElement(0),
        indices[0].GetElement(1),
        indices[0].GetElement(2),
        indices[1].GetElement(0),
        indices[1].GetElement(1),
        indices[1].GetElement(2),
        points[0].GetElement(0),
        points[0].GetElement(1),
        points[0].GetElement(2),
        points[1].GetElement(0),
        points[1].GetElement(1),
        points[1].GetElement(2),
        points[0].EuclideanDistanceTo(points[1]));

    if (n >= sizeof(txt)) {
        throw "RulerTool::toJson tried to write too big of string";
    }
    return std::string(txt);
}

RulerToolCollection::RulerToolCollection(QtGlSliceView* parent, std::shared_ptr< RulerToolMetaDataFactory > metaDataFactory, unsigned short axis, unsigned int slice)
    : parent{ parent }, metaDataFactory{ metaDataFactory }, axis{ axis }, slice{ slice }, currentId { -1 }, state { RulerToolState::standing }
{

}

RulerToolCollection::~RulerToolCollection() {}

void RulerToolCollection::handleMouseEvent(QMouseEvent* event, double index[]) {

    int over = -1;
    switch (this->state) {
    case RulerToolState::standing:
        over = isOver(index);
        if (over >= 0) {
            if (QGuiApplication::overrideCursor() == nullptr) {
                QGuiApplication::setOverrideCursor(Qt::OpenHandCursor);
            }
            if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::RightButton) { // we're over a ruler and have right-clicked to move the crosshair
                this->currentId = over;
                RulerTool* r = rulers[currentId].get();
                r->setFloatingIndex(r->isOver(index));
                this->state = RulerToolState::drawing;
                r->paint();
            }
        }
        else {
            QGuiApplication::restoreOverrideCursor();
        }

        // we're idle and we're clicking to create a new ruler
        if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::LeftButton) {
            // blank click on screen, make a ruler

            std::unique_ptr< RulerTool > r(new RulerTool(this->parent, RulerTool::PointType3D(index), metaDataFactory->getNext()));
            this->rulers.push_back(std::move(r));
            this->currentId = this->rulers.size() - 1;
            this->state = RulerToolState::drawing;
            this->paint();
        }
        break;
    case RulerToolState::drawing:
        if (QGuiApplication::overrideCursor() != nullptr) {
            QGuiApplication::restoreOverrideCursor(); // if we are drawing go back to a normal cursor, even if we're over a ruler
        }
        // we have one free end of the ruler and we are clicking to set it
        if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::LeftButton) {
            RulerTool* r = rulers[currentId].get();
            r->updateFloatingIndex(index);
            this->state = RulerToolState::standing;
        }
        // actively moving the free end
        else if (event->type() == QEvent::MouseMove) {
            RulerTool* r = rulers[currentId].get();
            r->updateFloatingIndex(index);
        }
        else if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::RightButton) { // delete and go back to standing
            metaDataFactory->refund(std::move(rulers[currentId]->metaData));
            rulers.erase(rulers.begin() + currentId);
            currentId = rulers.size() > 0 ? 0 : -1;
            this->state = RulerToolState::standing;
        }
        break;
    }

}

void RulerToolCollection::setMetaDataFactory(std::shared_ptr< RulerToolMetaDataFactory > factory) {
    metaDataFactory = factory;
}

void RulerToolCollection::paint() {
    for (auto &r : this->rulers) {
        r->paint();
    }
}

int RulerToolCollection::isOver(double index[]) {
    for (int i=0; i < rulers.size(); ++i) {
        auto r = rulers[i].get();
        int x = r->isOver(index);
        if (x >= 0) {
            return i; // return the index of the ruler (different than RulerTool::isOver() which returns the index of the ruler point covered)
        }
    }
    return -1;
}

RulerTool* RulerToolCollection::getActive() {
    return currentId >= 0 ? rulers[currentId].get() : nullptr;
}

std::string RulerToolCollection::toJson() {
    std::string ans = "{ \"axis\" : " + std::to_string(axis) + ", \"slice\" : " + std::to_string(slice) + ", \"rulers\" : [";
    if (rulers.size() > 0) {
        ans += rulers[0]->toJson();
    }
    for (auto iter = rulers.begin() + 1; iter != rulers.end(); ++iter) {
        ans += "," + (*iter)->toJson();
    }
    ans += "]}";
    return ans;
}<commit_msg>Fix RulerTool constructor<commit_after>#include "RulerWidget.h"
#include "QtGlSliceView.h"
#include <Qt>
#include <QtOpenGL/qgl.h>
#include <QMouseEvent>
#include <QGuiApplication>
#include <cmath>
#include "itkMath.h"

bool operator< (std::unique_ptr< RulerToolMetaData > const& lhs, std::unique_ptr< RulerToolMetaData > const& rhs) {
    return lhs->sortId < rhs->sortId;
}

RainbowMetaDataGenerator::RainbowMetaDataGenerator() {
    curColor = colors.begin();
}

std::unique_ptr< RulerToolMetaData > RainbowMetaDataGenerator::operator()(void) {
    std::string name = std::to_string(curId);
    QColor color = QColor(QString(curColor->c_str()));
    int id = curId;

    // wrap around to the beginning of the color list if at end
    ++curColor;
    if (curColor == colors.end()) {
        curColor = colors.begin();
    }

    ++curId;
    return std::unique_ptr< RulerToolMetaData >(new RulerToolMetaData{ id, name, color });
}

std::unique_ptr< RulerToolMetaData > ONSDMetaDataGenerator::operator()(void) {
    std::string name = flipper ? "R1" : "ONSD";
    QColor color = QColor(colors[(int)flipper].c_str());
    int id = curId;

    flipper = !flipper;
    ++curId;

    return std::unique_ptr< RulerToolMetaData >(new RulerToolMetaData{ id, name, color });
}

RulerToolMetaDataFactory::RulerToolMetaDataFactory(std::unique_ptr< MetaDataGenerator > generator) : generator{ std::move(generator) } { }

std::unique_ptr< RulerToolMetaData > RulerToolMetaDataFactory::getNext() {
    std::unique_ptr< RulerToolMetaData > ans;
    if (refunds.size() > 0) {
        ans = std::move(*(refunds.begin()));
        refunds.erase(refunds.begin());
    }
    else {
        ans = (*generator)();
    }
    return ans;
}

void RulerToolMetaDataFactory::refund(std::unique_ptr< RulerToolMetaData > ruler_meta) {
    refunds.push_back(std::move(ruler_meta));
    std::sort(refunds.begin(), refunds.end());
}

RulerTool::RulerTool(QtGlSliceView* parent0, PointType3D index0, std::unique_ptr< RulerToolMetaData > metaData) :
    parent{ parent0 }, indices{ index0, index0 }, points{ parent0->indexToPhysicalPoint(index0), parent0->indexToPhysicalPoint(index0) }, metaData{ std::move(metaData) }, clickRadius{ 10.0 }, state{ RulerToolState::drawing }, floatingIndex{ 1 }, crossStart{ 18 }, crossEnd{ 3 }, lineWidth{ 4 }
{

}

RulerTool::~RulerTool() {}

int RulerTool::isOver(double index[]) const {
    int ans = -1;
    auto screenPt = parent->indexToScreenPoint(PointType3D(index));
    if (screenPt.EuclideanDistanceTo(parent->indexToScreenPoint(indices[0])) < clickRadius) {
        ans = 0;
    }
    else if (screenPt.EuclideanDistanceTo(parent->indexToScreenPoint(indices[1])) < clickRadius) {
        ans = 1;
    }
    return ans;
}

void RulerTool::updateFloatingIndex(double index[]) {
    this->indices[this->floatingIndex] = PointType3D(index);
    this->points[this->floatingIndex] = this->parent->indexToPhysicalPoint(index);
}

void RulerTool::setFloatingIndex(int id) {
    this->floatingIndex = id;
}

int RulerTool::getFloatingIndex() const {
    return this->floatingIndex;
}

double RulerTool::length() {
    return this->points[0].EuclideanDistanceTo(this->points[1]);
}

void RulerTool::paint() {

    QPainter painter(this->parent);
    QPen pen;

    // could optimize this by memoization and catching parent stage changes
    PointType2D screen0 = parent->indexToScreenPoint(indices[0]);
    PointType2D screen1 = parent->indexToScreenPoint(indices[1]);

    QColor color = metaData->color;
    color.setAlphaF(0.7);
    pen.setWidth(lineWidth);
    pen.setColor(color);
    painter.setPen(pen);

    // TODO make line dotted

    // crosshair1
    painter.drawLine(QLine(screen0[0] - crossStart, screen0[1] - crossStart, screen0[0] - crossEnd, screen0[1] - crossEnd));
    painter.drawLine(QLine(screen0[0] + crossStart, screen0[1] + crossStart, screen0[0] + crossEnd, screen0[1] + crossEnd));
    painter.drawLine(QLine(screen0[0] - crossStart, screen0[1] + crossStart, screen0[0] - crossEnd, screen0[1] + crossEnd));
    painter.drawLine(QLine(screen0[0] + crossStart, screen0[1] - crossStart, screen0[0] + crossEnd, screen0[1] - crossEnd));

    // crosshair2
    painter.drawLine(QLine(screen1[0] - crossStart, screen1[1] - crossStart, screen1[0] - crossEnd, screen1[1] - crossEnd));
    painter.drawLine(QLine(screen1[0] + crossStart, screen1[1] + crossStart, screen1[0] + crossEnd, screen1[1] + crossEnd));
    painter.drawLine(QLine(screen1[0] - crossStart, screen1[1] + crossStart, screen1[0] - crossEnd, screen1[1] + crossEnd));
    painter.drawLine(QLine(screen1[0] + crossStart, screen1[1] - crossStart, screen1[0] + crossEnd, screen1[1] - crossEnd));

    QPen pen2;
    pen2.setWidth(lineWidth);
    pen2.setColor(color);
    pen2.setStyle(Qt::DashDotLine);
    painter.setPen(pen2);

    //line
    painter.drawLine(QLine(screen0[0], screen0[1], screen1[0], screen1[1]));

}

std::string RulerTool::toJson() {
    char txt[256];

    int n = snprintf(txt, sizeof(txt),
        "{ \"name\" : \"%s\", \"indices\" : [ [%.4f, %.4f, %.4f], [%.4f, %.4f, %.4f] ], \"points\" : [ [%.4f, %.4f, %.4f], [%.4f, %.4f, %.4f] ], \"distance\" : %.4f}",
        metaData->name.c_str(),
        indices[0].GetElement(0),
        indices[0].GetElement(1),
        indices[0].GetElement(2),
        indices[1].GetElement(0),
        indices[1].GetElement(1),
        indices[1].GetElement(2),
        points[0].GetElement(0),
        points[0].GetElement(1),
        points[0].GetElement(2),
        points[1].GetElement(0),
        points[1].GetElement(1),
        points[1].GetElement(2),
        points[0].EuclideanDistanceTo(points[1]));

    if (n >= sizeof(txt)) {
        throw "RulerTool::toJson tried to write too big of string";
    }
    return std::string(txt);
}

RulerToolCollection::RulerToolCollection(QtGlSliceView* parent, std::shared_ptr< RulerToolMetaDataFactory > metaDataFactory, unsigned short axis, unsigned int slice)
    : parent{ parent }, metaDataFactory{ metaDataFactory }, axis{ axis }, slice{ slice }, currentId { -1 }, state { RulerToolState::standing }
{

}

RulerToolCollection::~RulerToolCollection() {}

void RulerToolCollection::handleMouseEvent(QMouseEvent* event, double index[]) {

    int over = -1;
    switch (this->state) {
    case RulerToolState::standing:
        over = isOver(index);
        if (over >= 0) {
            if (QGuiApplication::overrideCursor() == nullptr) {
                QGuiApplication::setOverrideCursor(Qt::OpenHandCursor);
            }
            if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::RightButton) { // we're over a ruler and have right-clicked to move the crosshair
                this->currentId = over;
                RulerTool* r = rulers[currentId].get();
                r->setFloatingIndex(r->isOver(index));
                this->state = RulerToolState::drawing;
                r->paint();
            }
        }
        else {
            QGuiApplication::restoreOverrideCursor();
        }

        // we're idle and we're clicking to create a new ruler
        if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::LeftButton) {
            // blank click on screen, make a ruler

            std::unique_ptr< RulerTool > r(new RulerTool(this->parent, RulerTool::PointType3D(index), metaDataFactory->getNext()));
            this->rulers.push_back(std::move(r));
            this->currentId = this->rulers.size() - 1;
            this->state = RulerToolState::drawing;
            this->paint();
        }
        break;
    case RulerToolState::drawing:
        if (QGuiApplication::overrideCursor() != nullptr) {
            QGuiApplication::restoreOverrideCursor(); // if we are drawing go back to a normal cursor, even if we're over a ruler
        }
        // we have one free end of the ruler and we are clicking to set it
        if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::LeftButton) {
            RulerTool* r = rulers[currentId].get();
            r->updateFloatingIndex(index);
            this->state = RulerToolState::standing;
        }
        // actively moving the free end
        else if (event->type() == QEvent::MouseMove) {
            RulerTool* r = rulers[currentId].get();
            r->updateFloatingIndex(index);
        }
        else if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::RightButton) { // delete and go back to standing
            metaDataFactory->refund(std::move(rulers[currentId]->metaData));
            rulers.erase(rulers.begin() + currentId);
            currentId = rulers.size() > 0 ? 0 : -1;
            this->state = RulerToolState::standing;
        }
        break;
    }

}

void RulerToolCollection::setMetaDataFactory(std::shared_ptr< RulerToolMetaDataFactory > factory) {
    metaDataFactory = factory;
}

void RulerToolCollection::paint() {
    for (auto &r : this->rulers) {
        r->paint();
    }
}

int RulerToolCollection::isOver(double index[]) {
    for (int i=0; i < rulers.size(); ++i) {
        auto r = rulers[i].get();
        int x = r->isOver(index);
        if (x >= 0) {
            return i; // return the index of the ruler (different than RulerTool::isOver() which returns the index of the ruler point covered)
        }
    }
    return -1;
}

RulerTool* RulerToolCollection::getActive() {
    return currentId >= 0 ? rulers[currentId].get() : nullptr;
}

std::string RulerToolCollection::toJson() {
    std::string ans = "{ \"axis\" : " + std::to_string(axis) + ", \"slice\" : " + std::to_string(slice) + ", \"rulers\" : [";
    if (rulers.size() > 0) {
        ans += rulers[0]->toJson();
    }
    for (auto iter = rulers.begin() + 1; iter != rulers.end(); ++iter) {
        ans += "," + (*iter)->toJson();
    }
    ans += "]}";
    return ans;
}
<|endoftext|>


<commit_before>/*
 * By: ulises-jeremias
 * From: https://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=417
 * Name: Points in Figures: Rectangles
 * Date: 20/11/2017
 */

#include <iostream>
#include <utility>
#include <vector>
#include <algorithm>
#include <cmath>

#define EPS 1e-9
#define INF 1 << 30

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;

struct point_i
{
        int x, y;

        point_i () {
                x = y = 0;
        }

        point_i (int _x, int _y) : x(_x), y(_y) {
        };
};

struct point
{
        double x, y;

        point () {
                x = y = 0.0;
        }

        point (double _x, double _y) : x(_x), y(_y) {
        };
};

struct shape
{
        vector<point> points;
        double radius;
        int sh;

        shape(point upper_left, point lower_right)
        {
                sh = 1;

                points.push_back(point(upper_left.x, upper_left.y));
                points.push_back(point(upper_left.x, lower_right.y));
                points.push_back(point(lower_right.x, lower_right.y));
                points.push_back(point(lower_right.x, upper_left.y));
                points.push_back(point(upper_left.x, upper_left.y));
        }

        shape(point center, double radius)
        {
                sh = 2;

                points.push_back(center);
                this->radius = radius;
        }
};

int n, np;
char op;
double radius;
point upper_left, lower_right, center, p;
vector<shape> shapes;

double dist_point (const point &a, const point &b) {
        return hypot(a.x-b.x, a.y-b.y);
}

point to_vec(const point &a, const point &b)
{
        return point(a.x - b.x, a.y - b.y);
}

double cross(point a, point b)
{
        return (double) ((a.x * b.y) - (b.x * a.y));
}

bool ccw(point a, point b, point p)
{
        return cross(to_vec(a, p), to_vec(b, p)) > 0.0;
}

bool is_inside_box(int idx)
{
        shape rectangle = shapes[idx];

        for (int i = 0; i < 4; i++) {
                if (!ccw(rectangle.points[i], rectangle.points[i + 1], p)) {
                        return false;
                }
        }

        return true;
}

bool is_inside_circle(int idx)
{
        return (dist_point(shapes[idx].points[0], p) < shapes[idx].radius);
}

bool is_inside(int idx)
{
        if (shapes[idx].sh == 1) {
                return is_inside_box(idx);
        } else {
                return is_inside_circle(idx);
        }
}

int main(int argc, char const *argv[]) {
        /*#ifndef ONLINE_JUDGE
         #define ONLINE_JUDGE
           ios_base::sync_with_stdio(false);
           cin.tie(NULL);
         #endif*/

        int i;

        n = 0;
        while (scanf(" %c", &op), op != '*') {
                if (op == 'r') {
                        scanf("%lf %lf", &upper_left.x, &upper_left.y);
                        scanf("%lf %lf", &lower_right.x, &lower_right.y);

                        shapes.push_back(shape(upper_left, lower_right));
                } else {
                        scanf("%lf %lf", &center.x, &center.y);
                        scanf("%lf", &radius);

                        shapes.push_back(shape(center, radius));
                }

                n++;
        }

        np = 1;
        while (scanf("%lf %lf", &p.x, &p.y), !((fabs(p.x - 9999.9) < EPS) && (fabs(p.y - 9999.9) < EPS))) {

                bool any = false;
                for (i = 0; i < n; i++) {
                        if (is_inside(i)) {
                                printf("Point %d is contained in figure %d\n", np, i + 1);
                                any = true;
                        }
                }

                if (!any) {
                        printf("Point %d is not contained in any figure\n", np);
                }

                np++;
        }

        return 0;
}
<commit_msg>Solved<commit_after>/*
 * By: ulises-jeremias
 * From: https://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=417
 * Name: Points in Figures: Rectangles
 * Date: 20/11/2017
 */

#include <iostream>
#include <utility>
#include <vector>
#include <algorithm>
#include <cmath>

#define EPS 1e-9
#define INF 1 << 30

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;

struct point_i
{
        int x, y;

        point_i () {
                x = y = 0;
        }

        point_i (int _x, int _y) : x(_x), y(_y) {
        };
};

struct point
{
        double x, y;

        point () {
                x = y = 0.0;
        }

        point (double _x, double _y) : x(_x), y(_y) {
        };
};

struct shape
{
        vector<point> points;
        double radius;
        int sh;

        shape(point upper_left, point lower_right)
        {
                sh = 1;

                points.push_back(point(upper_left.x, upper_left.y));
                points.push_back(point(upper_left.x, lower_right.y));
                points.push_back(point(lower_right.x, lower_right.y));
                points.push_back(point(lower_right.x, upper_left.y));
                points.push_back(point(upper_left.x, upper_left.y));
        }

        shape(point center, double radius)
        {
                sh = 2;

                points.push_back(center);
                this->radius = radius;
        }
};

int n, np;
char op;
double radius;
point upper_left, lower_right, center, p;
vector<shape> shapes;

double dist_point (const point &a, const point &b) {
        return hypot(a.x-b.x, a.y-b.y);
}

point to_vec(const point &a, const point &b)
{
        return point(a.x - b.x, a.y - b.y);
}

double cross(point a, point b)
{
        return (double) ((a.x * b.y) - (b.x * a.y));
}

bool ccw(point a, point b, point p)
{
        return cross(to_vec(a, p), to_vec(b, p)) > 0.0;
}

bool is_inside_box(int idx)
{
        shape rectangle = shapes[idx];

        for (int i = 0; i < 4; i++) {
                if (!ccw(rectangle.points[i], rectangle.points[i + 1], p)) {
                        return false;
                }
        }

        return true;
}

bool is_inside_circle(int idx)
{
        return (dist_point(shapes[idx].points[0], p) < shapes[idx].radius);
}

bool is_inside(int idx)
{
        if (shapes[idx].sh == 1) {
                return is_inside_box(idx);
        } else {
                return is_inside_circle(idx);
        }
}

int main(int argc, char const *argv[]) {
        #ifndef ONLINE_JUDGE
        #define ONLINE_JUDGE
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        #endif

        int i;

        n = 0;
        while (scanf(" %c", &op), op != '*') {
                if (op == 'r') {
                        scanf("%lf %lf", &upper_left.x, &upper_left.y);
                        scanf("%lf %lf", &lower_right.x, &lower_right.y);

                        shapes.push_back(shape(upper_left, lower_right));
                } else {
                        scanf("%lf %lf", &center.x, &center.y);
                        scanf("%lf", &radius);

                        shapes.push_back(shape(center, radius));
                }

                n++;
        }

        np = 1;
        while (scanf("%lf %lf", &p.x, &p.y), !((fabs(p.x - 9999.9) < EPS) && (fabs(p.y - 9999.9) < EPS))) {

                bool any = false;
                for (i = 0; i < n; i++) {
                        if (is_inside(i)) {
                                printf("Point %d is contained in figure %d\n", np, i + 1);
                                any = true;
                        }
                }

                if (!any) {
                        printf("Point %d is not contained in any figure\n", np);
                }

                np++;
        }

        return 0;
}
<|endoftext|>


<commit_before>#include "stan/math/functions/fdim.hpp"
#include <gtest/gtest.h>

TEST(MathFunctions, fdim_double) {
  using stan::math::fdim;

  EXPECT_FLOAT_EQ(1.0, fdim(3.0,2.0));
  EXPECT_FLOAT_EQ(0.0, fdim(2.0,3.0));

  EXPECT_FLOAT_EQ(2.5, fdim(4.5,2.0));
}

TEST(MathFunctions, fdim_int) {
  using stan::math::fdim;

  // promotes results to double
  EXPECT_FLOAT_EQ(1.0, fdim(int(3),int(2)));
  EXPECT_FLOAT_EQ(0.0, fdim(int(2),int(3)));
}
<commit_msg>adding failing fdim test<commit_after>#include <stan/math/functions/fdim.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <gtest/gtest.h>

TEST(MathFunctions, fdim_double) {
  using stan::math::fdim;

  EXPECT_FLOAT_EQ(1.0, fdim(3.0,2.0));
  EXPECT_FLOAT_EQ(0.0, fdim(2.0,3.0));

  EXPECT_FLOAT_EQ(2.5, fdim(4.5,2.0));
}

TEST(MathFunctions, fdim_int) {
  using stan::math::fdim;

  // promotes results to double
  EXPECT_FLOAT_EQ(1.0, fdim(int(3),int(2)));
  EXPECT_FLOAT_EQ(0.0, fdim(int(2),int(3)));
}

TEST(MathFunctions, fdim_nan) {
  double nan = std::numeric_limits<double>::quiet_NaN();

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fdim(3.0, nan));

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fdim(nan, 3.0));

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::fdim(nan, nan));
}
<|endoftext|>


<commit_before>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <string>

#include "TiStore/TiFS.h"
#include "TiStore/TiStore.h"
#include "TiStore/fs/Initor.h"
#include "TiStore/traits.h"
#include "TiStore/kv/BloomFilter.h"
#include "TiStore/kv/SkipList.h"
#include "TiStore/lang/TypeInfo.h"

#include "stop_watch.h"
#include "test.h"

using namespace TiStore;

static const int kVerbose = 1;
static const int kIterators = 10000000;

#define TEST_VERIFY_BOOL(value, format, var) \
    printf(format, var, bool_to_string(!!(value)).c_str());

static inline std::string bool_to_string(bool value)
{
    if (value)
        return "true";
    else
        return "false";
}

void test_bloomfilter_hash_impl(const char key[])
{
    StopWatch sw;
    /**/ volatile /**/ uint32_t hash;
    StandardBloomFilter sbf(8192, 10);
    Slice skey(key);
    printf("key = %s\n\n", skey.toString().c_str());

    hash = 0;
    sw.start();
    for (int i = 0; i < kIterators; ++i) {
        hash += sbf.maybe_match(skey);
    }
    sw.stop();
    printf("sbf.maybe_match()         time spent: %8.3f ms, hash: 0x%08X\n", sw.getElapsedMillisec(), hash);

    hash = 0;
    sw.start();
    for (int i = 0; i < kIterators; ++i) {
        hash += sbf.rocksdb_maybe_match(skey);
    }
    sw.stop();
    printf("sbf.rocksdb_maybe_match() time spent: %8.3f ms, hash: 0x%08X\n", sw.getElapsedMillisec(), hash);

    hash = 0;
    sw.start();
    for (int i = 0; i < kIterators; ++i) {
        hash += sbf.maybe_match2(skey);
    }
    sw.stop();
    printf("sbf.maybe_match2()        time spent: %8.3f ms, hash: 0x%08X\n", sw.getElapsedMillisec(), hash);

    hash = 0;
    sw.start();
    for (int i = 0; i < kIterators; ++i) {
        hash += sbf.maybe_match_openssl(skey);
    }
    sw.stop();
    printf("sbf.maybe_match_openssl() time spent: %8.3f ms, hash: 0x%08X\n\n", sw.getElapsedMillisec(), hash);
}

void test_bloomfilter_hash()
{
    test_bloomfilter_hash_impl("This is a hash test.");
    test_bloomfilter_hash_impl("This is a hash test...");
}

void test_bloomfilter_impl()
{
    StandardBloomFilter sbf(8192, 10);
    bool isMatch;

    Slice skey("abc");
    sbf.setVerbose(true);

    sbf.addKey(skey);
    sbf.addKey("skyinno");
    sbf.addKey("bigdata");
    printf("\n");

    isMatch = sbf.maybeMatch(skey);
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", skey.data());

    isMatch = sbf.maybeMatch("skyinno");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "skyinno");

    isMatch = sbf.maybeMatch("bigdata");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "bigdata");
    printf("\n");

    isMatch = sbf.maybeMatch("ambari");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "ambari");

    isMatch = sbf.maybeMatch("Karazhan");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "Karazhan");

    isMatch = sbf.maybeMatch("pokemon go");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "pokemon go");

    printf("\n");
}

static Slice MemIntegerKey(int i, char * buffer) {
    ::memcpy(buffer, &i, sizeof(i));
    return Slice(buffer, sizeof(i));
}

static int NextLength(int length) {
    if (length < 10) {
        length += 1;
    }
    else if (length < 100) {
        length += 10;
    }
    else if (length < 1000) {
        length += 100;
    }
    else if (length < 10000) {
        length += 1000;
    }
    else {
        length += 5000;
    }
    return length;
}

template <typename T>
double getFalsePositiveRate(T const & bloom_filter, int length) {
    char buffer[sizeof(int)];
    int result = 0;
    //int max_length = (length <= 10000) ? 10000 : length;
    int max_length = length;
    for (int i = 0; i < 10000; ++i) {
        if (bloom_filter.maybeMatch(MemIntegerKey(i + 1000000000, buffer))) {
            result++;
        }
    }
    return (double)result / 10000.0;
}

void test_bloomfilter_standard_false_positive_rate()
{
    char buffer[sizeof(int)];

    // Count number of filters that significantly exceed the false positive rate
    int mediocre_filters = 0;
    int good_filters = 0;
    bool isMatch;

    std::cout << "----------------------------------" << std::endl;
    std::cout << "StandardBloomFilter Test" << std::endl;
    std::cout << "----------------------------------" << std::endl;
    std::cout << std::endl;

    StandardBloomFilter bloomfilter(10000, 14, true);

    for (int length = 1; length <= 10000; length = NextLength(length)) {
        bloomfilter.setOption(length, 14, false);
        bloomfilter.reset();
        for (int i = 0; i < length; i++) {
            bloomfilter.addKey(MemIntegerKey(i, buffer));
        }

        // All added keys must match
        for (int i = 0; i < length; ++i) {
            isMatch = bloomfilter.maybeMatch(MemIntegerKey(i, buffer));
            if (!isMatch) {
                std::cout << "[Not Match], Length = " << length << "; key = " << i << std::endl;
            }
        }

        // Check false positive rate
        double rate = getFalsePositiveRate(bloomfilter, length);
        if (kVerbose >= 1) {
            fprintf(stderr, "False positive rates: %5.2f%% @ length = %6d ; bytes = %6d ; used_bits = %d\n",
                rate * 100.0, length, (int)bloomfilter.getFilterSize(), (int)bloomfilter.getUsedBits());
        }
        if (rate > 0.0125)
            mediocre_filters++;  // Allowed, but not too often
        else
            good_filters++;
    }
    if (kVerbose >= 1) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Filters: %d good, %d mediocre\n",
            good_filters, mediocre_filters);
    }
    //TEST_ASSERT_LE(mediocre_filters, good_filters / 5);

    fprintf(stderr, "\n");
}

void test_bloomfilter_full_false_positive_rate()
{
    char buffer[sizeof(int)];

    // Count number of filters that significantly exceed the false positive rate
    int mediocre_filters = 0;
    int good_filters = 0;
    bool isMatch;

    std::cout << "----------------------------------" << std::endl;
    std::cout << "FullBloomFilter Test" << std::endl;
    std::cout << "----------------------------------" << std::endl;
    std::cout << std::endl;

    FullBloomFilter bloomfilter(10000, 10, true);

    for (int length = 1; length <= 10000; length = NextLength(length)) {
        bloomfilter.setOption(length, 10, false);
        bloomfilter.reset();
        for (int i = 0; i < length; i++) {
            bloomfilter.addKey(MemIntegerKey(i, buffer));
        }

        // All added keys must match
        for (int i = 0; i < length; ++i) {
            isMatch = bloomfilter.maybeMatch(MemIntegerKey(i, buffer));
            if (!isMatch) {
                std::cout << "[Not Match], Length = " << length << "; key = " << i << std::endl;
            }
        }

        // Check false positive rate
        double rate = getFalsePositiveRate(bloomfilter, length);
        if (kVerbose >= 1) {
            fprintf(stderr, "False positive rates: %5.2f%% @ length = %6d ; bytes = %6d ; used_bits = %d\n",
                rate * 100.0, length, (int)bloomfilter.getFilterSize(), (int)bloomfilter.getUsedBits());
        }
        if (rate > 0.0125)
            mediocre_filters++;  // Allowed, but not too often
        else
            good_filters++;
    }
    if (kVerbose >= 1) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Filters: %d good, %d mediocre\n",
            good_filters, mediocre_filters);
    }
    //TEST_ASSERT_LE(mediocre_filters, good_filters / 5);

    fprintf(stderr, "\n");
}

void test_bloomfilter()
{
    test_bloomfilter_impl();
    test_bloomfilter_hash();

    stop_watch sw;
    sw.start();
    test_bloomfilter_standard_false_positive_rate();
    sw.stop();

    printf("time spent: %0.3f ms.\n\n", sw.getElapsedMillisec());

    sw.start();
    test_bloomfilter_full_false_positive_rate();
    sw.stop();

    printf("time spent: %0.3f ms.\n\n", sw.getElapsedMillisec());
}

int main(int argc, char * argv[])
{
    printf("\n");

    TiStore::fs::Initor initor;

    TiStore::fs::File file;
    file.open("C:\\test.bin");
    if (file.is_open()) {
        file.close();
    }

    TiStore::fs::File file1("C:\\test.bin");
    file1.close();

    test_skiplist();
    test_property();
    //test_traist();
    test_stl_iterator();

    //test_bloomfilter();
    //test_typeinfo_module();

    //printf("\n");

#ifdef _WIN32
    ::system("pause");
#endif
    return 0;
}
<commit_msg>打开一些单元测试<commit_after>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <string>

#include "TiStore/TiFS.h"
#include "TiStore/TiStore.h"
#include "TiStore/fs/Initor.h"
#include "TiStore/traits.h"
#include "TiStore/kv/BloomFilter.h"
#include "TiStore/kv/SkipList.h"
#include "TiStore/lang/TypeInfo.h"

#include "stop_watch.h"
#include "test.h"

using namespace TiStore;

static const int kVerbose = 1;
static const int kIterators = 10000000;

#define TEST_VERIFY_BOOL(value, format, var) \
    printf(format, var, bool_to_string(!!(value)).c_str());

static inline std::string bool_to_string(bool value)
{
    if (value)
        return "true";
    else
        return "false";
}

void test_bloomfilter_hash_impl(const char key[])
{
    StopWatch sw;
    /**/ volatile /**/ uint32_t hash;
    StandardBloomFilter sbf(8192, 10);
    Slice skey(key);
    printf("key = %s\n\n", skey.toString().c_str());

    hash = 0;
    sw.start();
    for (int i = 0; i < kIterators; ++i) {
        hash += sbf.maybe_match(skey);
    }
    sw.stop();
    printf("sbf.maybe_match()         time spent: %8.3f ms, hash: 0x%08X\n", sw.getElapsedMillisec(), hash);

    hash = 0;
    sw.start();
    for (int i = 0; i < kIterators; ++i) {
        hash += sbf.rocksdb_maybe_match(skey);
    }
    sw.stop();
    printf("sbf.rocksdb_maybe_match() time spent: %8.3f ms, hash: 0x%08X\n", sw.getElapsedMillisec(), hash);

    hash = 0;
    sw.start();
    for (int i = 0; i < kIterators; ++i) {
        hash += sbf.maybe_match2(skey);
    }
    sw.stop();
    printf("sbf.maybe_match2()        time spent: %8.3f ms, hash: 0x%08X\n", sw.getElapsedMillisec(), hash);

    hash = 0;
    sw.start();
    for (int i = 0; i < kIterators; ++i) {
        hash += sbf.maybe_match_openssl(skey);
    }
    sw.stop();
    printf("sbf.maybe_match_openssl() time spent: %8.3f ms, hash: 0x%08X\n\n", sw.getElapsedMillisec(), hash);
}

void test_bloomfilter_hash()
{
    test_bloomfilter_hash_impl("This is a hash test.");
    test_bloomfilter_hash_impl("This is a hash test...");
}

void test_bloomfilter_impl()
{
    StandardBloomFilter sbf(8192, 10);
    bool isMatch;

    Slice skey("abc");
    sbf.setVerbose(true);

    sbf.addKey(skey);
    sbf.addKey("skyinno");
    sbf.addKey("bigdata");
    printf("\n");

    isMatch = sbf.maybeMatch(skey);
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", skey.data());

    isMatch = sbf.maybeMatch("skyinno");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "skyinno");

    isMatch = sbf.maybeMatch("bigdata");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "bigdata");
    printf("\n");

    isMatch = sbf.maybeMatch("ambari");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "ambari");

    isMatch = sbf.maybeMatch("Karazhan");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "Karazhan");

    isMatch = sbf.maybeMatch("pokemon go");
    TEST_VERIFY_BOOL(isMatch, "maybeMatch(\"%s\"): %s\n", "pokemon go");

    printf("\n");
}

static Slice MemIntegerKey(int i, char * buffer) {
    ::memcpy(buffer, &i, sizeof(i));
    return Slice(buffer, sizeof(i));
}

static int NextLength(int length) {
    if (length < 10) {
        length += 1;
    }
    else if (length < 100) {
        length += 10;
    }
    else if (length < 1000) {
        length += 100;
    }
    else if (length < 10000) {
        length += 1000;
    }
    else {
        length += 5000;
    }
    return length;
}

template <typename T>
double getFalsePositiveRate(T const & bloom_filter, int length) {
    char buffer[sizeof(int)];
    int result = 0;
    //int max_length = (length <= 10000) ? 10000 : length;
    int max_length = length;
    for (int i = 0; i < 10000; ++i) {
        if (bloom_filter.maybeMatch(MemIntegerKey(i + 1000000000, buffer))) {
            result++;
        }
    }
    return (double)result / 10000.0;
}

void test_bloomfilter_standard_false_positive_rate()
{
    char buffer[sizeof(int)];

    // Count number of filters that significantly exceed the false positive rate
    int mediocre_filters = 0;
    int good_filters = 0;
    bool isMatch;

    std::cout << "----------------------------------" << std::endl;
    std::cout << "StandardBloomFilter Test" << std::endl;
    std::cout << "----------------------------------" << std::endl;
    std::cout << std::endl;

    StandardBloomFilter bloomfilter(10000, 14, true);

    for (int length = 1; length <= 10000; length = NextLength(length)) {
        bloomfilter.setOption(length, 14, false);
        bloomfilter.reset();
        for (int i = 0; i < length; i++) {
            bloomfilter.addKey(MemIntegerKey(i, buffer));
        }

        // All added keys must match
        for (int i = 0; i < length; ++i) {
            isMatch = bloomfilter.maybeMatch(MemIntegerKey(i, buffer));
            if (!isMatch) {
                std::cout << "[Not Match], Length = " << length << "; key = " << i << std::endl;
            }
        }

        // Check false positive rate
        double rate = getFalsePositiveRate(bloomfilter, length);
        if (kVerbose >= 1) {
            fprintf(stderr, "False positive rates: %5.2f%% @ length = %6d ; bytes = %6d ; used_bits = %d\n",
                rate * 100.0, length, (int)bloomfilter.getFilterSize(), (int)bloomfilter.getUsedBits());
        }
        if (rate > 0.0125)
            mediocre_filters++;  // Allowed, but not too often
        else
            good_filters++;
    }
    if (kVerbose >= 1) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Filters: %d good, %d mediocre\n",
            good_filters, mediocre_filters);
    }
    //TEST_ASSERT_LE(mediocre_filters, good_filters / 5);

    fprintf(stderr, "\n");
}

void test_bloomfilter_full_false_positive_rate()
{
    char buffer[sizeof(int)];

    // Count number of filters that significantly exceed the false positive rate
    int mediocre_filters = 0;
    int good_filters = 0;
    bool isMatch;

    std::cout << "----------------------------------" << std::endl;
    std::cout << "FullBloomFilter Test" << std::endl;
    std::cout << "----------------------------------" << std::endl;
    std::cout << std::endl;

    FullBloomFilter bloomfilter(10000, 10, true);

    for (int length = 1; length <= 10000; length = NextLength(length)) {
        bloomfilter.setOption(length, 10, false);
        bloomfilter.reset();
        for (int i = 0; i < length; i++) {
            bloomfilter.addKey(MemIntegerKey(i, buffer));
        }

        // All added keys must match
        for (int i = 0; i < length; ++i) {
            isMatch = bloomfilter.maybeMatch(MemIntegerKey(i, buffer));
            if (!isMatch) {
                std::cout << "[Not Match], Length = " << length << "; key = " << i << std::endl;
            }
        }

        // Check false positive rate
        double rate = getFalsePositiveRate(bloomfilter, length);
        if (kVerbose >= 1) {
            fprintf(stderr, "False positive rates: %5.2f%% @ length = %6d ; bytes = %6d ; used_bits = %d\n",
                rate * 100.0, length, (int)bloomfilter.getFilterSize(), (int)bloomfilter.getUsedBits());
        }
        if (rate > 0.0125)
            mediocre_filters++;  // Allowed, but not too often
        else
            good_filters++;
    }
    if (kVerbose >= 1) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Filters: %d good, %d mediocre\n",
            good_filters, mediocre_filters);
    }
    //TEST_ASSERT_LE(mediocre_filters, good_filters / 5);

    fprintf(stderr, "\n");
}

void test_bloomfilter()
{
    test_bloomfilter_impl();
    test_bloomfilter_hash();

    stop_watch sw;
    sw.start();
    test_bloomfilter_standard_false_positive_rate();
    sw.stop();

    printf("time spent: %0.3f ms.\n\n", sw.getElapsedMillisec());

    sw.start();
    test_bloomfilter_full_false_positive_rate();
    sw.stop();

    printf("time spent: %0.3f ms.\n\n", sw.getElapsedMillisec());
}

int main(int argc, char * argv[])
{
    printf("\n");

    TiStore::fs::Initor initor;

    TiStore::fs::File file;
    file.open("C:\\test.bin");
    if (file.is_open()) {
        file.close();
    }

    TiStore::fs::File file1("C:\\test.bin");
    file1.close();

    test_skiplist();
    test_property();
    test_traist();
    test_stl_iterator();

    test_bloomfilter();
    test_typeinfo_module();

    //printf("\n");

#ifdef _WIN32
    ::system("pause");
#endif
    return 0;
}
<|endoftext|>