<commit_before>#pragma once

#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>
#include <optional>

#include "acmacs-base/string.hh"
#include "acmacs-base/fmt.hh"

// ----------------------------------------------------------------------

namespace acmacs
{
    namespace argv
    {
        inline namespace v2
        {
            class argv;
            using str = std::string_view;
            using str_array = std::vector<std::string_view>;

            struct desc : public std::string_view { using std::string_view::string_view; };
            struct arg_name : public std::string_view { using std::string_view::string_view; };
            enum mandatory { mandatory };
            template <typename T> struct dflt { dflt(T&& val) : value{std::move(val)} {} T value; explicit operator T() const { return value; } };
            dflt(const char*) -> dflt<str>;

            namespace detail
            {
                using cmd_line_iter = std::vector<const char*>::const_iterator;

                constexpr bool false_ = false;

                class option_base
                {
                  public:
                    option_base(argv& parent);
                    virtual ~option_base() = default;

                    virtual void add(cmd_line_iter& arg, cmd_line_iter last) = 0;
                    virtual void add(std::string_view arg) = 0;
                    std::string names() const noexcept;
                    constexpr bool has_name() const noexcept { return short_name_ || !long_name_.empty(); }
                    constexpr std::string_view description() const noexcept { return description_; }
                    virtual std::string get_default() const noexcept = 0;
                    virtual bool has_arg() const noexcept { return true; }
                    virtual bool has_value() const noexcept = 0;
                    virtual bool multiple_values() const noexcept = 0;
                    virtual bool is_bool() const noexcept = 0;
                    constexpr bool mandatory() const noexcept { return mandatory_; }

                    constexpr char short_name() const noexcept { return short_name_; }
                    constexpr std::string_view long_name() const noexcept { return long_name_; }
                    constexpr std::string_view arg_name() const noexcept { return arg_name_; }

                  protected:
                    constexpr void use_arg(char short_name) noexcept { short_name_ = short_name; }
                    constexpr void use_arg(const char* long_name) noexcept { long_name_ = long_name; }
                    constexpr void use_arg(desc&& description) noexcept { description_ = std::move(description); }
                    constexpr void use_arg(struct arg_name&& an) noexcept { arg_name_ = std::move(an); }
                    constexpr void use_arg(enum mandatory&&) noexcept { mandatory_ = true; }

                  private:
                    char short_name_ = 0;
                    std::string_view long_name_;
                    std::string_view description_;
                    std::string_view arg_name_{"ARG"};
                    bool mandatory_ = false;

                }; // class option_base

                template <typename T> T to_value(std::string_view source) { return source; }
                  // template <> inline const char* to_value<const char*>(std::string_view source) { return source; }
                // template <> inline string to_value<string>(std::string_view source) { return source; }
                template <> inline int to_value<int>(std::string_view source) { return std::stoi(std::string(source)); }
                template <> inline long to_value<long>(std::string_view source) { return std::stol(std::string(source)); }
                template <> inline unsigned long to_value<unsigned long>(std::string_view source) { return std::stoul(std::string(source)); }
                template <> inline double to_value<double>(std::string_view source) { return std::stod(std::string(source)); }
                template <> inline bool to_value<bool>(std::string_view source) { return std::stoi(std::string(source)); }

                template <typename T> std::string to_string(const T& source) noexcept { return std::to_string(source); }
                // template <> std::string to_string(const std::string& source) { return '"' + source + '"'; }
                template <> std::string to_string(const str& source) noexcept { return '"' + std::string(source) + '"'; }
                template <> std::string to_string(const str_array& source) noexcept { return '"' + string::join("\" \"", source) + '"'; }

                class invalid_option_value : public std::runtime_error { public: using std::runtime_error::runtime_error; };

            } // namespace detail

            // ----------------------------------------------------------------------

            template <typename T> class option : public detail::option_base
            {
              public:
                template <typename... Args> option(argv& parent, Args&&... args) : option_base(parent) { use_args(std::forward<Args>(args)...); }

                constexpr operator const T&() const { if (value_.has_value()) return *value_; else return default_; }
                constexpr const T& get() const { return static_cast<const T&>(*this); }
                constexpr const T* operator->() const { return &static_cast<const T&>(*this); }
                constexpr const T& operator*() const { return static_cast<const T&>(*this); }
                template <typename R> constexpr bool operator == (const R& rhs) const { return static_cast<const T&>(*this) == rhs; }
                template <typename R> constexpr bool operator != (const R& rhs) const { return !operator==(rhs); }
                std::string get_default() const noexcept override { return detail::to_string(default_); }
                bool has_arg() const noexcept override { return true; }
                bool has_value() const noexcept override { return value_.has_value(); }
                // constexpr bool operator!() const noexcept { return !has_value(); }
                bool multiple_values() const noexcept override { return false; }

                bool is_bool() const noexcept override { if constexpr (std::is_same_v<T, bool>) return true; else return false; }

                void add(detail::cmd_line_iter& arg, detail::cmd_line_iter last) override
                {
                    ++arg;
                    if (arg == last)
                        throw detail::invalid_option_value{"requires argument"};
                    add(*arg);
                }

                void add(std::string_view arg) override { value_ = detail::to_value<T>(arg); }

                template <typename Z = T, typename = std::enable_if_t<!std::is_same_v<Z, bool>>> explicit operator bool() const
                {
                    if constexpr (std::is_same_v<T, str>)
                        return has_value() && !get().empty();
                    else
                        static_assert(std::is_same_v<T, void>, "operator bool not defined for this option type");
                }

              protected:
                using detail::option_base::use_arg;
                constexpr void use_arg(dflt<T>&& def) { default_ = static_cast<T>(def); }

              private:
                std::optional<T> value_;
                T default_;

                template <typename Arg, typename... Args> void use_args(Arg&& arg, Args&&... args)
                {
                    use_arg(std::forward<Arg>(arg));
                    if constexpr (sizeof...(args) > 0)
                        use_args(std::forward<Args>(args)...);
                }
            }; // class option<T>

            template <typename T> inline std::ostream& operator << (std::ostream& out, const option<T>& opt) { return out << opt.get(); }

            template <> void option<bool>::add(detail::cmd_line_iter& /*arg*/, detail::cmd_line_iter /*last*/) { value_ = true; }
            template <> bool option<bool>::has_arg() const noexcept { return false; }
            template <> constexpr option<bool>::operator const bool&() const { if (value_.has_value()) return *value_; return detail::false_; }
            template <> inline std::ostream& operator << (std::ostream& out, const option<bool>& opt) { return out << std::boolalpha << static_cast<const bool&>(opt); }

            template <> void option<str_array>::add(std::string_view arg) { if (!value_) value_ = str_array{arg}; else value_->push_back(arg); }
            template <> bool option<str_array>::multiple_values() const noexcept { return true; }

            template <typename T> using argument = option<T>;

            // ----------------------------------------------------------------------

            class show_help : public std::exception {};
            class errors : public std::exception {};

            class argv
            {
             public:
                using errors_t = std::vector<std::string>;
                enum class on_error { exit, raise, return_false };
                  // returns true on success
                bool parse(int argc, const char* const argv[], on_error on_err = on_error::exit);

                constexpr auto program_name() const { return prog_name_; }
                constexpr const errors_t& errors() const { return errors_; }
                void show_help(std::ostream& out) const;

                virtual ~argv() = default;

             protected:
                argv() = default;

              private:
                std::string_view prog_name_;
                std::vector<detail::option_base*> options_;
                std::vector<std::string_view> args_;
                errors_t errors_;

                option<bool> show_help_{*this, 'h', "help", desc{"show this help screen"}};

                void use(detail::cmd_line_iter& arg, detail::cmd_line_iter last);
                detail::option_base* find(char short_name);
                detail::option_base* find(std::string_view long_name);

                void register_option(detail::option_base* opt);
                friend class detail::option_base;
                friend std::ostream& operator<<(std::ostream& out, const argv& args);

            }; // class argv

            // ----------------------------------------------------------------------

            inline detail::option_base::option_base(argv& parent) { parent.register_option(this); }

            // ----------------------------------------------------------------------

        } // namespace v2
    }     // namespace argv
} // namespace acmacs

// ----------------------------------------------------------------------

template <typename T> struct fmt::formatter<acmacs::argv::option<T>> : fmt::formatter<T> {
    template <typename FormatCtx> auto format(const acmacs::argv::option<T>& opt, FormatCtx& ctx) { return fmt::formatter<T>::format(*opt, ctx); }
};

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>minor fix<commit_after>#pragma once

#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>
#include <optional>

#include "acmacs-base/string.hh"
#include "acmacs-base/fmt.hh"

// ----------------------------------------------------------------------

namespace acmacs
{
    namespace argv
    {
        inline namespace v2
        {
            class argv;
            using str = std::string_view;
            using str_array = std::vector<std::string_view>;

            struct desc : public std::string_view { using std::string_view::string_view; };
            struct arg_name : public std::string_view { using std::string_view::string_view; };
            enum mandatory { mandatory };
            template <typename T> struct dflt { dflt(T&& val) : value{std::move(val)} {} T value; explicit operator T() const { return value; } };
            dflt(const char*) -> dflt<str>;

            namespace detail
            {
                using cmd_line_iter = std::vector<const char*>::const_iterator;

                constexpr bool false_ = false;

                class option_base
                {
                  public:
                    option_base(argv& parent);
                    virtual ~option_base() = default;

                    virtual void add(cmd_line_iter& arg, cmd_line_iter last) = 0;
                    virtual void add(std::string_view arg) = 0;
                    std::string names() const noexcept;
                    constexpr bool has_name() const noexcept { return short_name_ || !long_name_.empty(); }
                    constexpr std::string_view description() const noexcept { return description_; }
                    virtual std::string get_default() const noexcept = 0;
                    virtual bool has_arg() const noexcept { return true; }
                    virtual bool has_value() const noexcept = 0;
                    virtual bool multiple_values() const noexcept = 0;
                    virtual bool is_bool() const noexcept = 0;
                    constexpr bool mandatory() const noexcept { return mandatory_; }

                    constexpr char short_name() const noexcept { return short_name_; }
                    constexpr std::string_view long_name() const noexcept { return long_name_; }
                    constexpr std::string_view arg_name() const noexcept { return arg_name_; }

                  protected:
                    constexpr void use_arg(char short_name) noexcept { short_name_ = short_name; }
                    constexpr void use_arg(const char* long_name) noexcept { long_name_ = long_name; }
                    constexpr void use_arg(desc&& description) noexcept { description_ = std::move(description); }
                    constexpr void use_arg(struct arg_name&& an) noexcept { arg_name_ = std::move(an); }
                    constexpr void use_arg(enum mandatory&&) noexcept { mandatory_ = true; }

                  private:
                    char short_name_ = 0;
                    std::string_view long_name_;
                    std::string_view description_;
                    std::string_view arg_name_{"ARG"};
                    bool mandatory_ = false;

                }; // class option_base

                template <typename T> T to_value(std::string_view source) { return source; }
                  // template <> inline const char* to_value<const char*>(std::string_view source) { return source; }
                // template <> inline string to_value<string>(std::string_view source) { return source; }
                template <> inline int to_value<int>(std::string_view source) { return std::stoi(std::string(source)); }
                template <> inline long to_value<long>(std::string_view source) { return std::stol(std::string(source)); }
                template <> inline unsigned long to_value<unsigned long>(std::string_view source) { return std::stoul(std::string(source)); }
                template <> inline double to_value<double>(std::string_view source) { return std::stod(std::string(source)); }
                template <> inline bool to_value<bool>(std::string_view source) { return std::stoi(std::string(source)); }

                template <typename T> std::string to_string(const T& source) noexcept { return std::to_string(source); }
                // template <> std::string to_string(const std::string& source) { return '"' + source + '"'; }
                template <> std::string to_string(const str& source) noexcept { return '"' + std::string(source) + '"'; }
                template <> std::string to_string(const str_array& source) noexcept { return '"' + string::join("\" \"", source) + '"'; }

                class invalid_option_value : public std::runtime_error { public: using std::runtime_error::runtime_error; };

            } // namespace detail

            // ----------------------------------------------------------------------

            template <typename T> class option : public detail::option_base
            {
              public:
                template <typename... Args> option(argv& parent, Args&&... args) : option_base(parent) { use_args(std::forward<Args>(args)...); }

                constexpr operator const T&() const { if (value_.has_value()) return *value_; else return default_; }
                constexpr const T& get() const { return static_cast<const T&>(*this); }
                constexpr const T* operator->() const { return &static_cast<const T&>(*this); }
                constexpr const T& operator*() const { return static_cast<const T&>(*this); }
                template <typename R> constexpr bool operator == (const R& rhs) const { return static_cast<const T&>(*this) == rhs; }
                template <typename R> constexpr bool operator != (const R& rhs) const { return !operator==(rhs); }
                std::string get_default() const noexcept override { return detail::to_string(default_); }
                bool has_arg() const noexcept override { return true; }
                bool has_value() const noexcept override { return value_.has_value(); }
                bool multiple_values() const noexcept override { return false; }

                bool is_bool() const noexcept override { if constexpr (std::is_same_v<T, bool>) return true; else return false; }

                void add(detail::cmd_line_iter& arg, detail::cmd_line_iter last) override
                {
                    ++arg;
                    if (arg == last)
                        throw detail::invalid_option_value{"requires argument"};
                    add(*arg);
                }

                void add(std::string_view arg) override { value_ = detail::to_value<T>(arg); }

                template <typename Z = T, typename = std::enable_if_t<!std::is_same_v<Z, bool>>> explicit operator bool() const
                {
                    if constexpr (std::is_same_v<T, str>)
                        return has_value() && !get().empty();
                    else
                        static_assert(std::is_same_v<T, void>, "operator bool not defined for this option type");
                }

              protected:
                using detail::option_base::use_arg;
                constexpr void use_arg(dflt<T>&& def) { default_ = static_cast<T>(def); }

              private:
                std::optional<T> value_;
                T default_;

                template <typename Arg, typename... Args> void use_args(Arg&& arg, Args&&... args)
                {
                    use_arg(std::forward<Arg>(arg));
                    if constexpr (sizeof...(args) > 0)
                        use_args(std::forward<Args>(args)...);
                }
            }; // class option<T>

            template <typename T> inline std::ostream& operator << (std::ostream& out, const option<T>& opt) { return out << opt.get(); }

            template <> void option<bool>::add(detail::cmd_line_iter& /*arg*/, detail::cmd_line_iter /*last*/) { value_ = true; }
            template <> bool option<bool>::has_arg() const noexcept { return false; }
            template <> constexpr option<bool>::operator const bool&() const { if (value_.has_value()) return *value_; return detail::false_; }
            template <> inline std::ostream& operator << (std::ostream& out, const option<bool>& opt) { return out << std::boolalpha << static_cast<const bool&>(opt); }

            template <> void option<str_array>::add(std::string_view arg) { if (!value_) value_ = str_array{arg}; else value_->push_back(arg); }
            template <> bool option<str_array>::multiple_values() const noexcept { return true; }

            template <typename T> using argument = option<T>;

            // ----------------------------------------------------------------------

            class show_help : public std::exception {};
            class errors : public std::exception {};

            class argv
            {
             public:
                using errors_t = std::vector<std::string>;
                enum class on_error { exit, raise, return_false };
                  // returns true on success
                bool parse(int argc, const char* const argv[], on_error on_err = on_error::exit);

                constexpr auto program_name() const { return prog_name_; }
                constexpr const errors_t& errors() const { return errors_; }
                void show_help(std::ostream& out) const;

                virtual ~argv() = default;

             protected:
                argv() = default;

              private:
                std::string_view prog_name_;
                std::vector<detail::option_base*> options_;
                std::vector<std::string_view> args_;
                errors_t errors_;

                option<bool> show_help_{*this, 'h', "help", desc{"show this help screen"}};

                void use(detail::cmd_line_iter& arg, detail::cmd_line_iter last);
                detail::option_base* find(char short_name);
                detail::option_base* find(std::string_view long_name);

                void register_option(detail::option_base* opt);
                friend class detail::option_base;
                friend std::ostream& operator<<(std::ostream& out, const argv& args);

            }; // class argv

            // ----------------------------------------------------------------------

            inline detail::option_base::option_base(argv& parent) { parent.register_option(this); }

            // ----------------------------------------------------------------------

        } // namespace v2
    }     // namespace argv
} // namespace acmacs

// ----------------------------------------------------------------------

template <typename T> struct fmt::formatter<acmacs::argv::option<T>> : fmt::formatter<T> {
    template <typename FormatCtx> auto format(const acmacs::argv::option<T>& opt, FormatCtx& ctx) { return fmt::formatter<T>::format(*opt, ctx); }
};

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#include <memory>

#include "draw.hh"
#include "chart.hh"

#include "acmacs-draw/surface-cairo.hh"

// ----------------------------------------------------------------------

void ChartDraw::prepare()
{
    std::unique_ptr<BoundingBall> bb(mChart.projection(mProjectionNo).layout().minimum_bounding_ball());
    mViewport.set_from_center_size(bb->center(), bb->diameter());
    mViewport.whole_width();
      // std::cerr << mViewport << std::endl;

} // ChartDraw::prepare

// ----------------------------------------------------------------------

void ChartDraw::draw(Surface& aSurface)
{
    double pix = 0.01;
    aSurface.grid(1, "cyan3", pix);
    aSurface.border("blue", pix * 5);
    aSurface.circle({0, 0}, 1, 1, 0, "pink", pix);

} // ChartDraw::draw

// ----------------------------------------------------------------------

void ChartDraw::draw(std::string aFilename, double aSize)
{
    PdfCairo surface(aFilename, aSize, aSize);
    // surface.resize(mViewport.size.width);
    Surface& rescaled = surface.subsurface({0, 0}, surface.size(), mViewport.size.width, true);
    rescaled.viewport_offset(mViewport.offset());
    draw(rescaled);

} // ChartDraw::draw

// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>porting to the new surface system (from acmacs-draw)<commit_after>#include <memory>

#include "draw.hh"
#include "chart.hh"

#include "acmacs-draw/surface-cairo.hh"

// ----------------------------------------------------------------------

void ChartDraw::prepare()
{
    std::unique_ptr<BoundingBall> bb(mChart.projection(mProjectionNo).layout().minimum_bounding_ball());
    mViewport.set_from_center_size(bb->center(), bb->diameter());
    mViewport.whole_width();
      // std::cerr << mViewport << std::endl;

} // ChartDraw::prepare

// ----------------------------------------------------------------------

void ChartDraw::draw(Surface& aSurface)
{
    double pix = 0.01;
    aSurface.grid(Scaled{1}, "cyan3", Pixels{pix});
    aSurface.border("blue", Pixels{pix * 5});
    aSurface.circle({0, 0}, Scaled{1}, 1, 0, "pink", Pixels{pix});

} // ChartDraw::draw

// ----------------------------------------------------------------------

void ChartDraw::draw(std::string aFilename, double aSize)
{
    PdfCairo surface(aFilename, aSize, aSize);
    // surface.resize(mViewport.size.width);
    Surface& rescaled = surface.subsurface({0, 0}, Scaled{surface.viewport().size.width}, mViewport, true);
    draw(rescaled);

} // ChartDraw::draw

// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#include "acmacs-base/argv.hh"
#include "acmacs-base/temp-file.hh"
#include "acmacs-base/quicklook.hh"
#include "acmacs-base/filesystem.hh"
#include "acmacs-chart-2/factory-import.hh"
#include "acmacs-map-draw/setup-dbs.hh"
#include "acmacs-map-draw/log.hh"
#include "acmacs-map-draw/mapi-settings.hh"
#include "acmacs-map-draw/draw.hh"

// ----------------------------------------------------------------------

constexpr const std::string_view sHelpPost = R"(
-D <arg> --define <arg>

)";

using namespace acmacs::argv;
struct MapiOptions : public acmacs::argv::v2::argv
{
    MapiOptions(int a_argc, const char* const a_argv[], on_error on_err = on_error::exit) { parse(a_argc, a_argv, on_err); }
    // std::string_view help_pre() const override { return sHelpPost; }
    std::string_view help_post() const override { return sHelpPost; }

    option<str> db_dir{*this, "db-dir"};
    // option<str> seqdb{*this, "seqdb"};

    option<str_array> settings_files{*this, 's'};
    option<str_array> defines{*this, 'D', "define", desc{"see {ACMACSD_ROOT}/share/doc/mapi.org"}};
    option<str_array> apply{*this, 'a', "apply", dflt{str_array{"main"}}, desc{"name or json array to use as \"apply\", e.g. [\"/all-grey\",\"/egg\",\"/clades\",\"/labels\"]"}};
    // option<str>       apply_from{*this, "apply-from", desc{"read json array to use as \"apply\" from file (or stdin if \"-\""}};
    // option<bool>      clade{*this, "clade"};
    // option<double>    point_scale{*this, "point-scale", dflt{1.0}};
    // option<double>    rotate_degrees{*this, 'r', "rotate-degrees", dflt{0.0}, desc{"counter clockwise"}};
    // option<bool>      flip_ew{*this, "flip-ew"};
    // option<bool>      flip_ns{*this, "flip-ns"};
    // option<str>       save{*this, "save", desc{"save resulting chart with modified projection and plot spec"}};
    // option<str>       previous{*this, "previous"};
    option<size_t>    projection{*this, 'p', "projection", dflt{0ul}};

    option<bool>      open{*this, "open"};
    option<bool>      ql{*this, "ql"};
    option<str_array> verbose{*this, 'v', "verbose", desc{"comma separated list (or multiple switches) of enablers"}};

    argument<str> chart{*this, arg_name{"chart.ace"}, mandatory};
    argument<str> output{*this, arg_name{"mapi-output.pdf"}};
};

// ----------------------------------------------------------------------

int main(int argc, char* const argv[])
{
    using namespace std::string_view_literals;
    int exit_code = 0;
    try {
        acmacs::log::register_enabler_acmacs_base();
        MapiOptions opt(argc, argv);
        acmacs::log::enable(opt.verbose);
        setup_dbs(opt.db_dir, !opt.verbose.empty());
        ChartDraw chart_draw(std::make_shared<acmacs::chart::ChartModify>(acmacs::chart::import_from_file(opt.chart)), opt.projection);

        acmacs::mapi::Settings settings{chart_draw};
        settings.load(opt.settings_files, opt.defines);
        for (const auto& to_apply : opt.apply) {
            // AD_DEBUG("to_apply \"{}\"", to_apply);
            settings.apply(to_apply);
        }

        chart_draw.calculate_viewport();
        AD_INFO("{:.2f}", chart_draw.viewport("mapi main"));
        AD_INFO("transformation: {}", chart_draw.transformation());

        if (opt.output->empty()) {
            acmacs::file::temp output{fmt::format("{}--p{}.pdf", fs::path(*opt.chart).stem(), opt.projection)};
            chart_draw.draw(output, 800, report_time::yes);
            acmacs::quicklook(output, 2);
        }
        else if (*opt.output == "/dev/null"sv || opt.output == "/"sv) { // do not generate pdf
        }
        else {
            chart_draw.draw(opt.output, 800, report_time::yes);
            acmacs::open_or_quicklook(opt.open, opt.ql, opt.output);
        }
    }
    catch (std::exception& err) {
        fmt::print(stderr, "ERROR: {}\n", err);
        exit_code = 2;
    }
    return exit_code;
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>mapi: support for multiple inputs (e.g. for procrustes)<commit_after>#include "acmacs-base/argv.hh"
#include "acmacs-base/temp-file.hh"
#include "acmacs-base/string-compare.hh"
#include "acmacs-base/quicklook.hh"
#include "acmacs-base/filesystem.hh"
#include "acmacs-chart-2/factory-import.hh"
#include "acmacs-map-draw/setup-dbs.hh"
#include "acmacs-map-draw/log.hh"
#include "acmacs-map-draw/mapi-settings.hh"
#include "acmacs-map-draw/draw.hh"

// ----------------------------------------------------------------------

constexpr const std::string_view sHelpPost = R"(
one input chart: make map
two input charts: make procrustes
output /: do not generate any output
no output: generate temp pdf and open it (and then delete it)

-D <arg> --define <arg>

)";

using namespace acmacs::argv;
struct MapiOptions : public acmacs::argv::v2::argv
{
    MapiOptions(int a_argc, const char* const a_argv[], on_error on_err = on_error::exit) { parse(a_argc, a_argv, on_err); }
    // std::string_view help_pre() const override { return sHelpPost; }
    std::string_view help_post() const override { return sHelpPost; }

    option<str> db_dir{*this, "db-dir"};
    // option<str> seqdb{*this, "seqdb"};

    option<str_array> settings_files{*this, 's'};
    option<str_array> defines{*this, 'D', "define", desc{"see {ACMACSD_ROOT}/share/doc/mapi.org"}};
    option<str_array> apply{*this, 'a', "apply", dflt{str_array{"main"}}, desc{"name or json array to use as \"apply\", e.g. [\"/all-grey\",\"/egg\",\"/clades\",\"/labels\"]"}};
    // option<str>       apply_from{*this, "apply-from", desc{"read json array to use as \"apply\" from file (or stdin if \"-\""}};
    // option<bool>      clade{*this, "clade"};
    // option<double>    point_scale{*this, "point-scale", dflt{1.0}};
    // option<double>    rotate_degrees{*this, 'r', "rotate-degrees", dflt{0.0}, desc{"counter clockwise"}};
    // option<bool>      flip_ew{*this, "flip-ew"};
    // option<bool>      flip_ns{*this, "flip-ns"};
    // option<str>       save{*this, "save", desc{"save resulting chart with modified projection and plot spec"}};
    // option<str>       previous{*this, "previous"};
    option<size_t>    projection{*this, 'p', "projection", dflt{0ul}};
    option<size_t>    secondary_projection{*this, 'r', "secondary-projection", dflt{static_cast<size_t>(-1)}};

    option<bool>      open{*this, "open"};
    option<bool>      ql{*this, "ql"};
    option<str_array> verbose{*this, 'v', "verbose", desc{"comma separated list (or multiple switches) of enablers"}};

    argument<str_array> files{*this, arg_name{"input: chart.ace, chart.save, chart.acd1; output: map.pdf, /"}, mandatory};
};

// ----------------------------------------------------------------------

static std::pair<std::vector<std::string_view>, std::vector<std::string_view>> parse_files(const argument<str_array>& files);

int main(int argc, char* const argv[])
{
    using namespace std::string_view_literals;
    int exit_code = 0;
    try {
        acmacs::log::register_enabler_acmacs_base();
        MapiOptions opt(argc, argv);
        acmacs::log::enable(opt.verbose);
        setup_dbs(opt.db_dir, !opt.verbose.empty());

        const auto [inputs, outputs] = parse_files(opt.files);

        ChartDraw chart_draw(std::make_shared<acmacs::chart::ChartModify>(acmacs::chart::import_from_file(inputs[0])), opt.projection);

        acmacs::mapi::Settings settings{chart_draw};
        settings.load(opt.settings_files, opt.defines);
        for (const auto& to_apply : opt.apply) {
            // AD_DEBUG("to_apply \"{}\"", to_apply);
            settings.apply(to_apply);
        }

        chart_draw.calculate_viewport();
        AD_INFO("{:.2f}", chart_draw.viewport("mapi main"));
        AD_INFO("transformation: {}", chart_draw.transformation());

        if (outputs.empty()) {
            acmacs::file::temp output{fmt::format("{}--p{}.pdf", fs::path(inputs[0]).stem(), opt.projection)};
            chart_draw.draw(output, 800, report_time::yes);
            acmacs::quicklook(output, 2);
        }
        else if (outputs[0] == "/dev/null"sv || outputs[0] == "/"sv) { // do not generate pdf
        }
        else {
            chart_draw.draw(outputs[0], 800, report_time::yes);
            acmacs::open_or_quicklook(opt.open, opt.ql, outputs[0]);
        }
    }
    catch (std::exception& err) {
        fmt::print(stderr, "ERROR: {}\n", err);
        exit_code = 2;
    }
    return exit_code;
}

// ----------------------------------------------------------------------

std::pair<std::vector<std::string_view>, std::vector<std::string_view>> parse_files(const argument<str_array>& files)
{
    using namespace std::string_view_literals;
    std::vector<std::string_view> inputs, outputs;
    constexpr std::array input_suffixes{".ace"sv, ".acd1"sv, ".acd1.xz"sv, ".acd1.bz2"sv, ".save"sv, ".save.xz"sv, ".save.bz2"sv};
    const auto is_input = [&input_suffixes](std::string_view name) -> bool {
        return std::any_of(std::begin(input_suffixes), std::end(input_suffixes), [name](std::string_view suff) -> bool { return acmacs::string::endswith(name, suff); });
    };
    for (const auto& file : files) {
        if (is_input(file))
            inputs.push_back(file);
        else
            outputs.push_back(file);
    }
    if (inputs.empty())
        throw std::runtime_error{"no input files (charts) found in the command line"};
    return {inputs, outputs};

} // parse_files

// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>//===-- ubsan_type_hash_itanium.cc ----------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implementation of type hashing/lookup for Itanium C++ ABI.
//
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"
#include "ubsan_platform.h"
#if CAN_SANITIZE_UB && UBSAN_CAN_USE_CXXABI
#include "ubsan_type_hash.h"

#include "sanitizer_common/sanitizer_common.h"

// The following are intended to be binary compatible with the definitions
// given in the Itanium ABI. We make no attempt to be ODR-compatible with
// those definitions, since existing ABI implementations aren't.

namespace std {
  class type_info {
  public:
    virtual ~type_info();

    const char *__type_name;
  };
}

namespace __cxxabiv1 {

/// Type info for classes with no bases, and base class for type info for
/// classes with bases.
class __class_type_info : public std::type_info {
  ~__class_type_info() override;
};

/// Type info for classes with simple single public inheritance.
class __si_class_type_info : public __class_type_info {
public:
  ~__si_class_type_info() override;

  const __class_type_info *__base_type;
};

class __base_class_type_info {
public:
  const __class_type_info *__base_type;
  long __offset_flags;

  enum __offset_flags_masks {
    __virtual_mask = 0x1,
    __public_mask = 0x2,
    __offset_shift = 8
  };
};

/// Type info for classes with multiple, virtual, or non-public inheritance.
class __vmi_class_type_info : public __class_type_info {
public:
  ~__vmi_class_type_info() override;

  unsigned int flags;
  unsigned int base_count;
  __base_class_type_info base_info[1];
};

}

namespace abi = __cxxabiv1;

// We implement a simple two-level cache for type-checking results. For each
// (vptr,type) pair, a hash is computed. This hash is assumed to be globally
// unique; if it collides, we will get false negatives, but:
//  * such a collision would have to occur on the *first* bad access,
//  * the probability of such a collision is low (and for a 64-bit target, is
//    negligible), and
//  * the vptr, and thus the hash, can be affected by ASLR, so multiple runs
//    give better coverage.
//
// The first caching layer is a small hash table with no chaining; buckets are
// reused as needed. The second caching layer is a large hash table with open
// chaining. We can freely evict from either layer since this is just a cache.
//
// FIXME: Make these hash table accesses thread-safe. The races here are benign:
//        assuming the unsequenced loads and stores don't misbehave too badly,
//        the worst case is false negatives or poor cache behavior, not false
//        positives or crashes.

/// Find a bucket to store the given hash value in.
static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
  static const unsigned HashTableSize = 65537;
  static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize];

  unsigned First = (V & 65535) ^ 1;
  unsigned Probe = First;
  for (int Tries = 5; Tries; --Tries) {
    if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)
      return &__ubsan_vptr_hash_set[Probe];
    Probe += ((V >> 16) & 65535) + 1;
    if (Probe >= HashTableSize)
      Probe -= HashTableSize;
  }
  // FIXME: Pick a random entry from the probe sequence to evict rather than
  //        just taking the first.
  return &__ubsan_vptr_hash_set[First];
}

/// \brief Determine whether \p Derived has a \p Base base class subobject at
/// offset \p Offset.
static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
                                  const abi::__class_type_info *Base,
                                  sptr Offset) {
  if (Derived->__type_name == Base->__type_name ||
      (SANITIZER_NON_UNIQUE_TYPEINFO &&
       !internal_strcmp(Derived->__type_name, Base->__type_name)))
    return Offset == 0;

  if (const abi::__si_class_type_info *SI =
        dynamic_cast<const abi::__si_class_type_info*>(Derived))
    return isDerivedFromAtOffset(SI->__base_type, Base, Offset);

  const abi::__vmi_class_type_info *VTI =
    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
  if (!VTI)
    // No base class subobjects.
    return false;

  // Look for a base class which is derived from \p Base at the right offset.
  for (unsigned int base = 0; base != VTI->base_count; ++base) {
    // FIXME: Curtail the recursion if this base can't possibly contain the
    //        given offset.
    sptr OffsetHere = VTI->base_info[base].__offset_flags >>
                      abi::__base_class_type_info::__offset_shift;
    if (VTI->base_info[base].__offset_flags &
          abi::__base_class_type_info::__virtual_mask)
      // For now, just punt on virtual bases and say 'yes'.
      // FIXME: OffsetHere is the offset in the vtable of the virtual base
      //        offset. Read the vbase offset out of the vtable and use it.
      return true;
    if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,
                              Base, Offset - OffsetHere))
      return true;
  }

  return false;
}

/// \brief Find the derived-most dynamic base class of \p Derived at offset
/// \p Offset.
static const abi::__class_type_info *findBaseAtOffset(
    const abi::__class_type_info *Derived, sptr Offset) {
  if (!Offset)
    return Derived;

  if (const abi::__si_class_type_info *SI =
        dynamic_cast<const abi::__si_class_type_info*>(Derived))
    return findBaseAtOffset(SI->__base_type, Offset);

  const abi::__vmi_class_type_info *VTI =
    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
  if (!VTI)
    // No base class subobjects.
    return 0;

  for (unsigned int base = 0; base != VTI->base_count; ++base) {
    sptr OffsetHere = VTI->base_info[base].__offset_flags >>
                      abi::__base_class_type_info::__offset_shift;
    if (VTI->base_info[base].__offset_flags &
          abi::__base_class_type_info::__virtual_mask)
      // FIXME: Can't handle virtual bases yet.
      continue;
    if (const abi::__class_type_info *Base =
          findBaseAtOffset(VTI->base_info[base].__base_type,
                           Offset - OffsetHere))
      return Base;
  }

  return 0;
}

namespace {

struct VtablePrefix {
  /// The offset from the vptr to the start of the most-derived object.
  /// This will only be greater than zero in some virtual base class vtables
  /// used during object con-/destruction, and will usually be exactly zero.
  sptr Offset;
  /// The type_info object describing the most-derived class type.
  std::type_info *TypeInfo;
};
VtablePrefix *getVtablePrefix(void *Vtable) {
  VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable);
  if (!Vptr)
    return 0;
  VtablePrefix *Prefix = Vptr - 1;
  if (!Prefix->TypeInfo)
    // This can't possibly be a valid vtable.
    return 0;
  return Prefix;
}

}

bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
  // A crash anywhere within this function probably means the vptr is corrupted.
  // FIXME: Perform these checks more cautiously.

  // Check whether this is something we've evicted from the cache.
  HashValue *Bucket = getTypeCacheHashTableBucket(Hash);
  if (*Bucket == Hash) {
    __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
    return true;
  }

  void *VtablePtr = *reinterpret_cast<void **>(Object);
  VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
  if (!Vtable)
    return false;
  if (Vtable->Offset < -VptrMaxOffsetToTop || Vtable->Offset > VptrMaxOffsetToTop) {
    // Too large or too small offset are signs of Vtable corruption.
    return false;
  }

  // Check that this is actually a type_info object for a class type.
  abi::__class_type_info *Derived =
    dynamic_cast<abi::__class_type_info*>(Vtable->TypeInfo);
  if (!Derived)
    return false;

  abi::__class_type_info *Base = (abi::__class_type_info*)Type;
  if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))
    return false;

  // Success. Cache this result.
  __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
  *Bucket = Hash;
  return true;
}

__ubsan::DynamicTypeInfo
__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
  VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
  if (!Vtable)
    return DynamicTypeInfo(0, 0, 0);
  if (Vtable->Offset < -VptrMaxOffsetToTop || Vtable->Offset > VptrMaxOffsetToTop)
    return DynamicTypeInfo(0, Vtable->Offset, 0);
  const abi::__class_type_info *ObjectType = findBaseAtOffset(
    static_cast<const abi::__class_type_info*>(Vtable->TypeInfo),
    -Vtable->Offset);
  return DynamicTypeInfo(Vtable->TypeInfo->__type_name, -Vtable->Offset,
                         ObjectType ? ObjectType->__type_name : "<unknown>");
}

#endif  // CAN_SANITIZE_UB && !SANITIZER_WINDOWS
<commit_msg>Revert "    [compiler-rt] Allow c++ abi to be explictly disabled in cmake configuration"<commit_after>//===-- ubsan_type_hash_itanium.cc ----------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implementation of type hashing/lookup for Itanium C++ ABI.
//
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"
#include "ubsan_platform.h"
#if CAN_SANITIZE_UB && !SANITIZER_WINDOWS
#include "ubsan_type_hash.h"

#include "sanitizer_common/sanitizer_common.h"

// The following are intended to be binary compatible with the definitions
// given in the Itanium ABI. We make no attempt to be ODR-compatible with
// those definitions, since existing ABI implementations aren't.

namespace std {
  class type_info {
  public:
    virtual ~type_info();

    const char *__type_name;
  };
}

namespace __cxxabiv1 {

/// Type info for classes with no bases, and base class for type info for
/// classes with bases.
class __class_type_info : public std::type_info {
  ~__class_type_info() override;
};

/// Type info for classes with simple single public inheritance.
class __si_class_type_info : public __class_type_info {
public:
  ~__si_class_type_info() override;

  const __class_type_info *__base_type;
};

class __base_class_type_info {
public:
  const __class_type_info *__base_type;
  long __offset_flags;

  enum __offset_flags_masks {
    __virtual_mask = 0x1,
    __public_mask = 0x2,
    __offset_shift = 8
  };
};

/// Type info for classes with multiple, virtual, or non-public inheritance.
class __vmi_class_type_info : public __class_type_info {
public:
  ~__vmi_class_type_info() override;

  unsigned int flags;
  unsigned int base_count;
  __base_class_type_info base_info[1];
};

}

namespace abi = __cxxabiv1;

// We implement a simple two-level cache for type-checking results. For each
// (vptr,type) pair, a hash is computed. This hash is assumed to be globally
// unique; if it collides, we will get false negatives, but:
//  * such a collision would have to occur on the *first* bad access,
//  * the probability of such a collision is low (and for a 64-bit target, is
//    negligible), and
//  * the vptr, and thus the hash, can be affected by ASLR, so multiple runs
//    give better coverage.
//
// The first caching layer is a small hash table with no chaining; buckets are
// reused as needed. The second caching layer is a large hash table with open
// chaining. We can freely evict from either layer since this is just a cache.
//
// FIXME: Make these hash table accesses thread-safe. The races here are benign:
//        assuming the unsequenced loads and stores don't misbehave too badly,
//        the worst case is false negatives or poor cache behavior, not false
//        positives or crashes.

/// Find a bucket to store the given hash value in.
static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
  static const unsigned HashTableSize = 65537;
  static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize];

  unsigned First = (V & 65535) ^ 1;
  unsigned Probe = First;
  for (int Tries = 5; Tries; --Tries) {
    if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)
      return &__ubsan_vptr_hash_set[Probe];
    Probe += ((V >> 16) & 65535) + 1;
    if (Probe >= HashTableSize)
      Probe -= HashTableSize;
  }
  // FIXME: Pick a random entry from the probe sequence to evict rather than
  //        just taking the first.
  return &__ubsan_vptr_hash_set[First];
}

/// \brief Determine whether \p Derived has a \p Base base class subobject at
/// offset \p Offset.
static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
                                  const abi::__class_type_info *Base,
                                  sptr Offset) {
  if (Derived->__type_name == Base->__type_name ||
      (SANITIZER_NON_UNIQUE_TYPEINFO &&
       !internal_strcmp(Derived->__type_name, Base->__type_name)))
    return Offset == 0;

  if (const abi::__si_class_type_info *SI =
        dynamic_cast<const abi::__si_class_type_info*>(Derived))
    return isDerivedFromAtOffset(SI->__base_type, Base, Offset);

  const abi::__vmi_class_type_info *VTI =
    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
  if (!VTI)
    // No base class subobjects.
    return false;

  // Look for a base class which is derived from \p Base at the right offset.
  for (unsigned int base = 0; base != VTI->base_count; ++base) {
    // FIXME: Curtail the recursion if this base can't possibly contain the
    //        given offset.
    sptr OffsetHere = VTI->base_info[base].__offset_flags >>
                      abi::__base_class_type_info::__offset_shift;
    if (VTI->base_info[base].__offset_flags &
          abi::__base_class_type_info::__virtual_mask)
      // For now, just punt on virtual bases and say 'yes'.
      // FIXME: OffsetHere is the offset in the vtable of the virtual base
      //        offset. Read the vbase offset out of the vtable and use it.
      return true;
    if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,
                              Base, Offset - OffsetHere))
      return true;
  }

  return false;
}

/// \brief Find the derived-most dynamic base class of \p Derived at offset
/// \p Offset.
static const abi::__class_type_info *findBaseAtOffset(
    const abi::__class_type_info *Derived, sptr Offset) {
  if (!Offset)
    return Derived;

  if (const abi::__si_class_type_info *SI =
        dynamic_cast<const abi::__si_class_type_info*>(Derived))
    return findBaseAtOffset(SI->__base_type, Offset);

  const abi::__vmi_class_type_info *VTI =
    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
  if (!VTI)
    // No base class subobjects.
    return 0;

  for (unsigned int base = 0; base != VTI->base_count; ++base) {
    sptr OffsetHere = VTI->base_info[base].__offset_flags >>
                      abi::__base_class_type_info::__offset_shift;
    if (VTI->base_info[base].__offset_flags &
          abi::__base_class_type_info::__virtual_mask)
      // FIXME: Can't handle virtual bases yet.
      continue;
    if (const abi::__class_type_info *Base =
          findBaseAtOffset(VTI->base_info[base].__base_type,
                           Offset - OffsetHere))
      return Base;
  }

  return 0;
}

namespace {

struct VtablePrefix {
  /// The offset from the vptr to the start of the most-derived object.
  /// This will only be greater than zero in some virtual base class vtables
  /// used during object con-/destruction, and will usually be exactly zero.
  sptr Offset;
  /// The type_info object describing the most-derived class type.
  std::type_info *TypeInfo;
};
VtablePrefix *getVtablePrefix(void *Vtable) {
  VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable);
  if (!Vptr)
    return 0;
  VtablePrefix *Prefix = Vptr - 1;
  if (!Prefix->TypeInfo)
    // This can't possibly be a valid vtable.
    return 0;
  return Prefix;
}

}

bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
  // A crash anywhere within this function probably means the vptr is corrupted.
  // FIXME: Perform these checks more cautiously.

  // Check whether this is something we've evicted from the cache.
  HashValue *Bucket = getTypeCacheHashTableBucket(Hash);
  if (*Bucket == Hash) {
    __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
    return true;
  }

  void *VtablePtr = *reinterpret_cast<void **>(Object);
  VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
  if (!Vtable)
    return false;
  if (Vtable->Offset < -VptrMaxOffsetToTop || Vtable->Offset > VptrMaxOffsetToTop) {
    // Too large or too small offset are signs of Vtable corruption.
    return false;
  }

  // Check that this is actually a type_info object for a class type.
  abi::__class_type_info *Derived =
    dynamic_cast<abi::__class_type_info*>(Vtable->TypeInfo);
  if (!Derived)
    return false;

  abi::__class_type_info *Base = (abi::__class_type_info*)Type;
  if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))
    return false;

  // Success. Cache this result.
  __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
  *Bucket = Hash;
  return true;
}

__ubsan::DynamicTypeInfo
__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
  VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
  if (!Vtable)
    return DynamicTypeInfo(0, 0, 0);
  if (Vtable->Offset < -VptrMaxOffsetToTop || Vtable->Offset > VptrMaxOffsetToTop)
    return DynamicTypeInfo(0, Vtable->Offset, 0);
  const abi::__class_type_info *ObjectType = findBaseAtOffset(
    static_cast<const abi::__class_type_info*>(Vtable->TypeInfo),
    -Vtable->Offset);
  return DynamicTypeInfo(Vtable->TypeInfo->__type_name, -Vtable->Offset,
                         ObjectType ? ObjectType->__type_name : "<unknown>");
}

#endif  // CAN_SANITIZE_UB && !SANITIZER_WINDOWS
<|endoftext|>


<commit_before>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <stdio.h>
#include <util/system.h>
#include <walletinitinterface.h>

class CWallet;

namespace interfaces {
class Chain;
}

class DummyWalletInit : public WalletInitInterface {
public:

    bool HasWalletSupport() const override {return false;}
    void AddWalletOptions() const override;
    bool ParameterInteraction() const override {return true;}
    void Construct(InitInterfaces& interfaces) const override {LogPrintf("No wallet support compiled in!\n");}
};

void DummyWalletInit::AddWalletOptions() const
{
    std::vector<std::string> opts = {
        "-addresstype",
        "-changetype",
        "-disablewallet",
        "-discardfee=<amt>",
        "-fallbackfee=<amt>",
        "-keypool=<n>",
        "-mintxfee=<amt>",
        "-paytxfee=<amt>",
        "-rescan",
        "-salvagewallet",
        "-spendzeroconfchange",
        "-txconfirmtarget=<n>",
        "-upgradewallet",
        "-wallet=<path>",
        "-walletbroadcast",
        "-walletdir=<dir>",
        "-walletnotify=<cmd>",
        "-walletrbf",
        "-zapwallettxes=<mode>",
        "-dblogsize=<n>",
        "-flushwallet",
        "-privdb",
        "-walletrejectlongchains",
    };
    gArgs.AddHiddenArgs(opts);
}

const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();

fs::path GetWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<fs::path> ListWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<std::shared_ptr<CWallet>> GetWallets()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

namespace interfaces {

class Wallet;

std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

} // namespace interfaces
<commit_msg>Bugfix: dummywallet: Add -ignorepartialspends to list of ignored wallet options<commit_after>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <stdio.h>
#include <util/system.h>
#include <walletinitinterface.h>

class CWallet;

namespace interfaces {
class Chain;
}

class DummyWalletInit : public WalletInitInterface {
public:

    bool HasWalletSupport() const override {return false;}
    void AddWalletOptions() const override;
    bool ParameterInteraction() const override {return true;}
    void Construct(InitInterfaces& interfaces) const override {LogPrintf("No wallet support compiled in!\n");}
};

void DummyWalletInit::AddWalletOptions() const
{
    std::vector<std::string> opts = {
        "-addresstype",
        "-avoidpartialspends",
        "-changetype",
        "-disablewallet",
        "-discardfee=<amt>",
        "-fallbackfee=<amt>",
        "-keypool=<n>",
        "-mintxfee=<amt>",
        "-paytxfee=<amt>",
        "-rescan",
        "-salvagewallet",
        "-spendzeroconfchange",
        "-txconfirmtarget=<n>",
        "-upgradewallet",
        "-wallet=<path>",
        "-walletbroadcast",
        "-walletdir=<dir>",
        "-walletnotify=<cmd>",
        "-walletrbf",
        "-zapwallettxes=<mode>",
        "-dblogsize=<n>",
        "-flushwallet",
        "-privdb",
        "-walletrejectlongchains",
    };
    gArgs.AddHiddenArgs(opts);
}

const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();

fs::path GetWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<fs::path> ListWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<std::shared_ptr<CWallet>> GetWallets()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

namespace interfaces {

class Wallet;

std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

} // namespace interfaces
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file ContractionState.cxx
 ** Manages visibility of lines for folding.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include "Platform.h"

#include "ContractionState.h"

OneLine::OneLine() {
	displayLine = 0;
	//docLine = 0;
	visible = true;
	height = 1;
	expanded = true;
}

ContractionState::ContractionState() {
	lines = 0;
	size = 0;
	linesInDoc = 1;
	linesInDisplay = 1;
	valid = false;
	docLines = 0;
	sizeDocLines = 0;
}

ContractionState::~ContractionState() {
	Clear();
}

void ContractionState::MakeValid() const {
	if (!valid) {
		// Could be cleverer by keeping the index of the last still valid entry
		// rather than invalidating all.
		linesInDisplay = 0;
		for (int lineInDoc=0; lineInDoc<linesInDoc; lineInDoc++) {
			lines[lineInDoc].displayLine = linesInDisplay;
			if (lines[lineInDoc].visible) {
				linesInDisplay += lines[lineInDoc].height;
			}
		}
		if (sizeDocLines < linesInDisplay) {
			delete []docLines;
			int *docLinesNew = new int[linesInDisplay + growSize];
			if (!docLinesNew) {
				docLines = 0;
				sizeDocLines = 0;
				return;
			}
			docLines = docLinesNew;
			sizeDocLines = linesInDisplay + growSize;
		}

		int lineInDisplay=0;
		for (int line=0; line<linesInDoc; line++) {
			if (lines[line].visible) {
				for (int linePiece=0; linePiece<lines[line].height; linePiece++) {
					docLines[lineInDisplay] = line;
					lineInDisplay++;
				}
			}
		}
		valid = true;
	}
}

void ContractionState::Clear() {
	delete []lines;
	lines = 0;
	size = 0;
	linesInDoc = 1;
	linesInDisplay = 1;
	delete []docLines;
	docLines = 0;
	sizeDocLines = 0;
}

int ContractionState::LinesInDoc() const {
	return linesInDoc;
}

int ContractionState::LinesDisplayed() const {
	if (size != 0) {
		MakeValid();
	}
	return linesInDisplay;
}

int ContractionState::DisplayFromDoc(int lineDoc) const {
	if (size == 0) {
		return lineDoc;
	}
	MakeValid();
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		return lines[lineDoc].displayLine;
	}
	return -1;
}

int ContractionState::DocFromDisplay(int lineDisplay) const {
	if (lineDisplay <= 0)
		return 0;
	if (lineDisplay >= linesInDisplay)
		return linesInDoc;
	if (size == 0)
		return lineDisplay;
	MakeValid();
	if (docLines) {	// Valid allocation
		return docLines[lineDisplay];
	} else {
		return 0;
	}
}

void ContractionState::Grow(int sizeNew) {
	OneLine *linesNew = new OneLine[sizeNew];
	if (linesNew) {
		int i = 0;
		for (; i < size; i++) {
			linesNew[i] = lines[i];
		}
		for (; i < sizeNew; i++) {
			linesNew[i].displayLine = i;
		}
		delete []lines;
		lines = linesNew;
		size = sizeNew;
		valid = false;
	} else {
		Platform::DebugPrintf("No memory available\n");
		// TODO: Blow up
	}
}

void ContractionState::InsertLines(int lineDoc, int lineCount) {
	if (size == 0) {
		linesInDoc += lineCount;
		linesInDisplay += lineCount;
		return;
	}
	//Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc);
	if ((linesInDoc + lineCount + 2) >= size) {
		Grow(linesInDoc + lineCount + growSize);
	}
	linesInDoc += lineCount;
	for (int i = linesInDoc; i >= lineDoc + lineCount; i--) {
		lines[i].visible = lines[i - lineCount].visible;
		lines[i].height = lines[i - lineCount].height;
		linesInDisplay += lines[i].height;
		lines[i].expanded = lines[i - lineCount].expanded;
	}
	for (int d=0;d<lineCount;d++) {
		lines[lineDoc+d].visible = true;	// Should inherit visibility from context ?
		lines[lineDoc+d].height = 1;
		lines[lineDoc+d].expanded = true;
	}
	valid = false;
}

void ContractionState::DeleteLines(int lineDoc, int lineCount) {
	if (size == 0) {
		linesInDoc -= lineCount;
		linesInDisplay -= lineCount;
		return;
	}
	int deltaDisplayed = 0;
	for (int d=0;d<lineCount;d++) {
		if (lines[lineDoc+d].visible)
			deltaDisplayed -= lines[lineDoc+d].height;
	}
	for (int i = lineDoc; i < linesInDoc-lineCount; i++) {
		if (i != 0) // Line zero is always visible
			lines[i].visible = lines[i + lineCount].visible;
		lines[i].expanded = lines[i + lineCount].expanded;
		lines[i].height = lines[i + lineCount].height;
	}
	linesInDoc -= lineCount;
	linesInDisplay += deltaDisplayed;
	valid = false;
}

bool ContractionState::GetVisible(int lineDoc) const {
	if (size == 0)
		return true;
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		return lines[lineDoc].visible;
	} else {
		return false;
	}
}

bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) {
	if (lineDocStart == 0)
		lineDocStart++;
	if (lineDocStart > lineDocEnd)
		return false;
	if (size == 0) {
		Grow(linesInDoc + growSize);
	}
	// TODO: modify docLine members to mirror displayLine
	int delta = 0;
	// Change lineDocs
	if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < linesInDoc)) {
		for (int line=lineDocStart; line <= lineDocEnd; line++) {
			if (lines[line].visible != visible) {
				delta += visible ? lines[line].height : -lines[line].height;
				lines[line].visible = visible;
			}
		}
	}
	linesInDisplay += delta;
	valid = false;
	return delta != 0;
}

bool ContractionState::GetExpanded(int lineDoc) const {
	if (size == 0)
		return true;
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		return lines[lineDoc].expanded;
	} else {
		return false;
	}
}

bool ContractionState::SetExpanded(int lineDoc, bool expanded) {
	if (size == 0) {
		if (expanded) {
			// If in completely expanded state then setting
			// one line to expanded has no effect.
			return false;
		}
		Grow(linesInDoc + growSize);
	}
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		if (lines[lineDoc].expanded != expanded) {
			lines[lineDoc].expanded = expanded;
			return true;
		}
	}
	return false;
}

int ContractionState::GetHeight(int lineDoc) const {
	if (size == 0)
		return 1;
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		return lines[lineDoc].height;
	} else {
		return 1;
	}
}

// Set the number of display lines needed for this line.
// Return true if this is a change.
bool ContractionState::SetHeight(int lineDoc, int height) {
	if (lineDoc > linesInDoc)
		return false;
	if (size == 0) {
		if (height == 1) {
			// If in completely expanded state then all lines
			// assumed to have height of one so no effect here.
			return false;
		}
		Grow(linesInDoc + growSize);
	}
	if (lines[lineDoc].height != height) {
		lines[lineDoc].height = height;
		valid = false;
		return true;
	} else {
		return false;
	}
}

void ContractionState::ShowAll() {
	delete []lines;
	lines = 0;
	size = 0;
}
<commit_msg>Set linesInDisplay to linesInDoc in ShowAll to avoid crashes when out of document line numbers used.<commit_after>// Scintilla source code edit control
/** @file ContractionState.cxx
 ** Manages visibility of lines for folding.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include "Platform.h"

#include "ContractionState.h"

OneLine::OneLine() {
	displayLine = 0;
	//docLine = 0;
	visible = true;
	height = 1;
	expanded = true;
}

ContractionState::ContractionState() {
	lines = 0;
	size = 0;
	linesInDoc = 1;
	linesInDisplay = 1;
	valid = false;
	docLines = 0;
	sizeDocLines = 0;
}

ContractionState::~ContractionState() {
	Clear();
}

void ContractionState::MakeValid() const {
	if (!valid) {
		// Could be cleverer by keeping the index of the last still valid entry
		// rather than invalidating all.
		linesInDisplay = 0;
		for (int lineInDoc=0; lineInDoc<linesInDoc; lineInDoc++) {
			lines[lineInDoc].displayLine = linesInDisplay;
			if (lines[lineInDoc].visible) {
				linesInDisplay += lines[lineInDoc].height;
			}
		}
		if (sizeDocLines < linesInDisplay) {
			delete []docLines;
			int *docLinesNew = new int[linesInDisplay + growSize];
			if (!docLinesNew) {
				docLines = 0;
				sizeDocLines = 0;
				return;
			}
			docLines = docLinesNew;
			sizeDocLines = linesInDisplay + growSize;
		}

		int lineInDisplay=0;
		for (int line=0; line<linesInDoc; line++) {
			if (lines[line].visible) {
				for (int linePiece=0; linePiece<lines[line].height; linePiece++) {
					docLines[lineInDisplay] = line;
					lineInDisplay++;
				}
			}
		}
		valid = true;
	}
}

void ContractionState::Clear() {
	delete []lines;
	lines = 0;
	size = 0;
	linesInDoc = 1;
	linesInDisplay = 1;
	delete []docLines;
	docLines = 0;
	sizeDocLines = 0;
}

int ContractionState::LinesInDoc() const {
	return linesInDoc;
}

int ContractionState::LinesDisplayed() const {
	if (size != 0) {
		MakeValid();
	}
	return linesInDisplay;
}

int ContractionState::DisplayFromDoc(int lineDoc) const {
	if (size == 0) {
		return lineDoc;
	}
	MakeValid();
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		return lines[lineDoc].displayLine;
	}
	return -1;
}

int ContractionState::DocFromDisplay(int lineDisplay) const {
	if (lineDisplay <= 0)
		return 0;
	if (lineDisplay >= linesInDisplay)
		return linesInDoc;
	if (size == 0)
		return lineDisplay;
	MakeValid();
	if (docLines) {	// Valid allocation
		return docLines[lineDisplay];
	} else {
		return 0;
	}
}

void ContractionState::Grow(int sizeNew) {
	OneLine *linesNew = new OneLine[sizeNew];
	if (linesNew) {
		int i = 0;
		for (; i < size; i++) {
			linesNew[i] = lines[i];
		}
		for (; i < sizeNew; i++) {
			linesNew[i].displayLine = i;
		}
		delete []lines;
		lines = linesNew;
		size = sizeNew;
		valid = false;
	} else {
		Platform::DebugPrintf("No memory available\n");
		// TODO: Blow up
	}
}

void ContractionState::InsertLines(int lineDoc, int lineCount) {
	if (size == 0) {
		linesInDoc += lineCount;
		linesInDisplay += lineCount;
		return;
	}
	//Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc);
	if ((linesInDoc + lineCount + 2) >= size) {
		Grow(linesInDoc + lineCount + growSize);
	}
	linesInDoc += lineCount;
	for (int i = linesInDoc; i >= lineDoc + lineCount; i--) {
		lines[i].visible = lines[i - lineCount].visible;
		lines[i].height = lines[i - lineCount].height;
		linesInDisplay += lines[i].height;
		lines[i].expanded = lines[i - lineCount].expanded;
	}
	for (int d=0;d<lineCount;d++) {
		lines[lineDoc+d].visible = true;	// Should inherit visibility from context ?
		lines[lineDoc+d].height = 1;
		lines[lineDoc+d].expanded = true;
	}
	valid = false;
}

void ContractionState::DeleteLines(int lineDoc, int lineCount) {
	if (size == 0) {
		linesInDoc -= lineCount;
		linesInDisplay -= lineCount;
		return;
	}
	int deltaDisplayed = 0;
	for (int d=0;d<lineCount;d++) {
		if (lines[lineDoc+d].visible)
			deltaDisplayed -= lines[lineDoc+d].height;
	}
	for (int i = lineDoc; i < linesInDoc-lineCount; i++) {
		if (i != 0) // Line zero is always visible
			lines[i].visible = lines[i + lineCount].visible;
		lines[i].expanded = lines[i + lineCount].expanded;
		lines[i].height = lines[i + lineCount].height;
	}
	linesInDoc -= lineCount;
	linesInDisplay += deltaDisplayed;
	valid = false;
}

bool ContractionState::GetVisible(int lineDoc) const {
	if (size == 0)
		return true;
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		return lines[lineDoc].visible;
	} else {
		return false;
	}
}

bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) {
	if (lineDocStart == 0)
		lineDocStart++;
	if (lineDocStart > lineDocEnd)
		return false;
	if (size == 0) {
		Grow(linesInDoc + growSize);
	}
	// TODO: modify docLine members to mirror displayLine
	int delta = 0;
	// Change lineDocs
	if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < linesInDoc)) {
		for (int line=lineDocStart; line <= lineDocEnd; line++) {
			if (lines[line].visible != visible) {
				delta += visible ? lines[line].height : -lines[line].height;
				lines[line].visible = visible;
			}
		}
	}
	linesInDisplay += delta;
	valid = false;
	return delta != 0;
}

bool ContractionState::GetExpanded(int lineDoc) const {
	if (size == 0)
		return true;
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		return lines[lineDoc].expanded;
	} else {
		return false;
	}
}

bool ContractionState::SetExpanded(int lineDoc, bool expanded) {
	if (size == 0) {
		if (expanded) {
			// If in completely expanded state then setting
			// one line to expanded has no effect.
			return false;
		}
		Grow(linesInDoc + growSize);
	}
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		if (lines[lineDoc].expanded != expanded) {
			lines[lineDoc].expanded = expanded;
			return true;
		}
	}
	return false;
}

int ContractionState::GetHeight(int lineDoc) const {
	if (size == 0)
		return 1;
	if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
		return lines[lineDoc].height;
	} else {
		return 1;
	}
}

// Set the number of display lines needed for this line.
// Return true if this is a change.
bool ContractionState::SetHeight(int lineDoc, int height) {
	if (lineDoc > linesInDoc)
		return false;
	if (size == 0) {
		if (height == 1) {
			// If in completely expanded state then all lines
			// assumed to have height of one so no effect here.
			return false;
		}
		Grow(linesInDoc + growSize);
	}
	if (lines[lineDoc].height != height) {
		lines[lineDoc].height = height;
		valid = false;
		return true;
	} else {
		return false;
	}
}

void ContractionState::ShowAll() {
	delete []lines;
	lines = 0;
	size = 0;

	delete []docLines;
	docLines = 0;
	sizeDocLines = 0;

	linesInDisplay = linesInDoc;
}
<|endoftext|>


<commit_before>#ifndef DATASET_H
#define DATASET_H

#include <sstream>
#include <vector>
#include <iterator>
#include <functional> // function<>
#include <assert.h>

using namespace std;

using Input = vector<double>;
using Output = vector<double>;
using LabeledPairPredicate = function<bool(const Input &, const Output &)>;

struct LabeledPair {
    Input const &input;
    Output const &output;

    LabeledPair(const Input &input, const Output &output)
        : input(input), output(output) {}

    string fmt() {
        ostringstream ss;
        for (auto x : input) {
            ss << x << " ";
        }
        ss << "=>";
        for (auto y : output) {
            ss << " " << y;
        }
        return ss.str();
    }
};

class LabeledPairsIterator : public iterator<input_iterator_tag, LabeledPair> {
private:
    vector<Input> const *inputs;
    vector<Output> const *outputs;
    size_t position;

public:
    LabeledPairsIterator(const vector<Input> &inputs,
                         const vector<Output> &outputs, size_t position = 0)
        : inputs(&inputs), outputs(&outputs), position(position){};

    bool operator==(const LabeledPairsIterator &rhs) const {
        return (inputs == rhs.inputs && outputs == rhs.outputs &&
                position == rhs.position);
    }

    bool operator!=(const LabeledPairsIterator &rhs) const {
        return !(*this == rhs);
    }

    LabeledPair operator*() const {
        LabeledPair lp(inputs->at(position), outputs->at(position));
        return lp;
    }

    LabeledPairsIterator &operator++() {
        if (position < inputs->size()) {
            ++position;
        }
        return *this;
    }

    LabeledPairsIterator &operator++(int) { return ++(*this); }
};

class LabeledSet {
private:
    size_t nSamples;
    size_t inputSize;
    size_t outputSize;
    vector<Input> inputs;
    vector<Output> outputs;

    /// load a dataset from file (the same format as FANN)
    void loadFANN(istream &in) {
        in >> nSamples >> inputSize >> outputSize;
        inputs.clear();
        outputs.clear();
        for (size_t i = 0; i < nSamples; ++i) {
            auto input = vector<double>(inputSize);
            auto output = vector<double>(outputSize);
            for (size_t j = 0; j < inputSize; ++j) {
                in >> input[j];
            }
            for (size_t j = 0; j < outputSize; ++j) {
                in >> output[j];
            }
            inputs.push_back(input);
            outputs.push_back(output);
        }
    }

    /// format dataset as FANN plain-text format
    string fmtFANN() {
        ostringstream ss;
        ss << nSamples << " " << inputSize << " " << outputSize << "\n";
        for (size_t i = 0; i < nSamples; ++i) {
            for (size_t j = 0; j < inputSize; ++j) {
                if (j) {
                    ss << " ";
                }
                ss << inputs[i][j];
            }
            ss << "\n";
            for (size_t j = 0; j < outputSize; ++j) {
                if (j) {
                    ss << " ";
                }
                ss << outputs[i][j];
            }
            ss << "\n";
        }
        return ss.str();
    }

public:
    LabeledSet() : nSamples(0), inputSize(0), outputSize(0) {}
    LabeledSet(istream &in) { loadFANN(in); }

    LabeledPairsIterator begin() const {
        return LabeledPairsIterator(inputs, outputs);
    }

    LabeledPairsIterator end() const {
        return LabeledPairsIterator(inputs, outputs, nSamples);
    }

    size_t getSetSize() const { return nSamples; }
    size_t getInputSize() const { return inputSize; }
    size_t getOutputSize() const { return outputSize; }

    LabeledSet &append(Input &input, Output &output) {
        if (nSamples != 0) {
            assert(inputSize == input.size());
            assert(outputSize == output.size());
        } else {
            inputSize = input.size();
            outputSize = output.size();
        }
        nSamples++;
        inputs.push_back(input);
        outputs.push_back(output);
        return *this;
    }

    LabeledSet &append(const Input &input, const Output &output) {
        if (nSamples != 0) {
            assert(inputSize == input.size());
            assert(outputSize == output.size());
        } else {
            inputSize = input.size();
            outputSize = output.size();
        }
        nSamples++;
        Input input_copy(input);
        Output output_copy(output);
        inputs.push_back(input_copy);
        outputs.push_back(output_copy);
        return *this;
    }

    LabeledSet &append(LabeledPair &sample) {
        return append(sample.input, sample.output);
    }

    LabeledSet &append(const LabeledPair &sample) {
        return append(sample.input, sample.output);
    }

    LabeledSet filter(LabeledPairPredicate &selectPredicate) const {
        LabeledSet newSet;
        for (auto sample : *this) {
            if (selectPredicate(sample.input, sample.output)) {
                newSet.append(sample);
            }
        }
        return newSet;
    }

    friend istream &operator>>(istream &out, LabeledSet &ls);
    friend ostream &operator<<(ostream &out, LabeledSet &ls);
};

istream &operator>>(istream &in, LabeledSet &ls) {
    ls.loadFANN(in);
    // if (newLS.isBAD(TODO)) in.setstate(ios::failbit);
    return in;
}

ostream &operator<<(ostream &out, LabeledSet &ls) {
    out << ls.fmtFANN();
    return out;
}

#endif /* DATASET_H */

<commit_msg>initializer_list for LabeledSet<commit_after>#ifndef DATASET_H
#define DATASET_H

#include <sstream>
#include <vector>
#include <iterator>
#include <functional> // function<>
#include <assert.h>
#include <initializer_list>

using namespace std;

using Input = vector<double>;
using Output = vector<double>;
using LabeledPairPredicate = function<bool(const Input &, const Output &)>;

struct LabeledPair {
    Input const &input;
    Output const &output;

    LabeledPair(const Input &input, const Output &output)
        : input(input), output(output) {}

    string fmt() {
        ostringstream ss;
        for (auto x : input) {
            ss << x << " ";
        }
        ss << "=>";
        for (auto y : output) {
            ss << " " << y;
        }
        return ss.str();
    }
};

class LabeledPairsIterator : public iterator<input_iterator_tag, LabeledPair> {
private:
    vector<Input> const *inputs;
    vector<Output> const *outputs;
    size_t position;

public:
    LabeledPairsIterator(const vector<Input> &inputs,
                         const vector<Output> &outputs, size_t position = 0)
        : inputs(&inputs), outputs(&outputs), position(position){};

    bool operator==(const LabeledPairsIterator &rhs) const {
        return (inputs == rhs.inputs && outputs == rhs.outputs &&
                position == rhs.position);
    }

    bool operator!=(const LabeledPairsIterator &rhs) const {
        return !(*this == rhs);
    }

    LabeledPair operator*() const {
        LabeledPair lp(inputs->at(position), outputs->at(position));
        return lp;
    }

    LabeledPairsIterator &operator++() {
        if (position < inputs->size()) {
            ++position;
        }
        return *this;
    }

    LabeledPairsIterator &operator++(int) { return ++(*this); }
};

class LabeledSet {
private:
    size_t nSamples;
    size_t inputSize;
    size_t outputSize;
    vector<Input> inputs;
    vector<Output> outputs;

    /// load a dataset from file (the same format as FANN)
    void loadFANN(istream &in) {
        in >> nSamples >> inputSize >> outputSize;
        inputs.clear();
        outputs.clear();
        for (size_t i = 0; i < nSamples; ++i) {
            auto input = vector<double>(inputSize);
            auto output = vector<double>(outputSize);
            for (size_t j = 0; j < inputSize; ++j) {
                in >> input[j];
            }
            for (size_t j = 0; j < outputSize; ++j) {
                in >> output[j];
            }
            inputs.push_back(input);
            outputs.push_back(output);
        }
    }

    /// format dataset as FANN plain-text format
    string fmtFANN() {
        ostringstream ss;
        ss << nSamples << " " << inputSize << " " << outputSize << "\n";
        for (size_t i = 0; i < nSamples; ++i) {
            for (size_t j = 0; j < inputSize; ++j) {
                if (j) {
                    ss << " ";
                }
                ss << inputs[i][j];
            }
            ss << "\n";
            for (size_t j = 0; j < outputSize; ++j) {
                if (j) {
                    ss << " ";
                }
                ss << outputs[i][j];
            }
            ss << "\n";
        }
        return ss.str();
    }

public:
    LabeledSet() : nSamples(0), inputSize(0), outputSize(0) {}
    LabeledSet(istream &in) { loadFANN(in); }
    LabeledSet(initializer_list<LabeledPair> samples)
        : nSamples(0), inputSize(0), outputSize(0) {
        for (LabeledPair s : samples) {
            append(s);
        }
    }

    LabeledPairsIterator begin() const {
        return LabeledPairsIterator(inputs, outputs);
    }

    LabeledPairsIterator end() const {
        return LabeledPairsIterator(inputs, outputs, nSamples);
    }

    size_t getSetSize() const { return nSamples; }
    size_t getInputSize() const { return inputSize; }
    size_t getOutputSize() const { return outputSize; }

    LabeledSet &append(Input &input, Output &output) {
        if (nSamples != 0) {
            assert(inputSize == input.size());
            assert(outputSize == output.size());
        } else {
            inputSize = input.size();
            outputSize = output.size();
        }
        nSamples++;
        inputs.push_back(input);
        outputs.push_back(output);
        return *this;
    }

    LabeledSet &append(const Input &input, const Output &output) {
        if (nSamples != 0) {
            assert(inputSize == input.size());
            assert(outputSize == output.size());
        } else {
            inputSize = input.size();
            outputSize = output.size();
        }
        nSamples++;
        Input input_copy(input);
        Output output_copy(output);
        inputs.push_back(input_copy);
        outputs.push_back(output_copy);
        return *this;
    }

    LabeledSet &append(LabeledPair &sample) {
        return append(sample.input, sample.output);
    }

    LabeledSet &append(const LabeledPair &sample) {
        return append(sample.input, sample.output);
    }

    LabeledSet filter(LabeledPairPredicate &selectPredicate) const {
        LabeledSet newSet;
        for (auto sample : *this) {
            if (selectPredicate(sample.input, sample.output)) {
                newSet.append(sample);
            }
        }
        return newSet;
    }

    friend istream &operator>>(istream &out, LabeledSet &ls);
    friend ostream &operator<<(ostream &out, LabeledSet &ls);
};

istream &operator>>(istream &in, LabeledSet &ls) {
    ls.loadFANN(in);
    // if (newLS.isBAD(TODO)) in.setstate(ios::failbit);
    return in;
}

ostream &operator<<(ostream &out, LabeledSet &ls) {
    out << ls.fmtFANN();
    return out;
}

#endif /* DATASET_H */

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkOpenGLProperty.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include <math.h>
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLProperty.h"
#ifndef VTK_IMPLEMENT_MESA_CXX
# include "vtkOpenGL.h"
#endif
#include "vtkObjectFactory.h"
#include "vtkToolkits.h"  // for VTK_USE_GL2PS

#ifdef VTK_USE_GL2PS
#include "gl2ps.h"
#include "vtkGL2PSExporter.h"
#endif // VTK_USE_GL2PS

#ifndef VTK_IMPLEMENT_MESA_CXX
vtkCxxRevisionMacro(vtkOpenGLProperty, "1.31");
vtkStandardNewMacro(vtkOpenGLProperty);
#endif

// Implement base class method.
void vtkOpenGLProperty::Render(vtkActor *vtkNotUsed(anActor),
                             vtkRenderer *vtkNotUsed(ren))
{
  int i;
  GLenum method;
  float Info[4];
  GLenum Face;
  double  color[4];

  // unbind any textures for starters
  glDisable(GL_TEXTURE_2D);

  // disable alpha testing (this may have been enabled
  // by another actor in OpenGLTexture)
  glDisable (GL_ALPHA_TEST);

  glDisable(GL_COLOR_MATERIAL);

  Face = GL_FRONT_AND_BACK;
  // turn on/off backface culling
  if ( ! this->BackfaceCulling && ! this->FrontfaceCulling)
    {
    glDisable (GL_CULL_FACE);
    }
  else if ( this->BackfaceCulling)
    {
    glCullFace (GL_BACK);
    glEnable (GL_CULL_FACE);
    }
  else //if both front & back culling on, will fall into backface culling
    { //if you really want both front and back, use the Actor's visibility flag
    glCullFace (GL_FRONT);
    glEnable (GL_CULL_FACE);
    }

  Info[3] = this->Opacity;

  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Ambient*this->AmbientColor[i]);
    }
  glMaterialfv( Face, GL_AMBIENT, Info );
  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Diffuse*this->DiffuseColor[i]);
    }
  glMaterialfv( Face, GL_DIFFUSE, Info );
  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Specular*this->SpecularColor[i]);
    }
  glMaterialfv( Face, GL_SPECULAR, Info );

  Info[0] = static_cast<float>(this->SpecularPower);
  glMaterialfv( Face, GL_SHININESS, Info );

  // set interpolation
  switch (this->Interpolation)
    {
    case VTK_FLAT:
      method = GL_FLAT;
      break;
    case VTK_GOURAUD:
    case VTK_PHONG:
      method = GL_SMOOTH;
      break;
    default:
      method = GL_SMOOTH;
      break;
    }

  glShadeModel(method);

  // The material properties set above are used if shading is
  // enabled. This color set here is used if shading is
  // disabled. Shading is disabled in the
  // vtkOpenGLPolyDataMapper::Draw() method if points or lines
  // are encountered without normals.
  this->GetColor( color );
  color[3] = this->Opacity;
  glColor4dv( color );

  // Set the PointSize
  glPointSize (this->PointSize);

  // Set the LineWidth
  glLineWidth (this->LineWidth);

  // Set pointsize and linewidth for GL2PS output.
#ifdef VTK_USE_GL2PS
  gl2psPointSize(this->PointSize*
                 vtkGL2PSExporter::GetGlobalPointSizeFactor());
  gl2psLineWidth(this->LineWidth*
                 vtkGL2PSExporter::GetGlobalLineWidthFactor());
#endif // VTK_USE_GL2PS

  // Set the LineStipple
  if (this->LineStipplePattern != 0xFFFF)
    {
    glEnable (GL_LINE_STIPPLE);
#ifdef VTK_USE_GL2PS
    gl2psEnable(GL2PS_LINE_STIPPLE);
#endif // VTK_USE_GL2PS
    glLineStipple (this->LineStippleRepeatFactor, this->LineStipplePattern);
    }
  else
    {
    glDisable (GL_LINE_STIPPLE);
#ifdef VTK_USE_GL2PS
    gl2psDisable(GL2PS_LINE_STIPPLE);
#endif // VTK_USE_GL2PS
    }
}

// Implement base class method.
void vtkOpenGLProperty::BackfaceRender(vtkActor *vtkNotUsed(anActor),
                             vtkRenderer *vtkNotUsed(ren))
{
  int i;
  float Info[4];
  GLenum Face;

  Face = GL_BACK;

  Info[3] = this->Opacity;

  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Ambient*this->AmbientColor[i]);
    }
  glMaterialfv( Face, GL_AMBIENT, Info );
  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Diffuse*this->DiffuseColor[i]);
    }
  glMaterialfv( Face, GL_DIFFUSE, Info );
  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Specular*this->SpecularColor[i]);
    }
  glMaterialfv( Face, GL_SPECULAR, Info );

  Info[0] = static_cast<float>(this->SpecularPower);
  glMaterialfv( Face, GL_SHININESS, Info );

}

//----------------------------------------------------------------------------
void vtkOpenGLProperty::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>COMP: Removed extra include of math.h which causes an ordering problem that exposes a bug on SGI MIPSpro 7.4.2m.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkOpenGLProperty.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLProperty.h"
#ifndef VTK_IMPLEMENT_MESA_CXX
# include "vtkOpenGL.h"
#endif
#include "vtkObjectFactory.h"
#include "vtkToolkits.h"  // for VTK_USE_GL2PS

#ifdef VTK_USE_GL2PS
#include "gl2ps.h"
#include "vtkGL2PSExporter.h"
#endif // VTK_USE_GL2PS

#ifndef VTK_IMPLEMENT_MESA_CXX
vtkCxxRevisionMacro(vtkOpenGLProperty, "1.32");
vtkStandardNewMacro(vtkOpenGLProperty);
#endif

// Implement base class method.
void vtkOpenGLProperty::Render(vtkActor *vtkNotUsed(anActor),
                             vtkRenderer *vtkNotUsed(ren))
{
  int i;
  GLenum method;
  float Info[4];
  GLenum Face;
  double  color[4];

  // unbind any textures for starters
  glDisable(GL_TEXTURE_2D);

  // disable alpha testing (this may have been enabled
  // by another actor in OpenGLTexture)
  glDisable (GL_ALPHA_TEST);

  glDisable(GL_COLOR_MATERIAL);

  Face = GL_FRONT_AND_BACK;
  // turn on/off backface culling
  if ( ! this->BackfaceCulling && ! this->FrontfaceCulling)
    {
    glDisable (GL_CULL_FACE);
    }
  else if ( this->BackfaceCulling)
    {
    glCullFace (GL_BACK);
    glEnable (GL_CULL_FACE);
    }
  else //if both front & back culling on, will fall into backface culling
    { //if you really want both front and back, use the Actor's visibility flag
    glCullFace (GL_FRONT);
    glEnable (GL_CULL_FACE);
    }

  Info[3] = this->Opacity;

  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Ambient*this->AmbientColor[i]);
    }
  glMaterialfv( Face, GL_AMBIENT, Info );
  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Diffuse*this->DiffuseColor[i]);
    }
  glMaterialfv( Face, GL_DIFFUSE, Info );
  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Specular*this->SpecularColor[i]);
    }
  glMaterialfv( Face, GL_SPECULAR, Info );

  Info[0] = static_cast<float>(this->SpecularPower);
  glMaterialfv( Face, GL_SHININESS, Info );

  // set interpolation
  switch (this->Interpolation)
    {
    case VTK_FLAT:
      method = GL_FLAT;
      break;
    case VTK_GOURAUD:
    case VTK_PHONG:
      method = GL_SMOOTH;
      break;
    default:
      method = GL_SMOOTH;
      break;
    }

  glShadeModel(method);

  // The material properties set above are used if shading is
  // enabled. This color set here is used if shading is
  // disabled. Shading is disabled in the
  // vtkOpenGLPolyDataMapper::Draw() method if points or lines
  // are encountered without normals.
  this->GetColor( color );
  color[3] = this->Opacity;
  glColor4dv( color );

  // Set the PointSize
  glPointSize (this->PointSize);

  // Set the LineWidth
  glLineWidth (this->LineWidth);

  // Set pointsize and linewidth for GL2PS output.
#ifdef VTK_USE_GL2PS
  gl2psPointSize(this->PointSize*
                 vtkGL2PSExporter::GetGlobalPointSizeFactor());
  gl2psLineWidth(this->LineWidth*
                 vtkGL2PSExporter::GetGlobalLineWidthFactor());
#endif // VTK_USE_GL2PS

  // Set the LineStipple
  if (this->LineStipplePattern != 0xFFFF)
    {
    glEnable (GL_LINE_STIPPLE);
#ifdef VTK_USE_GL2PS
    gl2psEnable(GL2PS_LINE_STIPPLE);
#endif // VTK_USE_GL2PS
    glLineStipple (this->LineStippleRepeatFactor, this->LineStipplePattern);
    }
  else
    {
    glDisable (GL_LINE_STIPPLE);
#ifdef VTK_USE_GL2PS
    gl2psDisable(GL2PS_LINE_STIPPLE);
#endif // VTK_USE_GL2PS
    }
}

// Implement base class method.
void vtkOpenGLProperty::BackfaceRender(vtkActor *vtkNotUsed(anActor),
                             vtkRenderer *vtkNotUsed(ren))
{
  int i;
  float Info[4];
  GLenum Face;

  Face = GL_BACK;

  Info[3] = this->Opacity;

  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Ambient*this->AmbientColor[i]);
    }
  glMaterialfv( Face, GL_AMBIENT, Info );
  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Diffuse*this->DiffuseColor[i]);
    }
  glMaterialfv( Face, GL_DIFFUSE, Info );
  for (i=0; i < 3; i++)
    {
    Info[i] = static_cast<float>(this->Specular*this->SpecularColor[i]);
    }
  glMaterialfv( Face, GL_SPECULAR, Info );

  Info[0] = static_cast<float>(this->SpecularPower);
  glMaterialfv( Face, GL_SHININESS, Info );

}

//----------------------------------------------------------------------------
void vtkOpenGLProperty::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <stdio.h>
#include <util/system.h>
#include <walletinitinterface.h>

class CWallet;

namespace interfaces {
class Chain;
}

class DummyWalletInit : public WalletInitInterface {
public:

    bool HasWalletSupport() const override {return false;}
    void AddWalletOptions() const override;
    bool ParameterInteraction() const override {return true;}
    void Construct(InitInterfaces& interfaces) const override {LogPrintf("No wallet support compiled in!\n");}
};

void DummyWalletInit::AddWalletOptions() const
{
    std::vector<std::string> opts = {"-addresstype", "-changetype", "-disablewallet", "-discardfee=<amt>", "-fallbackfee=<amt>",
        "-keypool=<n>", "-maxtxfee=<amt>", "-mintxfee=<amt>", "-paytxfee=<amt>", "-rescan", "-salvagewallet", "-spendzeroconfchange",  "-txconfirmtarget=<n>",
        "-upgradewallet", "-wallet=<path>", "-walletbroadcast", "-walletdir=<dir>", "-walletnotify=<cmd>", "-walletrbf", "-zapwallettxes=<mode>",
        "-dblogsize=<n>", "-flushwallet", "-privdb", "-walletrejectlongchains"};
    gArgs.AddHiddenArgs(opts);
}

const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();

fs::path GetWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<fs::path> ListWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<std::shared_ptr<CWallet>> GetWallets()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

namespace interfaces {

class Wallet;

std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

} // namespace interfaces
<commit_msg>dummywallet: Reformat ignored wallet options list<commit_after>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <stdio.h>
#include <util/system.h>
#include <walletinitinterface.h>

class CWallet;

namespace interfaces {
class Chain;
}

class DummyWalletInit : public WalletInitInterface {
public:

    bool HasWalletSupport() const override {return false;}
    void AddWalletOptions() const override;
    bool ParameterInteraction() const override {return true;}
    void Construct(InitInterfaces& interfaces) const override {LogPrintf("No wallet support compiled in!\n");}
};

void DummyWalletInit::AddWalletOptions() const
{
    gArgs.AddHiddenArgs({
        "-addresstype",
        "-changetype",
        "-disablewallet",
        "-discardfee=<amt>",
        "-fallbackfee=<amt>",
        "-keypool=<n>",
        "-maxtxfee=<amt>",
        "-mintxfee=<amt>",
        "-paytxfee=<amt>",
        "-rescan",
        "-salvagewallet",
        "-spendzeroconfchange",
        "-txconfirmtarget=<n>",
        "-upgradewallet",
        "-wallet=<path>",
        "-walletbroadcast",
        "-walletdir=<dir>",
        "-walletnotify=<cmd>",
        "-walletrbf",
        "-zapwallettxes=<mode>",
        "-dblogsize=<n>",
        "-flushwallet",
        "-privdb",
        "-walletrejectlongchains",
    });
}

const WalletInitInterface& g_wallet_init_interface = DummyWalletInit();

fs::path GetWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<fs::path> ListWalletDir()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::vector<std::shared_ptr<CWallet>> GetWallets()
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

namespace interfaces {

class Wallet;

std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet)
{
    throw std::logic_error("Wallet function called in non-wallet build.");
}

} // namespace interfaces
<|endoftext|>