<commit_before>/*
 *  Project:    moba-common
 *
 *  Copyright (C) 2016 Stefan Paproth <pappi-@gmx.de>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/agpl.txt>.
 *
 */

#include "version.h"
#include <sstream>
#include <vector>
#include <iomanip>

#include <boost/lexical_cast.hpp>

namespace moba {

    Version::Version(const std::string &version) {
        std::string str = version;

        if(str.length() == 0) {
            throw VersionException(
                "version-string is empty or not set"
            );
        }

        try {
            size_t p = version.rfind('-');
            if(p != std::string::npos) {
                this->ver[3] = boost::lexical_cast<int>(version.substr(p + 1));
            }
            size_t f;
            --p;
            for(int i = 2; i >= 0; --i) {
                f = version.rfind('.', p);
                if(f == std::string::npos) {
                    f = -1;
                }
                this->ver[i] = boost::lexical_cast<int>(version.substr(f + 1, p - f));
                p = f - 1;
            }
        } catch(...) {
            throw VersionException("converting failed");
        }
    }

    std::string Version::getJsonString() const {
        if(this->ver[MAJOR] == -1) {
            return "\"0.0.0.0\"";
        }
        std::stringstream ss;
        ss <<
            '"' <<
            this->ver[MAJOR] << '.' <<
            this->ver[MINOR] << '.' <<
            this->ver[BUILD] << '.' <<
            this->ver[PATCH] << '"';

        return ss.str();
    }

    std::string Version::getString() const {
        if(ver[Version::MAJOR] == -1) {
            return "0.0.0-0000";
        }

        std::stringstream o;

        o <<
            ver[Version::MAJOR] << "." << ver[Version::MINOR] << "." <<
            ver[Version::BUILD] << "-" << std::setw(4) <<
            std::setfill('0') << ver[Version::PATCH];

        return o.str();
    }

    int Version::compareMajor(const Version &v) const {
        if(this->ver[MAJOR] < v.ver[MAJOR]) {
            return -1;
        }
        if(this->ver[MAJOR] > v.ver[MAJOR]) {
            return 1;
        }
        return 0;
    }

    int Version::compareMinor(const Version &v) const {
        if(this->ver[MINOR] < v.ver[MINOR]) {
            return -1;
        } else if(this->ver[MINOR] > v.ver[MINOR]) {
            return 1;
        }
        return 0;
    }

    bool Version::operator <(const Version &v) const {
        if(this->ver[MAJOR] < v.ver[MAJOR]) {
            return true;
        }
        if(this->ver[MAJOR] > v.ver[MAJOR]) {
            return false;
        }
        if(this->ver[MINOR] < v.ver[MINOR]) {
            return true;
        }
        if(this->ver[MINOR] > v.ver[MINOR]) {
            return false;
        }
        if(this->ver[BUILD] < v.ver[BUILD]) {
            return true;
        }
        if(this->ver[BUILD] > v.ver[BUILD]) {
            return false;
        }
        if(this->ver[PATCH] < v.ver[PATCH]) {
            return true;
        }
        if(this->ver[PATCH] > v.ver[PATCH]) {
            return false;
        }
        return false;
    }

    bool Version::operator >(const Version &v) const {
        return !this->operator <(v);
    }

    bool Version::operator <=(const Version &v) const {
        return this->operator <(v) || this->operator ==(v);
    }

    bool Version::operator >=(const Version &v) const {
        return this->operator >(v) || this->operator ==(v);
    }

    std::ostream& operator<<(std::ostream &out, const Version &v) {
        out << v.getString();
        return out;
    }
}
<commit_msg>bugfix: version accepts now .<commit_after>/*
 *  Project:    moba-common
 *
 *  Copyright (C) 2016 Stefan Paproth <pappi-@gmx.de>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/agpl.txt>.
 *
 */

#include "version.h"
#include <sstream>
#include <vector>
#include <iomanip>

#include <boost/lexical_cast.hpp>

namespace moba {

    Version::Version(const std::string &version) {
        std::string str = version;

        if(str.length() == 0) {
            throw VersionException("version-string is empty or not set");
        }

        try {
            size_t p = version.rfind('-');

            if(p == std::string::npos) {
                p = version.rfind('.');
            }
            if(p == std::string::npos) {
                throw VersionException("invalid version-string given");
            }

            this->ver[3] = boost::lexical_cast<int>(version.substr(p + 1));

            size_t f;
            --p;
            for(int i = 2; i >= 0; --i) {
                f = version.rfind('.', p);
                if(f == std::string::npos) {
                    f = -1;
                }
                this->ver[i] = boost::lexical_cast<int>(version.substr(f + 1, p - f));
                p = f - 1;
            }
        } catch(...) {
            throw VersionException("converting failed");
        }
    }

    std::string Version::getJsonString() const {
        if(this->ver[MAJOR] == -1) {
            return "\"0.0.0.0\"";
        }
        std::stringstream ss;
        ss <<
            '"' <<
            this->ver[MAJOR] << '.' <<
            this->ver[MINOR] << '.' <<
            this->ver[BUILD] << '.' <<
            this->ver[PATCH] << '"';

        return ss.str();
    }

    std::string Version::getString() const {
        if(ver[Version::MAJOR] == -1) {
            return "0.0.0-0000";
        }

        std::stringstream o;

        o <<
            ver[Version::MAJOR] << "." << ver[Version::MINOR] << "." <<
            ver[Version::BUILD] << "-" << std::setw(4) <<
            std::setfill('0') << ver[Version::PATCH];

        return o.str();
    }

    int Version::compareMajor(const Version &v) const {
        if(this->ver[MAJOR] < v.ver[MAJOR]) {
            return -1;
        }
        if(this->ver[MAJOR] > v.ver[MAJOR]) {
            return 1;
        }
        return 0;
    }

    int Version::compareMinor(const Version &v) const {
        if(this->ver[MINOR] < v.ver[MINOR]) {
            return -1;
        }
        if(this->ver[MINOR] > v.ver[MINOR]) {
            return 1;
        }
        return 0;
    }

    bool Version::operator <(const Version &v) const {
        if(this->ver[MAJOR] < v.ver[MAJOR]) {
            return true;
        }
        if(this->ver[MAJOR] > v.ver[MAJOR]) {
            return false;
        }
        if(this->ver[MINOR] < v.ver[MINOR]) {
            return true;
        }
        if(this->ver[MINOR] > v.ver[MINOR]) {
            return false;
        }
        if(this->ver[BUILD] < v.ver[BUILD]) {
            return true;
        }
        if(this->ver[BUILD] > v.ver[BUILD]) {
            return false;
        }
        if(this->ver[PATCH] < v.ver[PATCH]) {
            return true;
        }
        if(this->ver[PATCH] > v.ver[PATCH]) {
            return false;
        }
        return false;
    }

    bool Version::operator >(const Version &v) const {
        return !this->operator <(v);
    }

    bool Version::operator <=(const Version &v) const {
        return this->operator <(v) || this->operator ==(v);
    }

    bool Version::operator >=(const Version &v) const {
        return this->operator >(v) || this->operator ==(v);
    }

    std::ostream& operator<<(std::ostream &out, const Version &v) {
        out << v.getString();
        return out;
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010-2012 frankee zhou (frankee.zhou at gmail dot com)
 *
 * Distributed under under the Apache License, version 2.0 (the "License").
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

#include <cetty/service/builder/ServerBuilder.h>

#include <cetty/channel/ChannelPipeline.h>
#include <cetty/channel/asio/AsioServicePool.h>
#include <cetty/bootstrap/ServerUtil.h>
#include <cetty/bootstrap/ServerBootstrap.h>
#include <cetty/config/ConfigCenter.h>
#include <cetty/logging/Logger.h>
#include <cetty/logging/LoggerHelper.h>

namespace cetty {
namespace service {
namespace builder {

using namespace cetty::channel;
using namespace cetty::channel::asio;
using namespace cetty::bootstrap;
using namespace cetty::service;
using namespace cetty::config;
using namespace cetty::logging;

ServerBuilder::ServerBuilder() {
    ConfigCenter::instance().configure(&config_);
    init();
}

ServerBuilder::ServerBuilder(int parentThreadCnt, int childThreadCnt) {
    ConfigCenter::instance().configure(&config_);
    config_.parentThreadCount = parentThreadCnt;
    config_.childThreadCount = childThreadCnt;
    init();
}

ServerBuilder::~ServerBuilder() {
}

ServerBuilder& ServerBuilder::registerServer(const std::string& name,
        const ChildInitializer& childInitializer) {
    ChannelOptions empty;
    return registerServer(name,
                          empty,
                          empty,
                          childInitializer);
}

ServerBuilder& ServerBuilder::registerServer(const std::string& name,
        const ChannelOptions& options,
        const ChannelOptions& childOptions,
        const ChildInitializer& childInitializer) {
    if (name.empty()) {
        LOG_WARN << "name is empty, can not register the server.";
        return *this;
    }

    if (!childInitializer) {
        LOG_WARN << "childInitializer is empty, can not register the server.";
        return *this;
    }

    ServerBootstrapPtr bootstrap = new ServerBootstrap(
        parentEventLoopPool_,
        childEventLoopPool_);

    bootstrap->setChildInitializer(childInitializer);

    if (!options.empty()) {
        bootstrap->setChannelOptions(options);
    }

    if (!childOptions.empty()) {
        bootstrap->setChildOptions(childOptions);
    }

    bootstraps_.insert(std::make_pair(name, bootstrap));

    return *this;
}

ServerBuilder& ServerBuilder::setOptions(const std::string& name,
        const ChannelOptions& options,
        const ChannelOptions& childOptions) {
    ServerBootstraps::const_iterator itr = bootstraps_.find(name);

    if (itr != bootstraps_.end()) {
        itr->second->setChannelOptions(options);
        itr->second->setChildOptions(childOptions);
    }
    else {
        LOG_WARN << "can not find the server: "
                 << name
                 << ", do nothing.";
    }

    return *this;
}

cetty::channel::ChannelPtr ServerBuilder::build(const std::string& name,
        int port) {
    return build(name, std::string(), port);
}

ChannelPtr ServerBuilder::build(const std::string& name,
                                const std::string& host,
                                int port) {
    ServerBootstraps::const_iterator itr = bootstraps_.find(name);

    if (itr == bootstraps_.end()) {
        LOG_WARN << "has not found such server: "
                 << name
                 << " in builder registers, should registerServer first.";

        return ChannelPtr();
    }

    return build(itr->second, host, port);
}

ChannelPtr ServerBuilder::build(const std::string& name,
                                const ChildInitializer& initializer,
                                int port) {
    return build(name,
                 ChannelOptions(),
                 ChannelOptions(),
                 initializer,
                 std::string(),
                 port);
}

ChannelPtr ServerBuilder::build(const std::string& name,
                                const ChildInitializer& initializer,
                                const std::string& host,
                                int port) {
    return build(name,
                 ChannelOptions(),
                 ChannelOptions(),
                 initializer,
                 host,
                 port);
}

cetty::channel::ChannelPtr ServerBuilder::build(const std::string& name,
        const ChannelOptions& options,
        const ChannelOptions& childOptions,
        const ChildInitializer& childInitializer,
        int port) {
    return build(name,
                 options,
                 childOptions,
                 childInitializer,
                 std::string(),
                 port);
}

ChannelPtr ServerBuilder::build(const std::string& name,
        const ChannelOptions& options,
        const ChannelOptions& childOptions,
        const ChildInitializer& childInitializer,
        const std::string& host,
        int port) {
    if (name.empty()) {
        LOG_WARN << "parameter error, empty name or invalid address.";
        return ChannelPtr();
    }

    ServerBootstrap* bootstrap = new ServerBootstrap(
        parentEventLoopPool_,
        childEventLoopPool_);

    bootstraps_.insert(std::make_pair(name, bootstrap));

    if (childOptions.empty()) {
        //bootstrap->setChildOption(ChannelOption::CO_TCP_NODELAY, true);
    }

    if (options.empty()) {
        //bootstrap->setChannelOption(ChannelOption::CO_SO_LINGER, 0);
        //bootstrap->setChannelOption(ChannelOption::CO_SO_REUSEADDR, true);
        bootstrap->setChannelOption(ChannelOption::CO_TCP_NODELAY, true);
        bootstrap->setChannelOption(ChannelOption::CO_SO_BACKLOG, 4096);
        bootstrap->setChannelOption(ChannelOption::CO_SO_REUSEADDR, true);
    }

    if (childInitializer) {
        bootstrap->setChildInitializer(childInitializer);
    }
    else {
        LOG_WARN << "childInitializer is empty, channel will not work fine.";
    }

    bootstrap->setDaemonize(config_.deamonize);

    return build(bootstrap, host, port);
}

ChannelPtr ServerBuilder::build(const ServerBootstrapPtr& bootstrap,
        const std::string& host,
        int port) {
    ChannelFuturePtr future;

    if (host.empty()) {
        future = bootstrap->bind(port);
    }
    else {
        future = bootstrap->bind(host, port);
    }

    if (future->await()->isSuccess()) {
        return future->channel();
    }
    else {
        return ChannelPtr();
    }
}

int ServerBuilder::init() {
    if (config_.deamonize) {
        ServerUtil::daemonize();
    }

    if (!parentEventLoopPool_) {
        parentEventLoopPool_ = new AsioServicePool(config_.parentThreadCount);
    }

    if (!childEventLoopPool_) {
        if (config_.childThreadCount > 0) {
            childEventLoopPool_ = new AsioServicePool(config_.childThreadCount);
        }
        else {
            childEventLoopPool_ = parentEventLoopPool_;
        }
    }

    if (config_.logger) {
        Logger::logLevel(LogLevel::parseFrom(config_.logger->level));
    }

    return 0;
}

void ServerBuilder::shutdown() {
    ServerBootstraps::iterator itr;

    for (itr = bootstraps_.begin(); itr != bootstraps_.end(); ++itr) {
        itr->second->shutdown();
    }
}

void ServerBuilder::waitingForExit() {
    ServerBootstraps::iterator itr;

    if (config_.deamonize) {
        ServerUtil::createPidFile(config_.pidfile.c_str());

        for (itr = bootstraps_.begin(); itr != bootstraps_.end(); ++itr) {
            ServerBootstrap::Channels& channels = itr->second->channels();
            ServerBootstrap::Channels::iterator channelItr = channels.begin();

            for (; channelItr != channels.end(); ++channelItr) {
                channelItr->second->closeFuture()->awaitUninterruptibly();
            }
        }
    }
    else {
        printf("Servers: \n");

        for (itr = bootstraps_.begin(); itr != bootstraps_.end(); ++itr) {
            ServerBootstrap::Channels& channels = itr->second->channels();
            ServerBootstrap::Channels::const_iterator itr = channels.begin();
            for (; itr != channels.end(); ++itr) {
                printf("    Channel ID: %d has bind to %s\n",
                       itr->first,
                       itr->second->localAddress().toString().c_str());
            }
        }

        printf("To quit server, press 'q'.\n");

        char input;

        do {
            input = getchar();

            if (input == 'q') {
                shutdown();
                break;
            }
        }
        while (true);
    }
}

ServerBuilder& ServerBuilder::buildAll() {
    std::map<std::string, ServerBuilderConfig::Server*>::const_iterator itr =
        config_.servers.begin();
    for (; itr != config_.servers.end(); ++itr) {
        const std::string& name = itr->first;
        const ServerBuilderConfig::Server* server = itr->second;

        if (name.empty()) {
            LOG_WARN << "has not config the server name, will not start the server.";
            continue;
        }

        if (!server) {
            LOG_WARN << "config the server: "
                << name
                << " has no config item, will skip it.";
        }

        if (server->port <= 0) {
            LOG_WARN << "config the server: "
                     << name
                     << " , which port is not great than 0, will skip it.";
            continue;
        }

        ServerBootstraps::const_iterator itr
            = bootstraps_.find(name);

        if (itr == bootstraps_.end()) {
            LOG_WARN << "the server: "
                     << name
                     << "has not register to the builder, should register first.";
            continue;
        }

        //TODO setting the options

        build(itr->second, server->host, server->port);
    }

    return *this;
}

}
}
}
<commit_msg>daemonize改名<commit_after>/*
 * Copyright (c) 2010-2012 frankee zhou (frankee.zhou at gmail dot com)
 *
 * Distributed under under the Apache License, version 2.0 (the "License").
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

#include <cetty/service/builder/ServerBuilder.h>

#include <cetty/channel/ChannelPipeline.h>
#include <cetty/channel/asio/AsioServicePool.h>
#include <cetty/bootstrap/ServerUtil.h>
#include <cetty/bootstrap/ServerBootstrap.h>
#include <cetty/config/ConfigCenter.h>
#include <cetty/logging/Logger.h>
#include <cetty/logging/LoggerHelper.h>

namespace cetty {
namespace service {
namespace builder {

using namespace cetty::channel;
using namespace cetty::channel::asio;
using namespace cetty::bootstrap;
using namespace cetty::service;
using namespace cetty::config;
using namespace cetty::logging;

ServerBuilder::ServerBuilder() {
    ConfigCenter::instance().configure(&config_);
    init();
}

ServerBuilder::ServerBuilder(int parentThreadCnt, int childThreadCnt) {
    ConfigCenter::instance().configure(&config_);
    config_.parentThreadCount = parentThreadCnt;
    config_.childThreadCount = childThreadCnt;
    init();
}

ServerBuilder::~ServerBuilder() {
}

ServerBuilder& ServerBuilder::registerServer(const std::string& name,
        const ChildInitializer& childInitializer) {
    ChannelOptions empty;
    return registerServer(name,
                          empty,
                          empty,
                          childInitializer);
}

ServerBuilder& ServerBuilder::registerServer(const std::string& name,
        const ChannelOptions& options,
        const ChannelOptions& childOptions,
        const ChildInitializer& childInitializer) {
    if (name.empty()) {
        LOG_WARN << "name is empty, can not register the server.";
        return *this;
    }

    if (!childInitializer) {
        LOG_WARN << "childInitializer is empty, can not register the server.";
        return *this;
    }

    ServerBootstrapPtr bootstrap = new ServerBootstrap(
        parentEventLoopPool_,
        childEventLoopPool_);

    bootstrap->setChildInitializer(childInitializer);

    if (!options.empty()) {
        bootstrap->setChannelOptions(options);
    }

    if (!childOptions.empty()) {
        bootstrap->setChildOptions(childOptions);
    }

    bootstraps_.insert(std::make_pair(name, bootstrap));

    return *this;
}

ServerBuilder& ServerBuilder::setOptions(const std::string& name,
        const ChannelOptions& options,
        const ChannelOptions& childOptions) {
    ServerBootstraps::const_iterator itr = bootstraps_.find(name);

    if (itr != bootstraps_.end()) {
        itr->second->setChannelOptions(options);
        itr->second->setChildOptions(childOptions);
    }
    else {
        LOG_WARN << "can not find the server: "
                 << name
                 << ", do nothing.";
    }

    return *this;
}

cetty::channel::ChannelPtr ServerBuilder::build(const std::string& name,
        int port) {
    return build(name, std::string(), port);
}

ChannelPtr ServerBuilder::build(const std::string& name,
                                const std::string& host,
                                int port) {
    ServerBootstraps::const_iterator itr = bootstraps_.find(name);

    if (itr == bootstraps_.end()) {
        LOG_WARN << "has not found such server: "
                 << name
                 << " in builder registers, should registerServer first.";

        return ChannelPtr();
    }

    return build(itr->second, host, port);
}

ChannelPtr ServerBuilder::build(const std::string& name,
                                const ChildInitializer& initializer,
                                int port) {
    return build(name,
                 ChannelOptions(),
                 ChannelOptions(),
                 initializer,
                 std::string(),
                 port);
}

ChannelPtr ServerBuilder::build(const std::string& name,
                                const ChildInitializer& initializer,
                                const std::string& host,
                                int port) {
    return build(name,
                 ChannelOptions(),
                 ChannelOptions(),
                 initializer,
                 host,
                 port);
}

cetty::channel::ChannelPtr ServerBuilder::build(const std::string& name,
        const ChannelOptions& options,
        const ChannelOptions& childOptions,
        const ChildInitializer& childInitializer,
        int port) {
    return build(name,
                 options,
                 childOptions,
                 childInitializer,
                 std::string(),
                 port);
}

ChannelPtr ServerBuilder::build(const std::string& name,
        const ChannelOptions& options,
        const ChannelOptions& childOptions,
        const ChildInitializer& childInitializer,
        const std::string& host,
        int port) {
    if (name.empty()) {
        LOG_WARN << "parameter error, empty name or invalid address.";
        return ChannelPtr();
    }

    ServerBootstrap* bootstrap = new ServerBootstrap(
        parentEventLoopPool_,
        childEventLoopPool_);

    bootstraps_.insert(std::make_pair(name, bootstrap));

    if (childOptions.empty()) {
        //bootstrap->setChildOption(ChannelOption::CO_TCP_NODELAY, true);
    }

    if (options.empty()) {
        //bootstrap->setChannelOption(ChannelOption::CO_SO_LINGER, 0);
        //bootstrap->setChannelOption(ChannelOption::CO_SO_REUSEADDR, true);
        bootstrap->setChannelOption(ChannelOption::CO_TCP_NODELAY, true);
        bootstrap->setChannelOption(ChannelOption::CO_SO_BACKLOG, 4096);
        bootstrap->setChannelOption(ChannelOption::CO_SO_REUSEADDR, true);
    }

    if (childInitializer) {
        bootstrap->setChildInitializer(childInitializer);
    }
    else {
        LOG_WARN << "childInitializer is empty, channel will not work fine.";
    }

    bootstrap->setDaemonize(config_.daemonize);

    return build(bootstrap, host, port);
}

ChannelPtr ServerBuilder::build(const ServerBootstrapPtr& bootstrap,
        const std::string& host,
        int port) {
    ChannelFuturePtr future;

    if (host.empty()) {
        future = bootstrap->bind(port);
    }
    else {
        future = bootstrap->bind(host, port);
    }

    if (future->await()->isSuccess()) {
        return future->channel();
    }
    else {
        return ChannelPtr();
    }
}

int ServerBuilder::init() {
    if (config_.daemonize) {
        ServerUtil::daemonize();
    }

    if (!parentEventLoopPool_) {
        parentEventLoopPool_ = new AsioServicePool(config_.parentThreadCount);
    }

    if (!childEventLoopPool_) {
        if (config_.childThreadCount > 0) {
            childEventLoopPool_ = new AsioServicePool(config_.childThreadCount);
        }
        else {
            childEventLoopPool_ = parentEventLoopPool_;
        }
    }

    if (config_.logger) {
        Logger::logLevel(LogLevel::parseFrom(config_.logger->level));
    }

    return 0;
}

void ServerBuilder::shutdown() {
    ServerBootstraps::iterator itr;

    for (itr = bootstraps_.begin(); itr != bootstraps_.end(); ++itr) {
        itr->second->shutdown();
    }
}

void ServerBuilder::waitingForExit() {
    ServerBootstraps::iterator itr;

    if (config_.daemonize) {
        ServerUtil::createPidFile(config_.pidfile.c_str());

        for (itr = bootstraps_.begin(); itr != bootstraps_.end(); ++itr) {
            ServerBootstrap::Channels& channels = itr->second->channels();
            ServerBootstrap::Channels::iterator channelItr = channels.begin();

            for (; channelItr != channels.end(); ++channelItr) {
                channelItr->second->closeFuture()->awaitUninterruptibly();
            }
        }
    }
    else {
        printf("Servers: \n");

        for (itr = bootstraps_.begin(); itr != bootstraps_.end(); ++itr) {
            ServerBootstrap::Channels& channels = itr->second->channels();
            ServerBootstrap::Channels::const_iterator itr = channels.begin();
            for (; itr != channels.end(); ++itr) {
                printf("    Channel ID: %d has bind to %s\n",
                       itr->first,
                       itr->second->localAddress().toString().c_str());
            }
        }

        printf("To quit server, press 'q'.\n");

        char input;

        do {
            input = getchar();

            if (input == 'q') {
                shutdown();
                break;
            }
        }
        while (true);
    }
}

ServerBuilder& ServerBuilder::buildAll() {
    std::map<std::string, ServerBuilderConfig::Server*>::const_iterator itr =
        config_.servers.begin();
    for (; itr != config_.servers.end(); ++itr) {
        const std::string& name = itr->first;
        const ServerBuilderConfig::Server* server = itr->second;

        if (name.empty()) {
            LOG_WARN << "has not config the server name, will not start the server.";
            continue;
        }

        if (!server) {
            LOG_WARN << "config the server: "
                << name
                << " has no config item, will skip it.";
        }

        if (server->port <= 0) {
            LOG_WARN << "config the server: "
                     << name
                     << " , which port is not great than 0, will skip it.";
            continue;
        }

        ServerBootstraps::const_iterator itr
            = bootstraps_.find(name);

        if (itr == bootstraps_.end()) {
            LOG_WARN << "the server: "
                     << name
                     << "has not register to the builder, should register first.";
            continue;
        }

        //TODO setting the options

        build(itr->second, server->host, server->port);
    }

    return *this;
}

}
}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The tekcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both tekcoind and tekcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("tekcoin");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-TEK"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "f96a5a"
#    define GIT_COMMIT_DATE "$Format:%cD"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE "May 7, 2014"
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<commit_msg>Change version suffix<commit_after>// Copyright (c) 2012 The tekcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both tekcoind and tekcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("tekcoin");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-noise23"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "f96a5a"
#    define GIT_COMMIT_DATE "$Format:%cD"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE "May 7, 2014"
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<|endoftext|>


<commit_before>//===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetAsmBackend.h"
#include "ARM.h"
#include "ARMFixupKinds.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFormat.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegistry.h"
using namespace llvm;

namespace {
class ARMAsmBackend : public TargetAsmBackend {
public:
  ARMAsmBackend(const Target &T) : TargetAsmBackend() {}

  bool MayNeedRelaxation(const MCInst &Inst) const;

  void RelaxInstruction(const MCInst &Inst, MCInst &Res) const;

  bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;

  unsigned getPointerSize() const {
    return 4;
  }

protected:
  static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
    switch (Kind) {
    default:
      llvm_unreachable("Unknown fixup kind!");
    case FK_Data_4:
    case ARM::fixup_arm_movt_hi16:
    case ARM::fixup_arm_movw_lo16:
      return Value;
    case ARM::fixup_arm_pcrel_12: {
      bool isAdd = true;
      // ARM PC-relative values are offset by 8.
      Value -= 8;
      if ((int64_t)Value < 0) {
        Value = -Value;
        isAdd = false;
      }
      assert ((Value < 4096) && "Out of range pc-relative fixup value!");
      Value |= isAdd << 23;
      return Value;
    }
    case ARM::fixup_arm_branch:
      // These values don't encode the low two bits since they're always zero.
      // Offset by 8 just as above.
      return (Value - 8) >> 2;
    case ARM::fixup_arm_vfp_pcrel_10: {
      // Offset by 8 just as above.
      Value = Value - 8;
      bool isAdd = true;
      if ((int64_t)Value < 0) {
        Value = -Value;
        isAdd = false;
      }
      // These values don't encode the low two bits since they're always zero.
      Value >>= 2;
      assert ((Value < 256) && "Out of range pc-relative fixup value!");
      Value |= isAdd << 23;
      return Value;
    }
    }
  }
};
} // end anonymous namespace

bool ARMAsmBackend::MayNeedRelaxation(const MCInst &Inst) const {
  // FIXME: Thumb targets, different move constant targets..
  return false;
}

void ARMAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
  assert(0 && "ARMAsmBackend::RelaxInstruction() unimplemented");
  return;
}

bool ARMAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
  // FIXME: Zero fill for now. That's not right, but at least will get the
  // section size right.
  for (uint64_t i = 0; i != Count; ++i)
    OW->Write8(0);
  return true;
}

namespace {
// FIXME: This should be in a separate file.
// ELF is an ELF of course...
class ELFARMAsmBackend : public ARMAsmBackend {
  MCELFObjectFormat Format;

public:
  Triple::OSType OSType;
  ELFARMAsmBackend(const Target &T, Triple::OSType _OSType)
    : ARMAsmBackend(T), OSType(_OSType) {
    HasScatteredSymbols = true;
  }

  virtual const MCObjectFormat &getObjectFormat() const {
    return Format;
  }

  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                  uint64_t Value) const;

  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
    return createELFObjectWriter(OS, /*Is64Bit=*/false,
                                 OSType, ELF::EM_ARM,
                                 /*IsLittleEndian=*/true,
                                 /*HasRelocationAddend=*/false);
  }
};

// Fixme: can we raise this to share code between Darwin and ELF?
void ELFARMAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                                  uint64_t Value) const {
  uint32_t Mask = 0;
  // Fixme: 2 for Thumb
  unsigned NumBytes = 4;
  Value = adjustFixupValue(Fixup.getKind(), Value);

  switch (Fixup.getKind()) {
  default: assert(0 && "Unsupported Fixup kind"); break;
  case ARM::fixup_arm_branch: {
    unsigned Lo24 = Value & 0xFFFFFF;
    Mask = ~(0xFFFFFF);
    Value = Lo24;
  }; break;
  case ARM::fixup_arm_movt_hi16:
  case ARM::fixup_arm_movw_lo16: {
    unsigned Hi4 = (Value & 0xF000) >> 12;
    unsigned Lo12 = Value & 0x0FFF;
    // inst{19-16} = Hi4;
    // inst{11-0} = Lo12;
    Value = (Hi4 << 16) | (Lo12);
    Mask = ~(0xF0FFF);
  }; break;
  }

  assert((Fixup.getOffset() % NumBytes == 0)
         && "Offset mod NumBytes is nonzero!");
  // For each byte of the fragment that the fixup touches, mask in the
  // bits from the fixup value.
  // The Value has been "split up" into the appropriate bitfields above.
  // Fixme: how to share code with the .td generated code?
  for (unsigned i = 0; i != NumBytes; ++i) {
    DF.getContents()[Fixup.getOffset() + i] &= uint8_t(Mask >> (i * 8));
    DF.getContents()[Fixup.getOffset() + i] |= uint8_t(Value >> (i * 8));
  }
}

namespace {
// FIXME: This should be in a separate file.
class DarwinARMAsmBackend : public ARMAsmBackend {
  MCMachOObjectFormat Format;
public:
  DarwinARMAsmBackend(const Target &T) : ARMAsmBackend(T) {
    HasScatteredSymbols = true;
  }

  virtual const MCObjectFormat &getObjectFormat() const {
    return Format;
  }

  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                  uint64_t Value) const;

  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
    // FIXME: Subtarget info should be derived. Force v7 for now.
    return createMachObjectWriter(OS, /*Is64Bit=*/false,
                                  object::mach::CTM_ARM,
                                  object::mach::CSARM_V7,
                                  /*IsLittleEndian=*/true);
  }

  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
    return false;
  }
};
} // end anonymous namespace

static unsigned getFixupKindNumBytes(unsigned Kind) {
  switch (Kind) {
  default: llvm_unreachable("Unknown fixup kind!");
  case FK_Data_4: return 4;
  case ARM::fixup_arm_pcrel_12: return 3;
  case ARM::fixup_arm_vfp_pcrel_10: return 3;
  case ARM::fixup_arm_branch: return 3;
  }
}

void DarwinARMAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                                     uint64_t Value) const {
  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
  Value = adjustFixupValue(Fixup.getKind(), Value);

  assert(Fixup.getOffset() + NumBytes <= DF.getContents().size() &&
         "Invalid fixup offset!");
  // For each byte of the fragment that the fixup touches, mask in the
  // bits from the fixup value.
  for (unsigned i = 0; i != NumBytes; ++i)
    DF.getContents()[Fixup.getOffset() + i] |= uint8_t(Value >> (i * 8));
}
} // end anonymous namespace

TargetAsmBackend *llvm::createARMAsmBackend(const Target &T,
                                            const std::string &TT) {
  switch (Triple(TT).getOS()) {
  case Triple::Darwin:
    return new DarwinARMAsmBackend(T);
  case Triple::MinGW32:
  case Triple::Cygwin:
  case Triple::Win32:
    assert(0 && "Windows not supported on ARM");
  default:
    return new ELFARMAsmBackend(T, Triple(TT).getOS());
  }
}
<commit_msg>kill trailing space<commit_after>//===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetAsmBackend.h"
#include "ARM.h"
#include "ARMFixupKinds.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFormat.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegistry.h"
using namespace llvm;

namespace {
class ARMAsmBackend : public TargetAsmBackend {
public:
  ARMAsmBackend(const Target &T) : TargetAsmBackend() {}

  bool MayNeedRelaxation(const MCInst &Inst) const;

  void RelaxInstruction(const MCInst &Inst, MCInst &Res) const;

  bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;

  unsigned getPointerSize() const {
    return 4;
  }

protected:
  static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
    switch (Kind) {
    default:
      llvm_unreachable("Unknown fixup kind!");
    case FK_Data_4:
    case ARM::fixup_arm_movt_hi16:
    case ARM::fixup_arm_movw_lo16:
      return Value;
    case ARM::fixup_arm_pcrel_12: {
      bool isAdd = true;
      // ARM PC-relative values are offset by 8.
      Value -= 8;
      if ((int64_t)Value < 0) {
        Value = -Value;
        isAdd = false;
      }
      assert ((Value < 4096) && "Out of range pc-relative fixup value!");
      Value |= isAdd << 23;
      return Value;
    }
    case ARM::fixup_arm_branch:
      // These values don't encode the low two bits since they're always zero.
      // Offset by 8 just as above.
      return (Value - 8) >> 2;
    case ARM::fixup_arm_vfp_pcrel_10: {
      // Offset by 8 just as above.
      Value = Value - 8;
      bool isAdd = true;
      if ((int64_t)Value < 0) {
        Value = -Value;
        isAdd = false;
      }
      // These values don't encode the low two bits since they're always zero.
      Value >>= 2;
      assert ((Value < 256) && "Out of range pc-relative fixup value!");
      Value |= isAdd << 23;
      return Value;
    }
    }
  }
};
} // end anonymous namespace

bool ARMAsmBackend::MayNeedRelaxation(const MCInst &Inst) const {
  // FIXME: Thumb targets, different move constant targets..
  return false;
}

void ARMAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
  assert(0 && "ARMAsmBackend::RelaxInstruction() unimplemented");
  return;
}

bool ARMAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
  // FIXME: Zero fill for now. That's not right, but at least will get the
  // section size right.
  for (uint64_t i = 0; i != Count; ++i)
    OW->Write8(0);
  return true;
}

namespace {
// FIXME: This should be in a separate file.
// ELF is an ELF of course...
class ELFARMAsmBackend : public ARMAsmBackend {
  MCELFObjectFormat Format;

public:
  Triple::OSType OSType;
  ELFARMAsmBackend(const Target &T, Triple::OSType _OSType)
    : ARMAsmBackend(T), OSType(_OSType) {
    HasScatteredSymbols = true;
  }

  virtual const MCObjectFormat &getObjectFormat() const {
    return Format;
  }

  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                  uint64_t Value) const;

  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
    return createELFObjectWriter(OS, /*Is64Bit=*/false,
                                 OSType, ELF::EM_ARM,
                                 /*IsLittleEndian=*/true,
                                 /*HasRelocationAddend=*/false);
  }
};

// Fixme: can we raise this to share code between Darwin and ELF?
void ELFARMAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                                  uint64_t Value) const {
  uint32_t Mask = 0;
  // Fixme: 2 for Thumb
  unsigned NumBytes = 4;
  Value = adjustFixupValue(Fixup.getKind(), Value);

  switch (Fixup.getKind()) {
  default: assert(0 && "Unsupported Fixup kind"); break;
  case ARM::fixup_arm_branch: {
    unsigned Lo24 = Value & 0xFFFFFF;
    Mask = ~(0xFFFFFF);
    Value = Lo24;
  }; break;
  case ARM::fixup_arm_movt_hi16:
  case ARM::fixup_arm_movw_lo16: {
    unsigned Hi4 = (Value & 0xF000) >> 12;
    unsigned Lo12 = Value & 0x0FFF;
    // inst{19-16} = Hi4;
    // inst{11-0} = Lo12;
    Value = (Hi4 << 16) | (Lo12);
    Mask = ~(0xF0FFF);
  }; break;
  }

  assert((Fixup.getOffset() % NumBytes == 0)
         && "Offset mod NumBytes is nonzero!");
  // For each byte of the fragment that the fixup touches, mask in the
  // bits from the fixup value.
  // The Value has been "split up" into the appropriate bitfields above.
  // Fixme: how to share code with the .td generated code?
  for (unsigned i = 0; i != NumBytes; ++i) {
    DF.getContents()[Fixup.getOffset() + i] &= uint8_t(Mask >> (i * 8));
    DF.getContents()[Fixup.getOffset() + i] |= uint8_t(Value >> (i * 8));
  }
}

namespace {
// FIXME: This should be in a separate file.
class DarwinARMAsmBackend : public ARMAsmBackend {
  MCMachOObjectFormat Format;
public:
  DarwinARMAsmBackend(const Target &T) : ARMAsmBackend(T) {
    HasScatteredSymbols = true;
  }

  virtual const MCObjectFormat &getObjectFormat() const {
    return Format;
  }

  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                  uint64_t Value) const;

  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
    // FIXME: Subtarget info should be derived. Force v7 for now.
    return createMachObjectWriter(OS, /*Is64Bit=*/false,
                                  object::mach::CTM_ARM,
                                  object::mach::CSARM_V7,
                                  /*IsLittleEndian=*/true);
  }

  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
    return false;
  }
};
} // end anonymous namespace

static unsigned getFixupKindNumBytes(unsigned Kind) {
  switch (Kind) {
  default: llvm_unreachable("Unknown fixup kind!");
  case FK_Data_4: return 4;
  case ARM::fixup_arm_pcrel_12: return 3;
  case ARM::fixup_arm_vfp_pcrel_10: return 3;
  case ARM::fixup_arm_branch: return 3;
  }
}

void DarwinARMAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                                     uint64_t Value) const {
  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
  Value = adjustFixupValue(Fixup.getKind(), Value);

  assert(Fixup.getOffset() + NumBytes <= DF.getContents().size() &&
         "Invalid fixup offset!");
  // For each byte of the fragment that the fixup touches, mask in the
  // bits from the fixup value.
  for (unsigned i = 0; i != NumBytes; ++i)
    DF.getContents()[Fixup.getOffset() + i] |= uint8_t(Value >> (i * 8));
}
} // end anonymous namespace

TargetAsmBackend *llvm::createARMAsmBackend(const Target &T,
                                            const std::string &TT) {
  switch (Triple(TT).getOS()) {
  case Triple::Darwin:
    return new DarwinARMAsmBackend(T);
  case Triple::MinGW32:
  case Triple::Cygwin:
  case Triple::Win32:
    assert(0 && "Windows not supported on ARM");
  default:
    return new ELFARMAsmBackend(T, Triple(TT).getOS());
  }
}
<|endoftext|>


<commit_before>//===-- GlobalDCE.cpp - DCE unreachable internal functions ----------------===//
//
// This transform is designed to eliminate unreachable internal globals
// FIXME: GlobalDCE should update the callgraph, not destroy it!
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Analysis/CallGraph.h"
#include "Support/DepthFirstIterator.h"
#include "Support/StatisticReporter.h"

static Statistic<> NumFunctions("globaldce\t- Number of functions removed");
static Statistic<> NumVariables("globaldce\t- Number of global variables removed");

static bool RemoveUnreachableFunctions(Module &M, CallGraph &CallGraph) {
  // Calculate which functions are reachable from the external functions in the
  // call graph.
  //
  std::set<CallGraphNode*> ReachableNodes(df_begin(&CallGraph),
                                          df_end(&CallGraph));

  // Loop over the functions in the module twice.  The first time is used to
  // drop references that functions have to each other before they are deleted.
  // The second pass removes the functions that need to be removed.
  //
  std::vector<CallGraphNode*> FunctionsToDelete;   // Track unused functions
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    CallGraphNode *N = CallGraph[I];

    if (!ReachableNodes.count(N)) {              // Not reachable??
      I->dropAllReferences();
      N->removeAllCalledFunctions();
      FunctionsToDelete.push_back(N);
      ++NumFunctions;
    }
  }

  // Nothing to do if no unreachable functions have been found...
  if (FunctionsToDelete.empty()) return false;

  // Unreachables functions have been found and should have no references to
  // them, delete them now.
  //
  for (std::vector<CallGraphNode*>::iterator I = FunctionsToDelete.begin(),
	 E = FunctionsToDelete.end(); I != E; ++I)
    delete CallGraph.removeFunctionFromModule(*I);

  return true;
}

static bool RemoveUnreachableGlobalVariables(Module &M) {
  bool Changed = false;
  // Eliminate all global variables that are unused, and that are internal, or
  // do not have an initializer.
  //
  for (Module::giterator I = M.gbegin(); I != M.gend(); )
    if (!I->use_empty() || (I->hasExternalLinkage() && I->hasInitializer()))
      ++I;                     // Cannot eliminate global variable
    else {
      I = M.getGlobalList().erase(I);
      ++NumVariables;
      Changed = true;
    }
  return Changed;
}

namespace {
  struct GlobalDCE : public Pass {
    // run - Do the GlobalDCE pass on the specified module, optionally updating
    // the specified callgraph to reflect the changes.
    //
    bool run(Module &M) {
      return RemoveUnreachableFunctions(M, getAnalysis<CallGraph>()) |
             RemoveUnreachableGlobalVariables(M);
    }

    // getAnalysisUsage - This function works on the call graph of a module.
    // It is capable of updating the call graph to reflect the new state of the
    // module.
    //
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<CallGraph>();
    }
  };
  RegisterOpt<GlobalDCE> X("globaldce", "Dead Global Elimination");
}

Pass *createGlobalDCEPass() { return new GlobalDCE(); }
<commit_msg>  - Made GlobalDCE worklist driven, making it more successful.  Now can handle     cases like: test/Regression/Transforms/GlobalDCE/2002-08-17-WorkListTest.ll<commit_after>//===-- GlobalDCE.cpp - DCE unreachable internal functions ----------------===//
//
// This transform is designed to eliminate unreachable internal globals
// FIXME: GlobalDCE should update the callgraph, not destroy it!
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Analysis/CallGraph.h"
#include "Support/DepthFirstIterator.h"
#include "Support/StatisticReporter.h"
#include <algorithm>

static Statistic<> NumFunctions("globaldce\t- Number of functions removed");
static Statistic<> NumVariables("globaldce\t- Number of global variables removed");
static Statistic<> NumCPRs("globaldce\t- Number of const pointer refs removed");
static Statistic<> NumConsts("globaldce\t- Number of init constants removed");

static bool RemoveUnreachableFunctions(Module &M, CallGraph &CallGraph) {
  // Calculate which functions are reachable from the external functions in the
  // call graph.
  //
  std::set<CallGraphNode*> ReachableNodes(df_begin(&CallGraph),
                                          df_end(&CallGraph));

  // Loop over the functions in the module twice.  The first time is used to
  // drop references that functions have to each other before they are deleted.
  // The second pass removes the functions that need to be removed.
  //
  std::vector<CallGraphNode*> FunctionsToDelete;   // Track unused functions
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    CallGraphNode *N = CallGraph[I];

    if (!ReachableNodes.count(N)) {              // Not reachable??
      I->dropAllReferences();
      N->removeAllCalledFunctions();
      FunctionsToDelete.push_back(N);
      ++NumFunctions;
    }
  }

  // Nothing to do if no unreachable functions have been found...
  if (FunctionsToDelete.empty()) return false;

  // Unreachables functions have been found and should have no references to
  // them, delete them now.
  //
  for (std::vector<CallGraphNode*>::iterator I = FunctionsToDelete.begin(),
	 E = FunctionsToDelete.end(); I != E; ++I)
    delete CallGraph.removeFunctionFromModule(*I);

  return true;
}

namespace {
  struct GlobalDCE : public Pass {
    // run - Do the GlobalDCE pass on the specified module, optionally updating
    // the specified callgraph to reflect the changes.
    //
    bool run(Module &M) {
      return RemoveUnreachableFunctions(M, getAnalysis<CallGraph>()) |
             RemoveUnreachableGlobalVariables(M);
    }

    // getAnalysisUsage - This function works on the call graph of a module.
    // It is capable of updating the call graph to reflect the new state of the
    // module.
    //
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<CallGraph>();
    }

  private:
    std::vector<GlobalValue*> WorkList;

    inline bool RemoveIfDead(GlobalValue *GV);
    void DestroyInitializer(Constant *C);

    bool RemoveUnreachableGlobalVariables(Module &M);
    bool RemoveUnusedConstantPointerRef(GlobalValue &GV);
    bool SafeToDestroyConstant(Constant *C);
  };
  RegisterOpt<GlobalDCE> X("globaldce", "Dead Global Elimination");
}

Pass *createGlobalDCEPass() { return new GlobalDCE(); }

// RemoveIfDead - If this global value is dead, remove it from the current
// module and return true.
//
bool GlobalDCE::RemoveIfDead(GlobalValue *GV) {
  // If there is only one use of the global value, it might be a
  // ConstantPointerRef... which means that this global might actually be
  // dead.
  if (GV->use_size() == 1)
    RemoveUnusedConstantPointerRef(*GV);

  if (!GV->use_empty()) return false;

  if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
    // Eliminate all global variables that are unused, and that are internal, or
    // do not have an initializer.
    //
    if (!GVar->hasExternalLinkage() || !GVar->hasInitializer()) {
      Constant *Init = GVar->hasInitializer() ? GVar->getInitializer() : 0;
      GV->getParent()->getGlobalList().erase(GVar);
      ++NumVariables;

      // If there was an initializer for the global variable, try to destroy it
      // now.
      if (Init) DestroyInitializer(Init);

      // If the global variable is still on the worklist, remove it now.
      std::vector<GlobalValue*>::iterator I = std::find(WorkList.begin(),
                                                        WorkList.end(), GV);
      while (I != WorkList.end())
        I = std::find(WorkList.erase(I), WorkList.end(), GV);

      return true;
    }
  } else {
    Function *F = cast<Function>(GV);
    // FIXME: TODO

  }
  return false;
}

// DestroyInitializer - A global variable was just destroyed and C is its
// initializer. If we can, destroy C and all of the constants it refers to.
//
void GlobalDCE::DestroyInitializer(Constant *C) {
  // Cannot destroy constants still being used, and cannot destroy primitive
  // types.
  if (!C->use_empty() || C->getType()->isPrimitiveType()) return;

  // If this is a CPR, the global value referred to may be dead now!  Add it to
  // the worklist.
  //
  if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
    WorkList.push_back(CPR->getValue());
    C->destroyConstant();
    ++NumCPRs;
  } else {
    bool DestroyContents = true;

    // As an optimization to the GlobalDCE algorithm, do attempt to destroy the
    // contents of an array of primitive types, because we know that this will
    // never succeed, and there could be a lot of them.
    //
    if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
      if (CA->getType()->getElementType()->isPrimitiveType())
        DestroyContents = false;    // Nothing we can do with the subcontents

    // All other constants refer to other constants.  Destroy them if possible
    // as well.
    //
    std::vector<Value*> SubConstants;
    if (DestroyContents) SubConstants.insert(SubConstants.end(),
                                             C->op_begin(), C->op_end());

    // Destroy the actual constant...
    C->destroyConstant();
    ++NumConsts;

    if (DestroyContents) {
      // Remove duplicates from SubConstants, so that we do not call
      // DestroyInitializer on the same constant twice (the first call might
      // delete it, so this would be bad)
      //
      std::sort(SubConstants.begin(), SubConstants.end());
      SubConstants.erase(std::unique(SubConstants.begin(), SubConstants.end()),
                         SubConstants.end());

      // Loop over the subconstants, destroying them as well.
      for (unsigned i = 0, e = SubConstants.size(); i != e; ++i)
        DestroyInitializer(cast<Constant>(SubConstants[i]));
    }
  }
}

bool GlobalDCE::RemoveUnreachableGlobalVariables(Module &M) {
  bool Changed = false;
  WorkList.reserve(M.gsize());

  // Insert all of the globals into the WorkList, making sure to run
  // RemoveUnusedConstantPointerRef at least once on all globals...
  //
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    Changed |= RemoveUnusedConstantPointerRef(*I);
    WorkList.push_back(I);
  }
  for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
    Changed |= RemoveUnusedConstantPointerRef(*I);
    WorkList.push_back(I);
  }

  // Loop over the worklist, deleting global objects that we can.  Whenever we
  // delete something that might make something else dead, it gets added to the
  // worklist.
  //
  while (!WorkList.empty()) {
    GlobalValue *GV = WorkList.back();
    WorkList.pop_back();

    Changed |= RemoveIfDead(GV);
  }

  // Make sure that all memory is free'd from the worklist...
  std::vector<GlobalValue*>().swap(WorkList);
  return Changed;
}

// RemoveUnusedConstantPointerRef - Loop over all of the uses of the specified
// GlobalValue, looking for the constant pointer ref that may be pointing to it.
// If found, check to see if the constant pointer ref is safe to destroy, and if
// so, nuke it.  This will reduce the reference count on the global value, which
// might make it deader.
//
bool GlobalDCE::RemoveUnusedConstantPointerRef(GlobalValue &GV) {
  for (Value::use_iterator I = GV.use_begin(), E = GV.use_end(); I != E; ++I)
    if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(*I))
      if (SafeToDestroyConstant(CPR)) {  // Only if unreferenced...
        CPR->destroyConstant();
        ++NumCPRs;
        return true;
      }

  return false;
}

// SafeToDestroyConstant - It is safe to destroy a constant iff it is only used
// by constants itself.  Note that constants cannot be cyclic, so this test is
// pretty easy to implement recursively.
//
bool GlobalDCE::SafeToDestroyConstant(Constant *C) {
  for (Value::use_iterator I = C->use_begin(), E = C->use_end(); I != E; ++I)
    if (Constant *User = dyn_cast<Constant>(*I)) {
      if (!SafeToDestroyConstant(User)) return false;
    } else {
      return false;
    }

  return true;
}
<|endoftext|>


<commit_before>#ifndef resplunk_util_Cloneable_HeaderPlusPlus
#define resplunk_util_Cloneable_HeaderPlusPlus

#include <memory>
#include <type_traits>

namespace resplunk
{
	namespace util
	{
		struct Cloneable
		{
			Cloneable() = default;
			Cloneable(Cloneable const &) = default;
			Cloneable &operator=(Cloneable const &) = delete;
			Cloneable(Cloneable &&) = default;
			Cloneable &operator=(Cloneable &&) = delete;
			virtual ~Cloneable() = default;

			template<template<typename...> typename Wrapper = std::unique_ptr, typename... Args>
			static auto Clone(Cloneable const &c) noexcept
			-> Wrapper<Cloneable, Args...>
			{
				return Wrapper<Cloneable, Args...>{c.clone()};
			}

		private:
			template<typename DerivedT>
			friend struct CloneImplementor;
			virtual Cloneable *clone() const noexcept = 0;
		};
		template<typename DerivedT>
		struct CloneImplementor
		: virtual Cloneable
		{
			using Cloneable_t = DerivedT;
			using CloneImplementor_t = CloneImplementor;

			template<template<typename...> typename Wrapper = std::unique_ptr, typename... Args>
			static auto Clone(Cloneable_t const &ct) noexcept
			-> Wrapper<Cloneable_t, Args...>
			{
				Cloneable const &c = ct;
				return Wrapper<Cloneable_t, Args...>{dynamic_cast<Cloneable_t *>(c.clone())};
			}

		private:
			CloneImplementor() = default;
			friend Cloneable_t;
		};
	}
}

#endif
<commit_msg>More serialization work<commit_after>#ifndef resplunk_util_Cloneable_HeaderPlusPlus
#define resplunk_util_Cloneable_HeaderPlusPlus

#include <memory>
#include <type_traits>

namespace resplunk
{
	namespace util
	{
		struct Cloneable
		{
			Cloneable() = default;
			Cloneable(Cloneable const &) = default;
			Cloneable &operator=(Cloneable const &) = delete;
			Cloneable(Cloneable &&) = default;
			Cloneable &operator=(Cloneable &&) = delete;
			virtual ~Cloneable() = default;

			template<template<typename...> typename Wrapper = std::unique_ptr, typename... Args>
			static auto Clone(Cloneable const &c) noexcept
			-> Wrapper<Cloneable, Args...>
			{
				return Wrapper<Cloneable, Args...>{c.clone()};
			}

		private:
			template<typename DerivedT>
			friend struct CloneImplementor;
			virtual Cloneable *clone() const noexcept = 0;
		};
		template<typename DerivedT>
		struct CloneImplementor
		: virtual Cloneable
		{
			using Cloneable_t = DerivedT;
			using CloneImplementor_t = CloneImplementor;

			template<template<typename...> typename Wrapper = std::unique_ptr, typename... Args>
			static auto Clone(Cloneable_t const &ct) noexcept
			-> Wrapper<Cloneable_t, Args...>
			{
				Cloneable const &c = ct;
				return Wrapper<Cloneable_t, Args...>{dynamic_cast<Cloneable_t *>(c.clone())};
			}

		private:
			CloneImplementor() = default;
			friend Cloneable_t;
		};

		template<typename CloneableT, template<typename...> typename Wrapper = std::unique_ptr, typename... Args>
		struct ClonePtr final
		: Wrapper<CloneableT, Args...>
		{
			static_assert(std::is_base_of<Cloneable, CloneableT>::value);
			using Cloneable_t = CloneableT;
			using ClonePtr_t = ClonePtr;
			using Wrapper_t = Wrapper<CloneableT, Args...>;
			using Wrapper_t::Wrapper_t;
			ClonePtr(ClonePtr const &from) noexcept
			: Wrapper_t{std::move(Cloneable_t::Clone<Wrapper, Args...>(*from))}
			{
			}
			ClonePtr &operator=(ClonePtr const &from) noexcept
			{
				return Wrapper_t::operator=(std::move(Cloneable_t::Clone<Wrapper, Args...>(*from)));
			}
			ClonePtr(Cloneable_t const &from) noexcept
			: Wrapper_t{std::move(Cloneable_t::Clone<Wrapper, Args...>(from))}
			{
			}
			ClonePtr &operator=(Cloneable_t const &from) noexcept
			{
				return Wrapper_t::operator=(std::move(Cloneable_t::Clone<Wrapper, Args...>(from)));
			}
		};
	}
}

#endif
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <string>

// const charT* data() const;
//       charT* data();   // C++17

#include <string>
#include <cassert>

#include "test_macros.h"
#include "min_allocator.h"

template <class S>
void
test_const(const S& s)
{
    typedef typename S::traits_type T;
    const typename S::value_type* str = s.data();
    if (s.size() > 0)
    {
        assert(T::compare(str, &s[0], s.size()) == 0);
        assert(T::eq(str[s.size()], typename S::value_type()));
    }
    else
        assert(T::eq(str[0], typename S::value_type()));
}

template <class S>
void
test_nonconst(S& s)
{
    typedef typename S::traits_type T;
    typename S::value_type* str = s.data();
    if (s.size() > 0)
    {
        assert(T::compare(str, &s[0], s.size()) == 0);
        assert(T::eq(str[s.size()], typename S::value_type()));
    }
    else
        assert(T::eq(str[0], typename S::value_type()));
}

int main()
{
    {
    typedef std::string S;
    test_const(S(""));
    test_const(S("abcde"));
    test_const(S("abcdefghij"));
    test_const(S("abcdefghijklmnopqrst"));
    }
#if TEST_STD_VER >= 11
    {
    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
    test_const(S(""));
    test_const(S("abcde"));
    test_const(S("abcdefghij"));
    test_const(S("abcdefghijklmnopqrst"));
    }
#endif
#if TEST_STD_VER > 14
	{
    typedef std::string S;
    S s1("");                     test_nonconst(s1);
    S s2("abcde");                test_nonconst(s2);
    S s3("abcdefghij");           test_nonconst(s3);
    S s4("abcdefghijklmnopqrst"); test_nonconst(s4);
	}
#endif
}
<commit_msg>Remove a couple tabs that crept in<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <string>

// const charT* data() const;
//       charT* data();   // C++17

#include <string>
#include <cassert>

#include "test_macros.h"
#include "min_allocator.h"

template <class S>
void
test_const(const S& s)
{
    typedef typename S::traits_type T;
    const typename S::value_type* str = s.data();
    if (s.size() > 0)
    {
        assert(T::compare(str, &s[0], s.size()) == 0);
        assert(T::eq(str[s.size()], typename S::value_type()));
    }
    else
        assert(T::eq(str[0], typename S::value_type()));
}

template <class S>
void
test_nonconst(S& s)
{
    typedef typename S::traits_type T;
    typename S::value_type* str = s.data();
    if (s.size() > 0)
    {
        assert(T::compare(str, &s[0], s.size()) == 0);
        assert(T::eq(str[s.size()], typename S::value_type()));
    }
    else
        assert(T::eq(str[0], typename S::value_type()));
}

int main()
{
    {
    typedef std::string S;
    test_const(S(""));
    test_const(S("abcde"));
    test_const(S("abcdefghij"));
    test_const(S("abcdefghijklmnopqrst"));
    }
#if TEST_STD_VER >= 11
    {
    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
    test_const(S(""));
    test_const(S("abcde"));
    test_const(S("abcdefghij"));
    test_const(S("abcdefghijklmnopqrst"));
    }
#endif
#if TEST_STD_VER > 14
    {
    typedef std::string S;
    S s1("");                     test_nonconst(s1);
    S s2("abcde");                test_nonconst(s2);
    S s3("abcdefghij");           test_nonconst(s3);
    S s4("abcdefghijklmnopqrst"); test_nonconst(s4);
    }
#endif
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013-2015.
// Distributed under the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "cpp_utils/data.hpp"

#include "dataset.hpp"
#include "detector.hpp"
#include "image_utils.hpp"

//Real constants used to divide the dataset if necessary
constexpr const std::size_t test_divide = 5;
constexpr const std::size_t subset_divide = 10;

void preprocess(std::vector<double>& image, const config& conf){
    if(conf.gray){
        for(auto& pixel : image){
            pixel = 255 - pixel;
        }

        cpp::normalize(image);
    }
}

dataset get_oracle_dataset(const config& conf){

    dataset ds;

    for(auto& image_source_path : conf.files){
        if(!conf.quiet){
            std::cout << "Load and detect "<< image_source_path << std::endl;
        }

        auto source_image = open_image(image_source_path);
        auto original_image = open_image(image_source_path, false);

        if (!source_image.data || !original_image.data){
            std::cout << "Invalid source_image" << std::endl;
            return ds;
        }

        cv::Mat source;
        sudoku_binarize(source_image, source);

        //Detect if image was resized

        //bool resized = source_image.size() != original_image.size();
        //auto w_ratio = static_cast<double>(source_image.size().width) / original_image.size().width;
        //auto h_ratio = static_cast<double>(source_image.size().height) / original_image.size().height;

        //Read metadata

        auto data = read_data(image_source_path);
        auto pure_data = read_data_pure(image_source_path);

        cv::Mat dest_image;
        auto grid = detect(source_image, dest_image, conf.mixed);

        grid.source_image_path = image_source_path;

        for(size_t i = 0; i < 9; ++i){
            for(size_t j = 0; j < 9; ++j){
                auto& cell = grid(j, i);

                //This is a handwritten digit
                if(!pure_data.results[i][j]){
                    const auto& bounding_rect = cell.bounding;

                    auto width = 28 + 4;
                    auto height = 28 + 4;
                    auto x_start = -2 + bounding_rect.x + (bounding_rect.width - 28) / 2;
                    auto y_start = -2 + bounding_rect.y + (bounding_rect.height - 28) / 2;

                    //Apply reverse ratio
                    //if(resized){
                        //x_start *= (1.0 / w_ratio);
                        //y_start *= (1.0 / h_ratio);
                        //width *= (1.0 / h_ratio);
                        //height *= (1.0 / h_ratio);
                    //}

                    cell.digit_bounding.x = x_start;
                    cell.digit_bounding.y = y_start;
                    cell.digit_bounding.width = width;
                    cell.digit_bounding.height = height;

                    cell.color_mat = cv::Mat(source_image, cell.digit_bounding);
                    //cv::resize(color_final_square, cell.color_mat, cell.color_mat.size(), 0, 0, cv::INTER_CUBIC);
                    cv::cvtColor(cell.color_mat, cell.gray_mat, CV_RGB2GRAY);

                    //cv::Mat binary_final_square(source, cell.digit_bounding);

                    //cv::Mat binary_big_square(cv::Size(CELL_SIZE, CELL_SIZE), source.type());

                    //cv::resize(binary_final_square, binary_big_square, binary_big_square.size(), 0, 0, cv::INTER_CUBIC);

                    cell_binarize(cell.gray_mat, cell.binary_mat, conf.mixed);
                }

                //show_regrid(grid, 0);
                //cv::waitKey(0);

                cell.correct() = data.results[i][j];

                if(data.results[i][j]){
                    ds.all_labels.push_back(data.results[i][j]-1);
                    ds.all_images.emplace_back(cell.image(conf));
                }
            }
        }

        ds.source_grids.push_back(grid);
    }

    for(auto& image : ds.all_images){
        preprocess(image, conf);
    }

    if(conf.subset){
        std::size_t count = 0;
        auto filter_lambda = [&count](auto&){ return count++ % subset_divide > 0; };
        ds.all_labels.erase(std::remove_if(ds.all_labels.begin(), ds.all_labels.end(), filter_lambda), ds.all_labels.end());
        count = 0;
        ds.all_images.erase(std::remove_if(ds.all_images.begin(), ds.all_images.end(), filter_lambda), ds.all_images.end());
    }

    if(conf.test){
        for(std::size_t i = 0; i < ds.all_images.size(); ++i){
            if(i % test_divide == 0){
                ds.test_labels.push_back(ds.all_labels[i]);
                ds.test_images.push_back(ds.all_images[i]);
            } else {
                ds.training_labels.push_back(ds.all_labels[i]);
                ds.training_images.push_back(ds.all_images[i]);
            }
        }
    } else {
        ds.training_labels = ds.all_labels;
        ds.training_images = ds.all_images;
    }

    assert(ds.all_images.size() == ds.all_labels.size());
    assert(ds.training_images.size() == ds.training_labels.size());
    assert(ds.test_images.size() == ds.test_labels.size());

    std::cout << "...dataset loaded" << std::endl;

    return ds;
}

dataset get_dataset(const config& conf){
    if(conf.oracle){
        std::cout << "Start loading oracle dataset..." << std::endl;
        return get_oracle_dataset(conf);
    }

    std::cout << "Start loading dataset..." << std::endl;

    dataset ds;

    for(auto& image_source_path : conf.files){
        if(!conf.quiet){
            std::cout << "Load and detect "<< image_source_path << std::endl;
        }

        auto source_image = open_image(image_source_path);

        if (!source_image.data){
            std::cout << "Invalid source_image" << std::endl;
            continue;
        }

        auto data = read_data(image_source_path);

        cv::Mat dest_image;
        auto grid = detect(source_image, dest_image, conf.mixed);

        grid.source_image_path = image_source_path;

        for(size_t i = 0; i < 9; ++i){
            for(size_t j = 0; j < 9; ++j){
                auto& cell = grid(j, i);

                cell.correct() = data.results[i][j];

                if(data.results[i][j]){
                    ds.all_labels.push_back(data.results[i][j]-1);
                    ds.all_images.emplace_back(cell.image(conf));
                }
            }
        }

        ds.source_grids.push_back(grid);
    }

    for(auto& image : ds.all_images){
        preprocess(image, conf);
    }

    if(conf.subset){
        std::size_t count = 0;
        auto filter_lambda = [&count](auto&){ return count++ % subset_divide > 0; };
        ds.all_labels.erase(std::remove_if(ds.all_labels.begin(), ds.all_labels.end(), filter_lambda), ds.all_labels.end());
        count = 0;
        ds.all_images.erase(std::remove_if(ds.all_images.begin(), ds.all_images.end(), filter_lambda), ds.all_images.end());
    }

    if(conf.test){
        for(std::size_t i = 0; i < ds.all_images.size(); ++i){
            if(i % test_divide == 0){
                ds.test_labels.push_back(ds.all_labels[i]);
                ds.test_images.push_back(ds.all_images[i]);
            } else {
                ds.training_labels.push_back(ds.all_labels[i]);
                ds.training_images.push_back(ds.all_images[i]);
            }
        }
    } else {
        ds.training_labels = ds.all_labels;
        ds.training_images = ds.all_images;
    }

    assert(ds.all_images.size() == ds.all_labels.size());
    assert(ds.training_images.size() == ds.training_labels.size());
    assert(ds.test_images.size() == ds.test_labels.size());

    std::cout << "...dataset loaded" << std::endl;

    return ds;
}
<commit_msg>Cleanup<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013-2015.
// Distributed under the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "cpp_utils/data.hpp"

#include "dataset.hpp"
#include "detector.hpp"
#include "image_utils.hpp"

//Real constants used to divide the dataset if necessary
constexpr const std::size_t test_divide = 5;
constexpr const std::size_t subset_divide = 10;

void preprocess(std::vector<double>& image, const config& conf){
    if(conf.gray){
        for(auto& pixel : image){
            pixel = 255 - pixel;
        }

        cpp::normalize(image);
    }
}

dataset get_dataset(const config& conf){
    if(conf.oracle){
        std::cout << "Start loading oracle dataset..." << std::endl;
    } else {
        std::cout << "Start loading dataset..." << std::endl;
    }

    dataset ds;

    for(auto& image_source_path : conf.files){
        if(!conf.quiet){
            std::cout << "Load and detect "<< image_source_path << std::endl;
        }

        auto source_image = open_image(image_source_path);

        if (!source_image.data){
            std::cout << "Invalid source_image" << std::endl;
            continue;
        }

        cv::Mat source;
        if(conf.oracle){
            sudoku_binarize(source_image, source);
        }

        //Read metadata

        auto data = read_data(image_source_path);
        auto pure_data = read_data_pure(image_source_path);

        cv::Mat dest_image;
        auto grid = detect(source_image, dest_image, conf.mixed);

        grid.source_image_path = image_source_path;

        for(size_t i = 0; i < 9; ++i){
            for(size_t j = 0; j < 9; ++j){
                auto& cell = grid(j, i);

                //This is a handwritten digit
                if(conf.oracle && !pure_data.results[i][j]){
                    const auto& bounding_rect = cell.bounding;

                    static_assert(CELL_SIZE == 32, "Oracle algorith is out of sync with CELL_SIZE");

                    auto width = 28 + 4;
                    auto height = 28 + 4;
                    auto x_start = -2 + bounding_rect.x + (bounding_rect.width - 28) / 2;
                    auto y_start = -2 + bounding_rect.y + (bounding_rect.height - 28) / 2;

                    cell.digit_bounding.x = x_start;
                    cell.digit_bounding.y = y_start;
                    cell.digit_bounding.width = width;
                    cell.digit_bounding.height = height;

                    cell.color_mat = cv::Mat(source_image, cell.digit_bounding);
                    //cv::resize(color_final_square, cell.color_mat, cell.color_mat.size(), 0, 0, cv::INTER_CUBIC);
                    cv::cvtColor(cell.color_mat, cell.gray_mat, CV_RGB2GRAY);

                    //cv::Mat binary_final_square(source, cell.digit_bounding);
                    //cv::Mat binary_big_square(cv::Size(CELL_SIZE, CELL_SIZE), source.type());
                    //cv::resize(binary_final_square, binary_big_square, binary_big_square.size(), 0, 0, cv::INTER_CUBIC);

                    cell_binarize(cell.gray_mat, cell.binary_mat, conf.mixed);
                }

                cell.correct() = data.results[i][j];

                if(data.results[i][j]){
                    ds.all_labels.push_back(data.results[i][j]-1);
                    ds.all_images.emplace_back(cell.image(conf));
                }
            }
        }

        ds.source_grids.push_back(grid);
    }

    for(auto& image : ds.all_images){
        preprocess(image, conf);
    }

    if(conf.subset){
        std::size_t count = 0;
        auto filter_lambda = [&count](auto&){ return count++ % subset_divide > 0; };
        ds.all_labels.erase(std::remove_if(ds.all_labels.begin(), ds.all_labels.end(), filter_lambda), ds.all_labels.end());
        count = 0;
        ds.all_images.erase(std::remove_if(ds.all_images.begin(), ds.all_images.end(), filter_lambda), ds.all_images.end());
    }

    if(conf.test){
        for(std::size_t i = 0; i < ds.all_images.size(); ++i){
            if(i % test_divide == 0){
                ds.test_labels.push_back(ds.all_labels[i]);
                ds.test_images.push_back(ds.all_images[i]);
            } else {
                ds.training_labels.push_back(ds.all_labels[i]);
                ds.training_images.push_back(ds.all_images[i]);
            }
        }
    } else {
        ds.training_labels = ds.all_labels;
        ds.training_images = ds.all_images;
    }

    assert(ds.all_images.size() == ds.all_labels.size());
    assert(ds.training_images.size() == ds.training_labels.size());
    assert(ds.test_images.size() == ds.test_labels.size());

    std::cout << "...dataset loaded" << std::endl;

    return ds;
}
<|endoftext|>