<commit_before>// Copyright (C) 2018 Egor Pugin <egor.pugin@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <primitives/http.h>

#include <primitives/exceptions.h>

#include <curl/curl.h>

#ifdef _WIN32
#include <windows.h>
#include <Winhttp.h>
#endif

HttpSettings httpSettings;

String getAutoProxy()
{
    String proxy_addr;
    std::wstring wproxy_addr;
#ifdef _WIN32
    WINHTTP_PROXY_INFO proxy = { 0 };
    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxy2 = { 0 };
    if (WinHttpGetDefaultProxyConfiguration(&proxy) && proxy.lpszProxy)
        wproxy_addr = proxy.lpszProxy;
    else if (WinHttpGetIEProxyConfigForCurrentUser(&proxy2) && proxy2.lpszProxy)
        wproxy_addr = proxy2.lpszProxy;
    proxy_addr = to_string(wproxy_addr);
#endif
    return proxy_addr;
}

static auto curl_write_file(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    auto n = fwrite(ptr, size, nmemb, (FILE *)userdata);
    if (n != nmemb)
        perror("Cannot write to disk");
    return n;
}

static int curl_transfer_info(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
    int64_t file_size_limit = *(int64_t*)clientp;
    if (dlnow > file_size_limit)
        return 1;
    return 0;
}

static size_t curl_write_string(char *ptr, size_t size, size_t nmemb, String *s)
{
    auto read = size * nmemb;
    try
    {
        s->append(ptr, ptr + read);
    }
    catch (...)
    {
        return 0;
    }
    return read;
}

void download_file(const String &url, const path &fn, int64_t file_size_limit)
{
    auto parent = fn.parent_path();
    if (!parent.empty() && !fs::exists(parent))
        fs::create_directories(parent);

    ScopedFile ofile(fn, "wb");

    // set up curl request
    auto curl = curl_easy_init();

    if (httpSettings.verbose)
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);

    // proxy settings
    auto proxy_addr = getAutoProxy();
    if (!proxy_addr.empty())
    {
        curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr.c_str());
        curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
    }
    if (!httpSettings.proxy.host.empty())
    {
        curl_easy_setopt(curl, CURLOPT_PROXY, httpSettings.proxy.host.c_str());
        curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
        if (httpSettings.proxy.host.find("socks5") == 0)
        {
            curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
            curl_easy_setopt(curl, CURLOPT_SOCKS5_AUTH, CURLAUTH_BASIC);
        }
        if (!httpSettings.proxy.user.empty())
            curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, httpSettings.proxy.user.c_str());
    }

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_file); // must be set! see CURLOPT_WRITEDATA api desc
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, ofile.getHandle());
    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curl_transfer_info);
    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &file_size_limit);

#ifdef _WIN32
    if (!httpSettings.certs_file.empty())
        curl_easy_setopt(curl, CURLOPT_CAINFO, httpSettings.certs_file.c_str());
    else if (url.find("https") == 0)
    {
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
        if (httpSettings.ignore_ssl_checks)
        {
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
            //curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 0);
        }
    }
#else
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
#endif

    auto res = curl_easy_perform(curl);

    long http_code = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    curl_easy_cleanup(curl);

    // manual close
    ofile.close();

    auto on_error = [&fn]()
    {
        fs::remove(fn);
    };

    if (res == CURLE_ABORTED_BY_CALLBACK)
    {
        on_error();
        throw SW_RUNTIME_ERROR("File '" + url + "' is too big. Limit is " + std::to_string(file_size_limit) + " bytes.");
    }
    if (res != CURLE_OK)
    {
        on_error();
        throw SW_RUNTIME_ERROR("url = " + url + ", curl error: "s + curl_easy_strerror(res));
    }

    if (http_code / 100 != 2)
    {
        on_error();
        throw SW_RUNTIME_ERROR("url = " + url + ", http returned " + std::to_string(http_code));
    }
}

HttpResponse url_request(const HttpRequest &request)
{
    auto curl = curl_easy_init();

    if (request.verbose)
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

    if (!request.agent.empty())
        curl_easy_setopt(curl, CURLOPT_USERAGENT, request.agent.c_str());
    if (!request.username.empty())
        curl_easy_setopt(curl, CURLOPT_USERNAME, request.username.c_str());
    if (!request.password.empty())
        curl_easy_setopt(curl, CURLOPT_USERPWD, request.password.c_str());

    curl_easy_setopt(curl, CURLOPT_URL, request.url.c_str());
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    if (request.connect_timeout != -1)
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, request.connect_timeout);
    if (request.timeout != -1)
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, request.timeout);

    // proxy settings
    auto proxy_addr = getAutoProxy();
    if (!proxy_addr.empty())
    {
        curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr.c_str());
        curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
    }
    if (!request.proxy.host.empty())
    {
        curl_easy_setopt(curl, CURLOPT_PROXY, request.proxy.host.c_str());
        curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
        if (request.proxy.host.find("socks5") == 0)
        {
            curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
            curl_easy_setopt(curl, CURLOPT_SOCKS5_AUTH, CURLAUTH_BASIC);
        }
        if (!request.proxy.user.empty())
            curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, request.proxy.user.c_str());
    }

    std::string data;
    std::vector<char *> escaped;
    switch (request.type)
    {
    case HttpRequest::Post:
        if (!request.data_kv.empty())
        {
            for (auto &a : request.data_kv)
            {
                escaped.push_back(curl_easy_escape(curl, a.first.c_str(), (int)a.first.size()));
                data += escaped.back() + std::string("=");
                escaped.push_back(curl_easy_escape(curl, a.second.c_str(), (int)a.second.size()));
                data += escaped.back() + std::string("&");
            }
            data.resize(data.size() - 1);
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
            curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)data.size());
        }
        else
        {
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.data.c_str());
        }
        break;
    case HttpRequest::Delete:
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
        break;
    }

#ifdef _WIN32
    if (!httpSettings.certs_file.empty())
        curl_easy_setopt(curl, CURLOPT_CAINFO, httpSettings.certs_file.c_str());
    else if (request.url.find("https") == 0)
    {
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
        if (request.ignore_ssl_checks)
        {
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
            //curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 0);
        }
    }
#else
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
#endif

    HttpResponse response;
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response.response);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_string);

    struct curl_slist *list = NULL;

    auto ct = "Content-Type: " + request.content_type;
    if (!request.content_type.empty())
    {
        list = curl_slist_append(list, ct.c_str());
    }
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);

    auto res = curl_easy_perform(curl);

    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response.http_code);
    curl_slist_free_all(list);
    curl_easy_cleanup(curl);

    for (auto &e : escaped)
        curl_free(e);

    if (res != CURLE_OK)
        throw SW_RUNTIME_ERROR("url = " + request.url + ", curl error: "s + curl_easy_strerror(res));

    return response;
}

String download_file(const String &url)
{
    auto fn = fs::temp_directory_path() / unique_path();
    download_file(url, fn, 1_GB);
    auto s = read_file(fn);
    fs::remove(fn);
    return s;
}

bool isUrl(const String &s)
{
    if (s.find("http://") == 0 ||
        s.find("https://") == 0 ||
        s.find("ftp://") == 0 ||
        s.find("git://") == 0 ||
        // could be dangerous in case of vulnerabilities on client side? why?
        //s.find("ssh://") == 0 ||
        0
        )
    {
        return true;
    }
    return false;
}
<commit_msg>[http] Merge duplicate curl setup code.<commit_after>// Copyright (C) 2018 Egor Pugin <egor.pugin@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <primitives/http.h>

#include <primitives/exceptions.h>

#include <curl/curl.h>

#ifdef _WIN32
#include <windows.h>
#include <Winhttp.h>
#endif

HttpSettings httpSettings;

String getAutoProxy()
{
    String proxy_addr;
    std::wstring wproxy_addr;
#ifdef _WIN32
    WINHTTP_PROXY_INFO proxy = { 0 };
    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxy2 = { 0 };
    if (WinHttpGetDefaultProxyConfiguration(&proxy) && proxy.lpszProxy)
        wproxy_addr = proxy.lpszProxy;
    else if (WinHttpGetIEProxyConfigForCurrentUser(&proxy2) && proxy2.lpszProxy)
        wproxy_addr = proxy2.lpszProxy;
    proxy_addr = to_string(wproxy_addr);
#endif
    return proxy_addr;
}

static auto curl_write_file(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    auto n = fwrite(ptr, size, nmemb, (FILE *)userdata);
    if (n != nmemb)
        perror("Cannot write to disk");
    return n;
}

static int curl_transfer_info(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
    int64_t file_size_limit = *(int64_t*)clientp;
    if (dlnow > file_size_limit)
        return 1;
    return 0;
}

static size_t curl_write_string(char *ptr, size_t size, size_t nmemb, String *s)
{
    auto read = size * nmemb;
    try
    {
        s->append(ptr, ptr + read);
    }
    catch (...)
    {
        return 0;
    }
    return read;
}

struct CurlWrapper
{
    CURL *curl;
    struct curl_slist *headers = nullptr;
    std::string post_data;
    std::vector<char *> escaped_strings;

    CurlWrapper()
    {
        curl = curl_easy_init();
    }
    ~CurlWrapper()
    {
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);

        for (auto &e : escaped_strings)
            curl_free(e);
    }
};

static std::unique_ptr<CurlWrapper> setup_curl_request(const HttpRequest &request)
{
    auto wp = std::make_unique<CurlWrapper>();
    auto &w = *wp;
    auto curl = w.curl;

    curl_easy_setopt(curl, CURLOPT_URL, request.url.c_str());

    if (request.verbose)
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

    if (!request.agent.empty())
        curl_easy_setopt(curl, CURLOPT_USERAGENT, request.agent.c_str());

    if (!request.username.empty())
        curl_easy_setopt(curl, CURLOPT_USERNAME, request.username.c_str());
    if (!request.password.empty())
        curl_easy_setopt(curl, CURLOPT_USERPWD, request.password.c_str());

    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);

    if (request.connect_timeout != -1)
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, request.connect_timeout);
    if (request.timeout != -1)
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, request.timeout);

    // proxy settings
    auto proxy_addr = getAutoProxy();
    if (!proxy_addr.empty())
    {
        curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr.c_str());
        curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
    }
    if (!httpSettings.proxy.host.empty())
    {
        curl_easy_setopt(curl, CURLOPT_PROXY, httpSettings.proxy.host.c_str());
        curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
        if (httpSettings.proxy.host.find("socks5") == 0)
        {
            curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
            curl_easy_setopt(curl, CURLOPT_SOCKS5_AUTH, CURLAUTH_BASIC);
        }
        if (!httpSettings.proxy.user.empty())
            curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, httpSettings.proxy.user.c_str());
    }

    // ssl
#ifdef _WIN32
    if (!httpSettings.certs_file.empty())
        curl_easy_setopt(curl, CURLOPT_CAINFO, httpSettings.certs_file.c_str());
    else if (request.url.find("https") == 0)
    {
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
        if (request.ignore_ssl_checks)
        {
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
            //curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 0);
        }
    }
#else
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
#endif

    // headers
    auto ct = "Content-Type: " + request.content_type;
    if (!request.content_type.empty())
    {
        w.headers = curl_slist_append(w.headers, ct.c_str());
    }
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, w.headers);

    //
    switch (request.type)
    {
    case HttpRequest::Post:
        if (!request.data_kv.empty())
        {
            for (auto &a : request.data_kv)
            {
                w.escaped_strings.push_back(curl_easy_escape(curl, a.first.c_str(), (int)a.first.size()));
                w.post_data += w.escaped_strings.back() + std::string("=");
                w.escaped_strings.push_back(curl_easy_escape(curl, a.second.c_str(), (int)a.second.size()));
                w.post_data += w.escaped_strings.back() + std::string("&");
            }
            w.post_data.resize(w.post_data.size() - 1);
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, w.post_data.c_str());
            curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)w.post_data.size());
        }
        else
        {
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.data.c_str());
        }
        break;
    case HttpRequest::Delete:
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
        break;
    }

    return wp;
}

void download_file(const String &url, const path &fn, int64_t file_size_limit)
{
    auto parent = fn.parent_path();
    if (!parent.empty() && !fs::exists(parent))
        fs::create_directories(parent);

    ScopedFile ofile(fn, "wb");

    HttpRequest req(httpSettings);
    req.url = url;
    auto w = setup_curl_request(req);
    auto curl = w->curl;

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_file); // must be set! see CURLOPT_WRITEDATA api desc
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, ofile.getHandle());
    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curl_transfer_info);
    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &file_size_limit);

    auto res = curl_easy_perform(curl);

    long http_code = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

    // manual close
    ofile.close();

    auto on_error = [&fn]()
    {
        fs::remove(fn);
    };

    if (res == CURLE_ABORTED_BY_CALLBACK)
    {
        on_error();
        throw SW_RUNTIME_ERROR("File '" + url + "' is too big. Limit is " + std::to_string(file_size_limit) + " bytes.");
    }
    if (res != CURLE_OK)
    {
        on_error();
        throw SW_RUNTIME_ERROR("url = " + url + ", curl error: "s + curl_easy_strerror(res));
    }

    if (http_code / 100 != 2)
    {
        on_error();
        throw SW_RUNTIME_ERROR("url = " + url + ", http returned " + std::to_string(http_code));
    }
}

HttpResponse url_request(const HttpRequest &request)
{
    auto w = setup_curl_request(request);
    auto curl = w->curl;

    HttpResponse response;
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response.response);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_string);

    auto res = curl_easy_perform(curl);

    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response.http_code);

    if (res != CURLE_OK)
        throw SW_RUNTIME_ERROR("url = " + request.url + ", curl error: "s + curl_easy_strerror(res));

    return response;
}

String download_file(const String &url)
{
    auto fn = fs::temp_directory_path() / unique_path();
    download_file(url, fn, 1_GB);
    auto s = read_file(fn);
    fs::remove(fn);
    return s;
}

bool isUrl(const String &s)
{
    if (s.find("http://") == 0 ||
        s.find("https://") == 0 ||
        s.find("ftp://") == 0 ||
        s.find("git://") == 0 ||
        // could be dangerous in case of vulnerabilities on client side? why?
        //s.find("ssh://") == 0 ||
        0
        )
    {
        return true;
    }
    return false;
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2013 Mateusz Łoskot <mateusz@loskot.net>
// Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
//
#include "bbopenprojectwizard.hpp"
#include "bbproject.hpp"
#include "bbprojectmanagerconstants.hpp"
// Qt Creator
#include <coreplugin/dialogs/iwizard.h>
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>
#include <projectexplorer/customwizard/customwizard.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/pathchooser.h>
// Qt
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QVBoxLayout>

namespace BoostBuildProjectManager {
namespace Internal {

//////////////////////////////////////////////////////////////////////////////////////////
OpenProjectWizard::OpenProjectWizard(QString const& name, QString const& path, QWidget* parent)
    : Utils::Wizard(parent)
    , name_(name)
    , path_(path)
{
    setWindowTitle(tr("Open %1 Project").arg(QLatin1String(Constants::BOOSTBUILD)));

    pathsPage_ = new PathsSelectionWizardPage(this);
    pathsPage_->setTitle(tr("Project Name and Paths"));
    int const pathsPageId = addPage(pathsPage_);
    wizardProgress()->item(pathsPageId)->setTitle(tr("Location"));

    //int const filesPageId = addPage(filesPage_);
    //wizardProgress()->item(filesPageId)->setTitle(tr("Files"));
}

QString OpenProjectWizard::projectName() const
{
    return pathsPage_->projectName();
}

QString OpenProjectWizard::defaultProjectName() const
{
    return name_;
}

QString OpenProjectWizard::projectPath() const
{
    return path_;
}

QStringList OpenProjectWizard::selectedFiles() const
{
    return QStringList();
}

QStringList OpenProjectWizard::selectedPaths() const
{
    return QStringList();
}

//////////////////////////////////////////////////////////////////////////////////////////
PathsSelectionWizardPage::PathsSelectionWizardPage(OpenProjectWizard* wizard)
    : QWizardPage(wizard)
    , wizard_(wizard)
{
    QFormLayout *fl = new QFormLayout();
    setLayout(fl);

    QLabel* pathLabel = new QLabel(this);
    pathLabel->setText(tr("Opening the following Jamfile as a project:"));
    fl->addRow(pathLabel);

    QLineEdit* pathLine = new QLineEdit(this);
    pathLine->setReadOnly(true);
    pathLine->setText(wizard_->projectPath());
    fl->addRow(pathLine);

    nameLineEdit_ = new QLineEdit(this);
    nameLineEdit_->setText(wizard_->defaultProjectName());
    fl->addRow(tr("Project name:"), nameLineEdit_);

    QLabel* defaultsLabel = new QLabel(this);
    defaultsLabel->setText(tr("Default Boost.Build runtime locations:"));
    fl->addRow(defaultsLabel);

    QLineEdit* workingLine = new QLineEdit(this);
    workingLine->setReadOnly(true);
    workingLine->setText(Project::defaultWorkingDirectory(wizard_->projectPath()));
    fl->addRow(tr("Working directory:"), workingLine);

    QLineEdit* buildLine = new QLineEdit(this);
    buildLine->setReadOnly(true);
    buildLine->setText(Project::defaultBuildDirectory(wizard_->projectPath()));
    fl->addRow(tr("Build directory:"), buildLine);

    // TODO: find Boost.Build executable?

    QString const info(tr(
        "This allows you to use Qt Creator as an IDE to edit and navigate C++ code, "
        "run %1 command, work through compilation issues, "
        "configure executable targets to run and debug.")
        .arg(QLatin1String(Constants::BOOSTBUILD)));
    QLabel* infoLabel = new QLabel(this);
    infoLabel->setWordWrap(true);
    infoLabel->setText(info);
    fl->addRow(infoLabel);
}

QString PathsSelectionWizardPage::projectName() const
{
    return nameLineEdit_->text();
}

//////////////////////////////////////////////////////////////////////////////////////////
#if 0
FilesSelectionWizardPage::FilesSelectionWizardPage(
    OpenProjectWizard* genericProjectWizard
  , QWidget* parent)
{
}

bool FilesSelectionWizardPage::isComplete() const
{
}

void FilesSelectionWizardPage::initializePage()
{
}

void FilesSelectionWizardPage::cleanupPage()
{
}

QStringList FilesSelectionWizardPage::selectedFiles() const
{

}

QStringList FilesSelectionWizardPage::selectedPaths() const
{
}

void FilesSelectionWizardPage::applyFilter()
{
}

void FilesSelectionWizardPage::parsingProgress(const QString &text)
{
}

void FilesSelectionWizardPage::parsingFinished()
{
}

void FilesSelectionWizardPage::createHideFileFilterControls(QVBoxLayout* layout)
{

}

void FilesSelectionWizardPage::createShowFileFilterControls(QVBoxLayout* layout)
{

}

void FilesSelectionWizardPage::createApplyButton(QVBoxLayout *layout)
{

}
#endif

} // namespace Internal
} // namespace BoostBuildProjectManager
<commit_msg>Disable QLineEdit widgets on first page of OpenProjectWizard<commit_after>//
// Copyright (C) 2013 Mateusz Łoskot <mateusz@loskot.net>
// Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
//
#include "bbopenprojectwizard.hpp"
#include "bbproject.hpp"
#include "bbprojectmanagerconstants.hpp"
// Qt Creator
#include <coreplugin/dialogs/iwizard.h>
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>
#include <projectexplorer/customwizard/customwizard.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/pathchooser.h>
// Qt
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QVBoxLayout>

namespace BoostBuildProjectManager {
namespace Internal {

//////////////////////////////////////////////////////////////////////////////////////////
OpenProjectWizard::OpenProjectWizard(QString const& name, QString const& path, QWidget* parent)
    : Utils::Wizard(parent)
    , name_(name)
    , path_(path)
{
    setWindowTitle(tr("Open %1 Project").arg(QLatin1String(Constants::BOOSTBUILD)));

    pathsPage_ = new PathsSelectionWizardPage(this);
    pathsPage_->setTitle(tr("Project Name and Paths"));
    int const pathsPageId = addPage(pathsPage_);
    wizardProgress()->item(pathsPageId)->setTitle(tr("Location"));

    //int const filesPageId = addPage(filesPage_);
    //wizardProgress()->item(filesPageId)->setTitle(tr("Files"));
}

QString OpenProjectWizard::projectName() const
{
    return pathsPage_->projectName();
}

QString OpenProjectWizard::defaultProjectName() const
{
    return name_;
}

QString OpenProjectWizard::projectPath() const
{
    return path_;
}

QStringList OpenProjectWizard::selectedFiles() const
{
    return QStringList();
}

QStringList OpenProjectWizard::selectedPaths() const
{
    return QStringList();
}

//////////////////////////////////////////////////////////////////////////////////////////
PathsSelectionWizardPage::PathsSelectionWizardPage(OpenProjectWizard* wizard)
    : QWizardPage(wizard)
    , wizard_(wizard)
{
    QFormLayout *fl = new QFormLayout();
    setLayout(fl);

    QLabel* pathLabel = new QLabel(this);
    pathLabel->setText(tr("Opening the following Jamfile as a project:"));
    fl->addRow(pathLabel);

    QLineEdit* pathLine = new QLineEdit(this);
    pathLine->setReadOnly(true);
    pathLine->setDisabled(true);
    pathLine->setText(wizard_->projectPath());
    fl->addRow(pathLine);

    nameLineEdit_ = new QLineEdit(this);
    nameLineEdit_->setText(wizard_->defaultProjectName());
    fl->addRow(tr("Project name:"), nameLineEdit_);

    QLabel* defaultsLabel = new QLabel(this);
    defaultsLabel->setText(tr("Default Boost.Build runtime locations:"));
    fl->addRow(defaultsLabel);

    QLineEdit* workingLine = new QLineEdit(this);
    workingLine->setReadOnly(true);
    workingLine->setDisabled(true);
    workingLine->setText(Project::defaultWorkingDirectory(wizard_->projectPath()));
    fl->addRow(tr("Working directory:"), workingLine);

    QLineEdit* buildLine = new QLineEdit(this);
    buildLine->setReadOnly(true);
    buildLine->setDisabled(true);
    buildLine->setText(Project::defaultBuildDirectory(wizard_->projectPath()));
    fl->addRow(tr("Build directory:"), buildLine);

    // TODO: find Boost.Build executable?

    QString const info(tr(
        "This allows you to use Qt Creator as an IDE to edit and navigate C++ code, "
        "run %1 command, work through compilation issues, "
        "configure executable targets to run and debug.")
        .arg(QLatin1String(Constants::BOOSTBUILD)));
    QLabel* infoLabel = new QLabel(this);
    infoLabel->setWordWrap(true);
    infoLabel->setText(info);
    fl->addRow(infoLabel);
}

QString PathsSelectionWizardPage::projectName() const
{
    return nameLineEdit_->text();
}

//////////////////////////////////////////////////////////////////////////////////////////
#if 0
FilesSelectionWizardPage::FilesSelectionWizardPage(
    OpenProjectWizard* genericProjectWizard
  , QWidget* parent)
{
}

bool FilesSelectionWizardPage::isComplete() const
{
}

void FilesSelectionWizardPage::initializePage()
{
}

void FilesSelectionWizardPage::cleanupPage()
{
}

QStringList FilesSelectionWizardPage::selectedFiles() const
{

}

QStringList FilesSelectionWizardPage::selectedPaths() const
{
}

void FilesSelectionWizardPage::applyFilter()
{
}

void FilesSelectionWizardPage::parsingProgress(const QString &text)
{
}

void FilesSelectionWizardPage::parsingFinished()
{
}

void FilesSelectionWizardPage::createHideFileFilterControls(QVBoxLayout* layout)
{

}

void FilesSelectionWizardPage::createShowFileFilterControls(QVBoxLayout* layout)
{

}

void FilesSelectionWizardPage::createApplyButton(QVBoxLayout *layout)
{

}
#endif

} // namespace Internal
} // namespace BoostBuildProjectManager
<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <deque>
#include <map>
#include <utility>
#include <functional>
#include <algorithm>

namespace tabu
{
    template<class T>
    T search(int max_attempts,
             int short_memory_size,
             std::function<float(T)> fitness,
             std::function<T()> random,
             std::function<std::vector<T>(T)> neighbours)
    {
        std::deque<T> short_memory(short_memory_size, random());
        T current = short_memory.front();
        T best = current;
        float best_fitness = fitness(best);
        for (int i = 0; i < max_attempts; i++)
        {
            auto possibles = neighbours(current);

            for (auto& sm : short_memory)
            {
                auto it = std::find(possibles.begin(), possibles.end(), sm);
                if (it != possibles.end())
                {
                    possibles.erase(it);
                }
            }
            if (possibles.size() == 0)
            {
                break;
            }

            std::vector<std::pair<float, T>> scores;
            std::transform(possibles.begin(), possibles.end(), std::inserter(scores, scores.begin()), [&](T p) { return std::pair<float, T>(fitness(p), p); });
            std::sort(scores.begin(), scores.end(), std::greater<std::pair<float, T>>());

            for (auto& kvp : scores)
            {
                short_memory.pop_back();
                short_memory.push_front(kvp.second);
                if (kvp.first > best_fitness)
                {
                    best = kvp.second;
                    best_fitness = kvp.first;
                }
                current = kvp.second;
            }
        }

        return best;
    }
}<commit_msg>re-add break when a non-tabu score was found<commit_after>#pragma once

#include <vector>
#include <deque>
#include <map>
#include <utility>
#include <functional>
#include <algorithm>

namespace tabu
{
    template<class T>
    T search(int max_attempts,
             int short_memory_size,
             std::function<float(T)> fitness,
             std::function<T()> random,
             std::function<std::vector<T>(T)> neighbours)
    {
        std::deque<T> short_memory(short_memory_size, random());
        T current = short_memory.front();
        T best = current;
        float best_fitness = fitness(best);
        for (int i = 0; i < max_attempts; i++)
        {
            auto possibles = neighbours(current);

            for (auto& sm : short_memory)
            {
                auto it = std::find(possibles.begin(), possibles.end(), sm);
                if (it != possibles.end())
                {
                    possibles.erase(it);
                }
            }
            if (possibles.size() == 0)
            {
                break;
            }

            std::vector<std::pair<float, T>> scores;
            std::transform(possibles.begin(), possibles.end(), std::inserter(scores, scores.begin()), [&](T p) { return std::pair<float, T>(fitness(p), p); });
            std::sort(scores.begin(), scores.end(), std::greater<std::pair<float, T>>());

            for (auto& kvp : scores)
            {
                short_memory.pop_back();
                short_memory.push_front(kvp.second);
                if (kvp.first > best_fitness)
                {
                    best = kvp.second;
                    best_fitness = kvp.first;
                }
                current = kvp.second;
                break;
            }
        }

        return best;
    }
}<|endoftext|>


<commit_before>/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* Write some debug info */

#include "mysql_priv.h"
#include "sql_select.h"
#include <hash.h>
#include <thr_alarm.h>
#include <malloc.h>

/* Intern key cache variables */
extern "C" pthread_mutex_t THR_LOCK_keycache;

#ifndef DBUG_OFF

void
print_where(COND *cond,const char *info)
{
  if (cond)
  {
    char buff[256];
    String str(buff,(uint32) sizeof(buff));
    str.length(0);
    cond->print(&str);
    str.append('\0');
    DBUG_LOCK_FILE;
    (void) fprintf(DBUG_FILE,"\nWHERE:(%s) ",info);
    (void) fputs(str.ptr(),DBUG_FILE);
    (void) fputc('\n',DBUG_FILE);
    DBUG_UNLOCK_FILE;
  }
}

	/* This is for debugging purposes */

extern HASH open_cache;
extern TABLE *unused_tables;

void print_cached_tables(void)
{
  uint idx,count,unused;
  TABLE *start_link,*lnk;

  VOID(pthread_mutex_lock(&LOCK_open));
  puts("DB             Table                            Version  Thread  L.thread  Open");

  for (idx=unused=0 ; idx < open_cache.records ; idx++)
  {
    TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
    printf("%-14.14s %-32s%6ld%8ld%10ld%6d\n",
	   entry->table_cache_key,entry->real_name,entry->version,
	   entry->in_use ? entry->in_use->thread_id : 0L,
	   entry->in_use ? entry->in_use->dbug_thread_id : 0L,
	   entry->db_stat ? 1 : 0);
    if (!entry->in_use)
      unused++;
  }
  count=0;
  if ((start_link=lnk=unused_tables))
  {
    do
    {
      if (lnk != lnk->next->prev || lnk != lnk->prev->next)
      {
	printf("unused_links isn't linked properly\n");
	return;
      }
    } while (count++ < open_cache.records && (lnk=lnk->next) != start_link);
    if (lnk != start_link)
    {
      printf("Unused_links aren't connected\n");
    }
  }
  if (count != unused)
    printf("Unused_links (%d) doesn't match open_cache: %d\n", count,unused);
  printf("\nCurrent refresh version: %ld\n",refresh_version);
  if (hash_check(&open_cache))
    printf("Error: File hash table is corrupted\n");
  fflush(stdout);
  VOID(pthread_mutex_unlock(&LOCK_open));
  return;
}

void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special)
{
  char buff[256],buff2[256];
  String str(buff,sizeof(buff)),out(buff2,sizeof(buff2));
  const char *sep;
  DBUG_ENTER("TEST_filesort");

  out.length(0);
  for (sep=""; s_length-- ; sortorder++, sep=" ")
  {
    out.append(sep);
    if (sortorder->reverse)
      out.append('-');
    if (sortorder->field)
    {
      if (sortorder->field->table_name)
      {
	out.append(sortorder->field->table_name);
	out.append('.');
      }
      out.append(sortorder->field->field_name ? sortorder->field->field_name:
		 "tmp_table_column");
    }
    else
    {
      str.length(0);
      sortorder->item->print(&str);
      out.append(str);
    }
  }
  out.append('\0');				// Purify doesn't like c_ptr()
  DBUG_LOCK_FILE;
  VOID(fputs("\nInfo about FILESORT\n",DBUG_FILE));
  if (special)
    fprintf(DBUG_FILE,"Records to sort: %lu\n",(ulong) special);
  fprintf(DBUG_FILE,"Sortorder: %s\n",out.ptr());
  DBUG_UNLOCK_FILE;
  DBUG_VOID_RETURN;
}

void
TEST_join(JOIN *join)
{
  uint i,ref;
  DBUG_ENTER("TEST_join");

  DBUG_LOCK_FILE;
  VOID(fputs("\nInfo about JOIN\n",DBUG_FILE));
  for (i=0 ; i < join->tables ; i++)
  {
    JOIN_TAB *tab=join->join_tab+i;
    TABLE *form=tab->table;
    fprintf(DBUG_FILE,"%-16.16s  type: %-7s  q_keys: %4d  refs: %d  key: %d  len: %d\n",
	    form->table_name,
	    join_type_str[tab->type],
	    tab->keys,
	    tab->ref.key_parts,
	    tab->ref.key,
	    tab->ref.key_length);
    if (tab->select)
    {
      if (tab->use_quick == 2)
	fprintf(DBUG_FILE,
		"                  quick select checked for each record (keys: %d)\n",
		(int) tab->select->quick_keys);
      else if (tab->select->quick)
	fprintf(DBUG_FILE,"                  quick select used on key %s, length: %d\n",
		form->key_info[tab->select->quick->index].name,
		tab->select->quick->max_used_key_length);
      else
	VOID(fputs("                  select used\n",DBUG_FILE));
    }
    if (tab->ref.key_parts)
    {
      VOID(fputs("                  refs: ",DBUG_FILE));
      for (ref=0 ; ref < tab->ref.key_parts ; ref++)
      {
	Item *item=tab->ref.items[ref];
	fprintf(DBUG_FILE,"%s  ", item->full_name());
      }
      VOID(fputc('\n',DBUG_FILE));
    }
  }
  DBUG_UNLOCK_FILE;
  DBUG_VOID_RETURN;
}

#endif

void mysql_print_status(THD *thd)
{
  char current_dir[FN_REFLEN];
  printf("\nStatus information:\n\n");
  my_getwd(current_dir, sizeof(current_dir),MYF(0));
  printf("Current dir: %s\n", current_dir);
  if (thd)
    thd->proc_info="locks";
  thr_print_locks();				// Write some debug info
#ifndef DBUG_OFF
  if (thd)
    thd->proc_info="table cache";
  print_cached_tables();
#endif
  /* Print key cache status */
  if (thd)
    thd->proc_info="key cache";
  pthread_mutex_lock(&THR_LOCK_keycache);
  printf("key_cache status:\n\
blocks used:%10lu\n\
not flushed:%10lu\n\
w_requests: %10lu\n\
writes:     %10lu\n\
r_requests: %10lu\n\
reads:      %10lu\n",
	 _my_blocks_used,_my_blocks_changed,_my_cache_w_requests,
	 _my_cache_write,_my_cache_r_requests,_my_cache_read);
  pthread_mutex_unlock(&THR_LOCK_keycache);

  if (thd)
    thd->proc_info="status";
  pthread_mutex_lock(&LOCK_status);
  printf("\nhandler status:\n\
read_key:   %10lu\n\
read_next:  %10lu\n\
read_rnd    %10lu\n\
read_first: %10lu\n\
write:      %10lu\n\
delete      %10lu\n\
update:     %10lu\n",
	 ha_read_key_count, ha_read_next_count,
	 ha_read_rnd_count, ha_read_first_count,
	 ha_write_count, ha_delete_count, ha_update_count);
  pthread_mutex_unlock(&LOCK_status);
  printf("\nTable status:\n\
Opened tables: %10lu\n\
Open tables:   %10lu\n\
Open files:    %10lu\n\
Open streams:  %10lu\n",
	 opened_tables,
	 (ulong) cached_tables(),
	 (ulong) my_file_opened,
	 (ulong) my_stream_opened);

  ALARM_INFO alarm_info;
#ifndef DONT_USE_THR_ALARM
  thr_alarm_info(&alarm_info);
  printf("\nAlarm status:\n\
Active alarms:   %u\n\
Max used alarms: %u\n\
Next alarm time: %lu\n",
	 alarm_info.active_alarms,
	 alarm_info.max_used_alarms,
	 alarm_info.next_alarm_time);
#endif
  fflush(stdout);
  if (thd)
    thd->proc_info="malloc";
  my_checkmalloc();
  TERMINATE(stdout);				// Write malloc information

#ifdef HAVE_MALLINFO
  struct mallinfo info= mallinfo();
  printf("\nMemory status:\n\
Non-mmapped space allocated from system: %d\n\
Number of free chunks:			 %d\n\
Number of fastbin blocks:		 %d\n\
Number of mmapped regions:		 %d\n\
Space in mmapped regions:		 %d\n\
Maximum total allocated space:		 %d\n\
Space available in freed fastbin blocks: %d\n\
Total allocated space:			 %d\n\
Total free space:			 %d\n\
Top-most, releasable space:		 %d\n",
	 (int) info.arena,
	 (int) info.ordblks,
	 (int) info.smblks,
	 (int) info.hblks,
	 (int) info.hblkhd,
	 (int) info.usmblks,
	 (int) info.fsmblks,
	 (int) info.uordblks,
	 (int) info.fordblks,
	 (int) info.keepcost);
#endif
  puts("");
  if (thd)
    thd->proc_info=0;
}
<commit_msg>Add more information about memory usage to debug log<commit_after>/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* Write some debug info */

#include "mysql_priv.h"
#include "sql_select.h"
#include <hash.h>
#include <thr_alarm.h>
#include <malloc.h>

/* Intern key cache variables */
extern "C" pthread_mutex_t THR_LOCK_keycache;

#ifndef DBUG_OFF

void
print_where(COND *cond,const char *info)
{
  if (cond)
  {
    char buff[256];
    String str(buff,(uint32) sizeof(buff));
    str.length(0);
    cond->print(&str);
    str.append('\0');
    DBUG_LOCK_FILE;
    (void) fprintf(DBUG_FILE,"\nWHERE:(%s) ",info);
    (void) fputs(str.ptr(),DBUG_FILE);
    (void) fputc('\n',DBUG_FILE);
    DBUG_UNLOCK_FILE;
  }
}

	/* This is for debugging purposes */

extern HASH open_cache;
extern TABLE *unused_tables;

void print_cached_tables(void)
{
  uint idx,count,unused;
  TABLE *start_link,*lnk;

  VOID(pthread_mutex_lock(&LOCK_open));
  puts("DB             Table                            Version  Thread  L.thread  Open");

  for (idx=unused=0 ; idx < open_cache.records ; idx++)
  {
    TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
    printf("%-14.14s %-32s%6ld%8ld%10ld%6d\n",
	   entry->table_cache_key,entry->real_name,entry->version,
	   entry->in_use ? entry->in_use->thread_id : 0L,
	   entry->in_use ? entry->in_use->dbug_thread_id : 0L,
	   entry->db_stat ? 1 : 0);
    if (!entry->in_use)
      unused++;
  }
  count=0;
  if ((start_link=lnk=unused_tables))
  {
    do
    {
      if (lnk != lnk->next->prev || lnk != lnk->prev->next)
      {
	printf("unused_links isn't linked properly\n");
	return;
      }
    } while (count++ < open_cache.records && (lnk=lnk->next) != start_link);
    if (lnk != start_link)
    {
      printf("Unused_links aren't connected\n");
    }
  }
  if (count != unused)
    printf("Unused_links (%d) doesn't match open_cache: %d\n", count,unused);
  printf("\nCurrent refresh version: %ld\n",refresh_version);
  if (hash_check(&open_cache))
    printf("Error: File hash table is corrupted\n");
  fflush(stdout);
  VOID(pthread_mutex_unlock(&LOCK_open));
  return;
}

void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special)
{
  char buff[256],buff2[256];
  String str(buff,sizeof(buff)),out(buff2,sizeof(buff2));
  const char *sep;
  DBUG_ENTER("TEST_filesort");

  out.length(0);
  for (sep=""; s_length-- ; sortorder++, sep=" ")
  {
    out.append(sep);
    if (sortorder->reverse)
      out.append('-');
    if (sortorder->field)
    {
      if (sortorder->field->table_name)
      {
	out.append(sortorder->field->table_name);
	out.append('.');
      }
      out.append(sortorder->field->field_name ? sortorder->field->field_name:
		 "tmp_table_column");
    }
    else
    {
      str.length(0);
      sortorder->item->print(&str);
      out.append(str);
    }
  }
  out.append('\0');				// Purify doesn't like c_ptr()
  DBUG_LOCK_FILE;
  VOID(fputs("\nInfo about FILESORT\n",DBUG_FILE));
  if (special)
    fprintf(DBUG_FILE,"Records to sort: %lu\n",(ulong) special);
  fprintf(DBUG_FILE,"Sortorder: %s\n",out.ptr());
  DBUG_UNLOCK_FILE;
  DBUG_VOID_RETURN;
}

void
TEST_join(JOIN *join)
{
  uint i,ref;
  DBUG_ENTER("TEST_join");

  DBUG_LOCK_FILE;
  VOID(fputs("\nInfo about JOIN\n",DBUG_FILE));
  for (i=0 ; i < join->tables ; i++)
  {
    JOIN_TAB *tab=join->join_tab+i;
    TABLE *form=tab->table;
    fprintf(DBUG_FILE,"%-16.16s  type: %-7s  q_keys: %4d  refs: %d  key: %d  len: %d\n",
	    form->table_name,
	    join_type_str[tab->type],
	    tab->keys,
	    tab->ref.key_parts,
	    tab->ref.key,
	    tab->ref.key_length);
    if (tab->select)
    {
      if (tab->use_quick == 2)
	fprintf(DBUG_FILE,
		"                  quick select checked for each record (keys: %d)\n",
		(int) tab->select->quick_keys);
      else if (tab->select->quick)
	fprintf(DBUG_FILE,"                  quick select used on key %s, length: %d\n",
		form->key_info[tab->select->quick->index].name,
		tab->select->quick->max_used_key_length);
      else
	VOID(fputs("                  select used\n",DBUG_FILE));
    }
    if (tab->ref.key_parts)
    {
      VOID(fputs("                  refs: ",DBUG_FILE));
      for (ref=0 ; ref < tab->ref.key_parts ; ref++)
      {
	Item *item=tab->ref.items[ref];
	fprintf(DBUG_FILE,"%s  ", item->full_name());
      }
      VOID(fputc('\n',DBUG_FILE));
    }
  }
  DBUG_UNLOCK_FILE;
  DBUG_VOID_RETURN;
}

#endif

void mysql_print_status(THD *thd)
{
  char current_dir[FN_REFLEN];
  printf("\nStatus information:\n\n");
  my_getwd(current_dir, sizeof(current_dir),MYF(0));
  printf("Current dir: %s\n", current_dir);
  printf("Running threads: %d  Stack size: %ld\n", thread_count,
	 (long) thread_stack);
  if (thd)
    thd->proc_info="locks";
  thr_print_locks();				// Write some debug info
#ifndef DBUG_OFF
  if (thd)
    thd->proc_info="table cache";
  print_cached_tables();
#endif
  /* Print key cache status */
  if (thd)
    thd->proc_info="key cache";
  pthread_mutex_lock(&THR_LOCK_keycache);
  printf("key_cache status:\n\
blocks used:%10lu\n\
not flushed:%10lu\n\
w_requests: %10lu\n\
writes:     %10lu\n\
r_requests: %10lu\n\
reads:      %10lu\n",
	 _my_blocks_used,_my_blocks_changed,_my_cache_w_requests,
	 _my_cache_write,_my_cache_r_requests,_my_cache_read);
  pthread_mutex_unlock(&THR_LOCK_keycache);

  if (thd)
    thd->proc_info="status";
  pthread_mutex_lock(&LOCK_status);
  printf("\nhandler status:\n\
read_key:   %10lu\n\
read_next:  %10lu\n\
read_rnd    %10lu\n\
read_first: %10lu\n\
write:      %10lu\n\
delete      %10lu\n\
update:     %10lu\n",
	 ha_read_key_count, ha_read_next_count,
	 ha_read_rnd_count, ha_read_first_count,
	 ha_write_count, ha_delete_count, ha_update_count);
  pthread_mutex_unlock(&LOCK_status);
  printf("\nTable status:\n\
Opened tables: %10lu\n\
Open tables:   %10lu\n\
Open files:    %10lu\n\
Open streams:  %10lu\n",
	 opened_tables,
	 (ulong) cached_tables(),
	 (ulong) my_file_opened,
	 (ulong) my_stream_opened);

  ALARM_INFO alarm_info;
#ifndef DONT_USE_THR_ALARM
  thr_alarm_info(&alarm_info);
  printf("\nAlarm status:\n\
Active alarms:   %u\n\
Max used alarms: %u\n\
Next alarm time: %lu\n",
	 alarm_info.active_alarms,
	 alarm_info.max_used_alarms,
	 alarm_info.next_alarm_time);
#endif
  fflush(stdout);
  if (thd)
    thd->proc_info="malloc";
  my_checkmalloc();
  TERMINATE(stdout);				// Write malloc information

#ifdef HAVE_MALLINFO
  struct mallinfo info= mallinfo();
  printf("\nMemory status:\n\
Non-mmapped space allocated from system: %d\n\
Number of free chunks:			 %d\n\
Number of fastbin blocks:		 %d\n\
Number of mmapped regions:		 %d\n\
Space in mmapped regions:		 %d\n\
Maximum total allocated space:		 %d\n\
Space available in freed fastbin blocks: %d\n\
Total allocated space:			 %d\n\
Total free space:			 %d\n\
Top-most, releasable space:		 %d\n\
Estimated memory (with thread stack):    %ld\n",
	 (int) info.arena	,
	 (int) info.ordblks,
	 (int) info.smblks,
	 (int) info.hblks,
	 (int) info.hblkhd,
	 (int) info.usmblks,
	 (int) info.fsmblks,
	 (int) info.uordblks,
	 (int) info.fordblks,
	 (int) info.keepcost,
	 (long) (thread_count * thread_stack + info.hblkhd + info.arena));
#endif
  puts("");
  if (thd)
    thd->proc_info=0;
}
<|endoftext|>


<commit_before>// Tournament.hpp
// Pitches Players against each other in a last-player-out gun duel tournament.

#ifndef __TOURNAMENT_HPP__
#define __TOURNAMENT_HPP__

// Tournament Core
#include "ProxyPlayer.hpp"
#include "GunDuel.hpp"

// Necessary classes
#include <iomanip>
#include <memory>
#include <algorithm>
#include <limits>
#include <numeric>>
#include <chrono>
#include <random>

// Class responsible for a tournament.
template <class Pool>
class Tournament final
{
public:
	// Scorecard for a player.
	struct ScoreCard
	{
		// Unique player identifier.
		size_t identifier;
		// Is player still alive?
		bool alive;
		// Points in current round;
		int point;
		// Points in current round;
		int pointTotal;
		// How many rounds has the player survived?
		size_t survival;
		// How many points has the player gained in each round?
		std::vector<int> history;
	};

public:
	// Initializes a tournament.
	Tournament(size_t repetition = 100)
		: mSize(Pool::size()), mRepetition(repetition), mScores(mSize)
	{
		// Randomly assign identifier.
		std::vector<size_t> identifiers;
		for (size_t index = 0; index < mSize; ++index)
			identifiers.push_back(index);
		unsigned seed = (unsigned)std::chrono::system_clock::now().time_since_epoch().count();
		std::shuffle(identifiers.begin(), identifiers.end(), std::default_random_engine(seed));

		// Initialize players.
		for (size_t index = 0; index < mSize; ++index)
		{
			ScoreCard &sc = mScores[index];
			sc.identifier = identifiers[index];
			sc.alive = true;
			sc.point = 0;
			sc.pointTotal = 0;
			sc.survival = 0;
		}
	}

public:
	// Run the tournament!
	void run()
	{
		size_t round = 0;
		while (getPlayerRemaining() > 1)
		{
			startRound();
			for (size_t turn = 0; turn < mRepetition; ++turn)
			{
				for (size_t indexA = 0; indexA < mSize - 1; ++indexA)
				{
					if (!mScores[indexA].alive) continue;
					for (size_t indexB = indexA + 1; indexB < mSize; ++indexB)
					{
						if (!mScores[indexB].alive) continue;
						performDuel(indexA, indexB);
					}
				}
			}
			endRound();
			printScore();
		}
		printScoreBoard();
	}

private:

	// Perform a duel.
	void performDuel(size_t a, size_t b)
	{
		size_t identifierA = mScores[a].identifier;
		size_t identifierB = mScores[b].identifier;
		std::unique_ptr<Player> playerA = Pool::newPlayer(a, identifierB);
		std::unique_ptr<Player> playerB = Pool::newPlayer(b, identifierA);
		GunDuel duel(*playerA, *playerB);
		GunDuel::Outcome status = duel.fight();
		switch (status)
		{
		case GunDuel::AWIN:
			mScores[a].point += 1;
			mScores[a].pointTotal += 1;
			break;
		case GunDuel::BWIN:
			mScores[b].point += 1;
			mScores[b].pointTotal += 1;
			break;
		}
	}

	// Declare the start of a round.
	void startRound()
	{
		// Set all points to zero.
		std::for_each(mScores.begin(), mScores.end(), [](ScoreCard &sc) -> void {
			sc.point = 0;
		});
	}

	// Declare the end of a round.
	void endRound()
	{
		// Get the minimum score.
		int minPoint = std::numeric_limits<int>::max();
		int minPointTotal = std::numeric_limits<int>::max();
		std::for_each(mScores.begin(), mScores.end(), [&](ScoreCard const &sc) -> void {
			if (sc.alive && sc.point < minPoint)
			{
				minPoint = sc.point;
			}
			if (sc.alive && sc.pointTotal < minPointTotal)
			{
				minPointTotal = sc.pointTotal;
			}
		});

		// Eliminate remaining players who have the lowest score.
		std::for_each(mScores.begin(), mScores.end(), [&](ScoreCard &sc) -> void {
			if (!sc.alive) return;
			// Only loop through players that are alive.
			if (sc.point >= minPoint && sc.pointTotal > minPointTotal)
			{
				// Advance player to next round.
				sc.history.push_back(sc.point);
				sc.survival++;
			}
			else
			{
				// Remove player from tournament.
				sc.alive = false;
			}
		});
	}

private:
	// Get the number of remaining players
	size_t getPlayerRemaining() const
	{
		return std::count_if(mScores.begin(), mScores.end(), [](ScoreCard const &s) -> bool {
			return s.alive;
		});
	}

	// Print score.
	void printScore() const
	{
		std::cout << " :: ScoreBoard" << std::endl;
		size_t index = 0;
		std::for_each(mScores.begin(), mScores.end(), [&index](ScoreCard const &sc) -> void {
			std::cout << "    " << (index++)
				<< " ";
			if (sc.alive)
				std::cout << "ALIVE";
			else
				std::cout << "-----";
			std::cout << " " << std::setw(6) << sc.point << "/"
				<< std::setw(6) << sc.pointTotal
				<< " " << sc.survival << std::endl;
		});
	}

	// Print scoreboard.
	void printScoreBoard() const
	{
		std::cout << " :: Final Scoreboard" << std::endl;
		for (size_t index = 0; index < mSize; ++index)
		{
			ScoreCard const &sc = mScores[index];

			std::cout << "     Pool #" << index
				<< " survived " << std::setw(3) << sc.survival
				<< " rounds with " << sc.pointTotal << " total points." << std::endl;
		}
	}

private:
	// Size of tournament.
	const size_t mSize;

	// Number of duel between every two players in each round of tournament.
	size_t mRepetition;

	// Keeps track of the scoreboard.
	std::vector<ScoreCard> mScores;
};

#endif // ! __TOURNAMENT_HPP__<commit_msg>Remove extra > in includes. Credit to Matteo Italia.<commit_after>// Tournament.hpp
// Pitches Players against each other in a last-player-out gun duel tournament.

#ifndef __TOURNAMENT_HPP__
#define __TOURNAMENT_HPP__

// Tournament Core
#include "ProxyPlayer.hpp"
#include "GunDuel.hpp"

// Necessary classes
#include <iomanip>
#include <memory>
#include <algorithm>
#include <limits>
#include <numeric>
#include <chrono>
#include <random>

// Class responsible for a tournament.
template <class Pool>
class Tournament final
{
public:
	// Scorecard for a player.
	struct ScoreCard
	{
		// Unique player identifier.
		size_t identifier;
		// Is player still alive?
		bool alive;
		// Points in current round;
		int point;
		// Points in current round;
		int pointTotal;
		// How many rounds has the player survived?
		size_t survival;
		// How many points has the player gained in each round?
		std::vector<int> history;
	};

public:
	// Initializes a tournament.
	Tournament(size_t repetition = 100)
		: mSize(Pool::size()), mRepetition(repetition), mScores(mSize)
	{
		// Randomly assign identifier.
		std::vector<size_t> identifiers;
		for (size_t index = 0; index < mSize; ++index)
			identifiers.push_back(index);
		unsigned seed = (unsigned)std::chrono::system_clock::now().time_since_epoch().count();
		std::shuffle(identifiers.begin(), identifiers.end(), std::default_random_engine(seed));

		// Initialize players.
		for (size_t index = 0; index < mSize; ++index)
		{
			ScoreCard &sc = mScores[index];
			sc.identifier = identifiers[index];
			sc.alive = true;
			sc.point = 0;
			sc.pointTotal = 0;
			sc.survival = 0;
		}
	}

public:
	// Run the tournament!
	void run()
	{
		size_t round = 0;
		while (getPlayerRemaining() > 1)
		{
			startRound();
			for (size_t turn = 0; turn < mRepetition; ++turn)
			{
				for (size_t indexA = 0; indexA < mSize - 1; ++indexA)
				{
					if (!mScores[indexA].alive) continue;
					for (size_t indexB = indexA + 1; indexB < mSize; ++indexB)
					{
						if (!mScores[indexB].alive) continue;
						performDuel(indexA, indexB);
					}
				}
			}
			endRound();
			printScore();
		}
		printScoreBoard();
	}

private:

	// Perform a duel.
	void performDuel(size_t a, size_t b)
	{
		size_t identifierA = mScores[a].identifier;
		size_t identifierB = mScores[b].identifier;
		std::unique_ptr<Player> playerA = Pool::newPlayer(a, identifierB);
		std::unique_ptr<Player> playerB = Pool::newPlayer(b, identifierA);
		GunDuel duel(*playerA, *playerB);
		GunDuel::Outcome status = duel.fight();
		switch (status)
		{
		case GunDuel::AWIN:
			mScores[a].point += 1;
			mScores[a].pointTotal += 1;
			break;
		case GunDuel::BWIN:
			mScores[b].point += 1;
			mScores[b].pointTotal += 1;
			break;
		}
	}

	// Declare the start of a round.
	void startRound()
	{
		// Set all points to zero.
		std::for_each(mScores.begin(), mScores.end(), [](ScoreCard &sc) -> void {
			sc.point = 0;
		});
	}

	// Declare the end of a round.
	void endRound()
	{
		// Get the minimum score.
		int minPoint = std::numeric_limits<int>::max();
		int minPointTotal = std::numeric_limits<int>::max();
		std::for_each(mScores.begin(), mScores.end(), [&](ScoreCard const &sc) -> void {
			if (sc.alive && sc.point < minPoint)
			{
				minPoint = sc.point;
			}
			if (sc.alive && sc.pointTotal < minPointTotal)
			{
				minPointTotal = sc.pointTotal;
			}
		});

		// Eliminate remaining players who have the lowest score.
		std::for_each(mScores.begin(), mScores.end(), [&](ScoreCard &sc) -> void {
			if (!sc.alive) return;
			// Only loop through players that are alive.
			if (sc.point >= minPoint && sc.pointTotal > minPointTotal)
			{
				// Advance player to next round.
				sc.history.push_back(sc.point);
				sc.survival++;
			}
			else
			{
				// Remove player from tournament.
				sc.alive = false;
			}
		});
	}

private:
	// Get the number of remaining players
	size_t getPlayerRemaining() const
	{
		return std::count_if(mScores.begin(), mScores.end(), [](ScoreCard const &s) -> bool {
			return s.alive;
		});
	}

	// Print score.
	void printScore() const
	{
		std::cout << " :: ScoreBoard" << std::endl;
		size_t index = 0;
		std::for_each(mScores.begin(), mScores.end(), [&index](ScoreCard const &sc) -> void {
			std::cout << "    " << (index++)
				<< " ";
			if (sc.alive)
				std::cout << "ALIVE";
			else
				std::cout << "-----";
			std::cout << " " << std::setw(6) << sc.point << "/"
				<< std::setw(6) << sc.pointTotal
				<< " " << sc.survival << std::endl;
		});
	}

	// Print scoreboard.
	void printScoreBoard() const
	{
		std::cout << " :: Final Scoreboard" << std::endl;
		for (size_t index = 0; index < mSize; ++index)
		{
			ScoreCard const &sc = mScores[index];

			std::cout << "     Pool #" << index
				<< " survived " << std::setw(3) << sc.survival
				<< " rounds with " << sc.pointTotal << " total points." << std::endl;
		}
	}

private:
	// Size of tournament.
	const size_t mSize;

	// Number of duel between every two players in each round of tournament.
	size_t mRepetition;

	// Keeps track of the scoreboard.
	std::vector<ScoreCard> mScores;
};

#endif // ! __TOURNAMENT_HPP__<|endoftext|>


<commit_before>/* Here is how the code is produced
  1) Get on an airplane with Android phone
  2) Install 'C++ Compiler IDE' from the Play Store
  3) Sometimes it is possible to Google for some code snippets but sometimes not.
     But it is not documented what version of C++ is being written.
  4) It is very difficult to enter code because extra keystroke attempts are needed to switch
     between alphabetic, numeric, and symbol
Therefore the effort was quite heroic. */

#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>  // for random seed
#include <vector>
#include <algorithm> // to sort using vector and algorithm got accomplished only partly

using namespace std;

char grid[15][15]; // the board to square up
int gridx[100];
int gridy[100];  // row, col coords for each tile on board

class Square
{
    // represents a 5x5 square, a sub-region of the 15x15 grid.
    public:
       int row; // 0..10
       int col;  // 0..10
       int tilecount;
       int cost;  // would be 25 - tilecount.
};

// blah bbbb bbbb bbbbb llll aasas hhhhh

Square all_squares[121]; // each 5x5 square

std::vector<Square> v_squares (all_squares, all_squares+121);

std::string letters  ("AAAAAAAAABBCCDDDDEEEEEEEEEEEEFFGGGHHIIIIIIIIIJKLLLLMMNNNNNNOOOOOOOO??PPQRRRRRRSSSSTTTTTTUUUUVVWWXYYZ");

// Function to randomize the initial position
int initGrid() {

   time_t seconds;
   time(&seconds);
   srand((unsigned int) seconds);

    for (int i=0; i<15; i++) {
        for (int j=0; j<15; j++) {
            grid[i][j] = '_';
    }}

  for (int i =0; i<100;i++)
    {
        for (char g='.';g == '.';)
        {
            int b = rand() % 15;
            int c = rand() % 15;
            if (grid[b][c] == '_')
            {
                g = letters[i];
                grid[b][c] = g;
               gridx[i]=b;
                gridy[i]=c;
             }
        }
    }

   return 0;
}

// version 0.1 movecost is number of moved tiles
// find set of four 5x5 blocks containing maximum number of tiles
int movecost(int a, int b, int u, int v)
{
   if (a==u && b==v)
   {
      return 0;
   } else {
      //return 2 + max(abs(a-u), abs(b-v));
      return 1;
   }
}

// Function to inefficiently determine the cost, given it's the indicator cost function, of moving tiles into any given square
int doCount()
{
   int square_index = 0;
   for (int i=0; i<11; i++)
   {
      for (int j=0; j<11; j++)
      {
         int tcount = 0;
         for (int k=0; k<5;k++)
         {
            for (int m=0; m<5; m++)
            {
                if (grid[i+k][j+m] !='_')
                {
                      tcount ++; // todo: 5x speedup
                }
           }
        }
// make a 5x5 square here, and add it to the array
       Square* sq = all_squares + square_index++;

        sq->row = i;
        sq->col = j;
        sq->tilecount = tcount;
        sq->cost = 25 - tcount;

   // cout <<  totalcost << ' ';
   }
  // cout << endl;
}
   return 0;
}

// This uses bubble sort so the list of 5x5 squares is ordered from lowest cost to highest cost.
// todo: i think a better bubble sort might move the bubble more than 1 spot at a time.
int doSort() {
  for (int count=0; count < 121; count++) {
    for (int p= 0; p< 120; p++) {
      Square low_cost_square = all_squares[p+1];
      if (all_squares[p].cost < low_cost_square.cost) {
         all_squares[p+1] = all_squares[p];
         all_squares[p] = low_cost_square;
         //cout <<  squareone.cost << '!';
      }
    }
  }
}

int showGrid() {
    for (int i=0; i<15; i++)
    {
        for (int j= 0; j<15; j++)
        {
             cout << grid[i][ j ];
        }
        cout << endl;
    }
    return 0;
}

int showSorted() {

    for (int k=0; k<50; k++) {
        //Square sq = v_squares.component(k);
        Square sq = all_squares[k];
        cout << '(' <<  sq.row << ',' << sq.col << ','  << sq.cost  << ") ";
    }
   return 0;
}

// Does square p overlap square q? (referring to the global all_squares array)
bool overlap2(int p, int q) {
    return (abs(all_squares[p].row - all_squares[q].row)<5 && abs(all_squares[p].col - all_squares[q].col)<5);
}

// Do any of the four squares a, b, c, d overlap?  (Variables changed more often in the iteration are checked before others)
bool overlap(int a, int b, int c, int d) {
    return overlap2(d,c) || overlap2(d,b) ||overlap2(d,a) ||overlap2(c,b) ||overlap2(c,a) ||overlap2(b,a) ;
}

int main(){

    cout<<("Squaring Tiles - 0.1 by Kevin Leeds\n"); // Egotizing

    initGrid();  // randomize

   showGrid();

//
// v0.1 cost of squaring is number of tiles not in the four squares, so maximize the tile count inside them
// Work with a list all the possible 5x5 squares, sorted from lowest cost to highest
// Inspect all combinations of four of those.  Iterate to gradually increase the sum of the four costs ...
//    Don't look at higher cost solutions til various combinations have been inspected
//    That cutoff quantity is called "tiles_restart" in the program.
//    Then all that has to be done is locate a set that does not have overlaps - the first one encountered will be the best answer.

// If the cost function is more complicated then the search will not be so simple,
//   because the location of each region will affect the cost amount of itself and the other ones too.

    doCount();

   // std::sort (v_squares.begin(), v_squares.end(), square_lessthan);

   doSort();

 //  showSorted();

   // do complicated loop to search for best combination of four squares
    // simplified by the fact they don't interact to change each other's cost in v 0.1
    // tiles_limit is the max "cost" to consider (cost is perverse - todo: rename it)

    // todo: improve the iteration so it does not re-do all the work each time the target is relaxed
    // and also make it more readable I hope, maybe by abstracting the iterator or pre-computing somehow.

    int a=0;
    int b=a+1;
    int c=b+1;
    int d=c+1;   // start optimistically with the four best squares, but likely they will overlap
    int tiles_restart = all_squares[a].cost +all_squares[b].cost + all_squares[c].cost + all_squares[d].cost;
     //cout << "hope for "+tiles_restart;

    // it starts out optimistic but it gets overlaps
    // it knows it can get tiles_restart but then they overlap
    // so it tries to find another combination without giving up its hope (or a target)
    // if that doesn't work it relaxes its hope

    while (overlap(a,b,c,d)) {
        // conditions are
        // 121>d>c>b>a
        //
        // if tiles_inside unavoidably decreases to less than restart value, start back at 0,1,2,3
        // note 'cost' is actually the tile count, not the cost of moving, so try to maximize it without overlapping here
        int ta = all_squares[a].cost;
        int tb = ta + all_squares[b].cost;
        int tc = tb + all_squares[c].cost;

        // increase d if not exceed
        // this is a 4-nested loop, for upper triangle, a<b<c<d, d ranges from c+1 to end of array, but
        //   if we notice we are outside the target then iterate an earlier variable instead.  this is
        //   inefficient but it does work fast enough to enjoy the output

        if (d<120 && tc+all_squares[d+1].cost <= tiles_restart) {
            d++;
            //cout << 'd';
         } else if (c < 119 && tb+all_squares[c+1].cost+all_squares[c+2].cost <= tiles_restart){
            c++;
            d= c+1;
           // cout << 'c';
         } else if (b<118 && ta + all_squares[b+1].cost + all_squares[b+2].cost+all_squares[b+3].cost <= tiles_restart) {
            b++;
            c=b+1;
            d=c+1;
            //cout << 'b';
         } else if (a<117 && all_squares[a+1].cost+all_squares[a+2].cost+all_squares[a+3].cost+all_squares[a+4].cost <= tiles_restart ) {
            a++;
            b=a+1;
            c=b+1;
            d=c+1;
            //cout << 'a';
         } else {
            a=1;
            b=a+1;
            c=b+1;
            d=c+1;
            tiles_restart++;
            //cout << "Hoping for " << tiles_restart << "\n";
         }

       // cout << a << ' ' << b << ' ' << c << ' ' << d << '\n';

    }

   // cout << "Answer:\n";
 //  cout << "a,b,c,d=" << a << "," << b << "," << c << "," << d << "\n";
    cout << '(' << all_squares[a].row << ',' << all_squares[a].col << ") =" << all_squares[a].cost << " ";

cout << '(' << all_squares[b].row << ',' << all_squares[b].col << ") =" << all_squares[b].cost << " ";
cout << '(' << all_squares[c].row << ',' << all_squares[c].col << ") =" << all_squares[d].cost << " ";
cout << '(' << all_squares[d].row << ',' << all_squares[d].col << ") =" << all_squares[d].cost << " ";

cout << "total tiles to move is " << all_squares[a].cost + all_squares[b].cost + all_squares[c].cost + all_squares[d].cost << ".\n";

    return 0;
}

<commit_msg>The sort now uses a Vector sort<commit_after>/* version 0.2
   attempt to optimize version 0.1 just for fun of course.
*/

#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>  // for random seed
#include <vector>
#include <algorithm> // to sort using vector and algorithm got accomplished only partly

using namespace std;

char grid[15][15]; // the board to square up
size_t gridx[100];
size_t gridy[100];  // row, col coords for each tile on board

class Square
{
    // represents a 5x5 square, a sub-region of the 15x15 grid.
    public:
       size_t row; // 0..10
       size_t col;  // 0..10
       size_t tilecount;
       size_t cost;  // would be 25 - tilecount.
};

std::vector<Square> all_squares (121);  // each 5x5 square

std::string letters  ("AAAAAAAAABBCCDDDDEEEEEEEEEEEEFFGGGHHIIIIIIIIIJKLLLLMMNNNNNNOOOOOOOO??PPQRRRRRRSSSSTTTTTTUUUUVVWWXYYZ");

// Function to randomize the initial position
int initGrid() {

   time_t seconds;
   time(&seconds);
   srand((unsigned int) seconds);

    for (size_t i=0; i<15; i++) {
        for (size_t j=0; j<15; j++) {
            grid[i][j] = '_';
    }}

  for (size_t i =0; i<100;i++)
    {
        for (char g='.';g == '.';)
        {
            size_t b = rand() % 15;
            size_t c = rand() % 15;
            if (grid[b][c] == '_')
            {
                g = letters[i];
                grid[b][c] = g;
               gridx[i]=b;
                gridy[i]=c;
             }
        }
    }

   return 0;
}

// Function to inefficiently determine the cost, given it's the indicator cost function, of moving tiles into any given square
int doCount()
{
    size_t square_index = 0;
    for (size_t i=0; i<11; i++)
    {
        for (size_t j=0; j<11; j++)
        {
           size_t tcount = 0;
           for (size_t k=0; k<5;k++)
           {
              for (size_t m=0; m<5; m++)
              {
                  if (grid[i+k][j+m] !='_')
                  {
                      tcount ++; // todo: 5x speedup
                  }
              }
           }

	// Set up the square in the vector of squares
           //all_squares[square_index];
           all_squares[square_index].row = i;
           all_squares[square_index].col = j;
           all_squares[square_index].tilecount = tcount;
           all_squares[square_index].cost = 25 - tcount;

           //cout <<  "Counted " << i << ',' << j << ' ' << tcount << "\n";

           square_index++;
       }
    }

    return 0;
}

// This uses bubble sort so the list of 5x5 squares is ordered from lowest cost to highest cost.
// todo: i think a better bubble sort might move the bubble more than 1 spot at a time.
int doBubbleSort() {
  for (size_t count=0; count < 121; count++) {
    for (size_t p= 0; p< 120; p++) {
      Square low_cost_square = all_squares[p+1];
      if (all_squares[p].cost < low_cost_square.cost) {
         all_squares[p+1] = all_squares[p];
         all_squares[p] = low_cost_square;
         //cout <<  squareone.cost << '!';
      }
    }
  }
}

bool square_compare(Square sq1, Square sq2) {
    return (sq1.cost < sq2.cost);
}

int doSort() {
   std::sort(all_squares.begin(), all_squares.end(), square_compare);
}

int showGrid() {
    for (size_t i=0; i<15; i++)
    {
        for (size_t j= 0; j<15; j++)
        {
             cout << grid[i][ j ];
        }
        cout << endl;
    }
    return 0;
}

int showSorted() {

    for (size_t k=0; k<121; k++) {
        Square sq = all_squares[k];
        cout << "square i,j,cost: (" <<  sq.row << ',' << sq.col << ','  << sq.cost  << ")" << endl;
    }
   return 0;
}

size_t absval(size_t a) {
	return (a >= 0 ? a : a);
}

// Does square p overlap square q? (referring to the global all_squares array)
bool overlap2(size_t p, size_t q) {
    return (absval(all_squares[p].row - all_squares[q].row)<5 && absval(all_squares[p].col - all_squares[q].col)<5);
}

// Do any of the four squares a, b, c, d overlap?  (Variables changed more often in the iteration are checked before others)
bool overlap(size_t a, size_t b, size_t c, size_t d) {
    return overlap2(d,c) || overlap2(d,b) ||overlap2(d,a) ||overlap2(c,b) ||overlap2(c,a) ||overlap2(b,a) ;
}

int doSolution() {

    size_t a=0;
    size_t b=a+1;
    size_t c=b+1;
    size_t d=c+1;   // start optimistically with the four best squares, but likely they will overlap
    size_t tiles_restart = all_squares[a].cost +all_squares[b].cost + all_squares[c].cost + all_squares[d].cost;
     //cout << "hope for "+tiles_restart;

    // it starts out optimistic but it gets overlaps
    // it knows it can get tiles_restart but then they overlap
    // so it tries to find another combination without giving up its hope (or a target)
    // if that doesn't work it relaxes its hope

    while (overlap(a,b,c,d)) {
        // conditions are
        // 121>d>c>b>a
        //
        // if tiles_inside unavoidably decreases to less than restart value, start back at 0,1,2,3
        // note 'cost' is actually the tile count, not the cost of moving, so try to maximize it without overlapping here
        size_t ta = all_squares[a].cost;
        size_t tb = ta + all_squares[b].cost;
        size_t tc = tb + all_squares[c].cost;

        // increase d if not exceed
        // this is a 4-nested loop, for upper triangle, a<b<c<d, d ranges from c+1 to end of array, but
        //   if we notice we are outside the target then iterate an earlier variable instead.  this is
        //   inefficient but it does work fast enough to enjoy the output

        if (d<120 && tc+all_squares[d+1].cost <= tiles_restart) {
            d++;
            cout << 'd';
         } else if (c < 119 && tb+all_squares[c+1].cost+all_squares[c+2].cost <= tiles_restart){
            c++;
            d= c+1;
            cout << 'c';
         } else if (b<118 && ta + all_squares[b+1].cost + all_squares[b+2].cost+all_squares[b+3].cost <= tiles_restart) {
            b++;
            c=b+1;
            d=c+1;
            cout << 'b';
         } else if (a<117 && all_squares[a+1].cost+all_squares[a+2].cost+all_squares[a+3].cost+all_squares[a+4].cost <= tiles_restart ) {
            a++;
            b=a+1;
            c=b+1;
            d=c+1;
            cout << 'a';
         } else {
            a=1;
            b=a+1;
            c=b+1;
            d=c+1;
            tiles_restart++;
            cout << "\nHoping for " << tiles_restart << "\n";
         }

        //cout << a << ' ' << b << ' ' << c << ' ' << d << '\n';

    }

    cout << "\nAnswer:\n";
    //  cout << "a,b,c,d=" << a << "," << b << "," << c << "," << d << "\n";
    cout << '(' << all_squares[a].row << ',' << all_squares[a].col << ") =" << all_squares[a].cost << " ";

    cout << '(' << all_squares[b].row << ',' << all_squares[b].col << ") =" << all_squares[b].cost << " ";
    cout << '(' << all_squares[c].row << ',' << all_squares[c].col << ") =" << all_squares[d].cost << " ";
    cout << '(' << all_squares[d].row << ',' << all_squares[d].col << ") =" << all_squares[d].cost << " ";

    cout << "total tiles to move is " << all_squares[a].cost + all_squares[b].cost + all_squares[c].cost + all_squares[d].cost << ".\n";
}

int main(){

    cout<<("Squaring Tiles - 0.1 by Kevin Leeds\n"); // Egotizing

    initGrid();  // randomize

    showGrid();

//
// v0.1 cost of squaring is number of tiles not in the four squares, so maximize the tile count inside them
// Work with a list all the possible 5x5 squares, sorted from lowest cost to highest
// Inspect all combinations of four of those.  Iterate to gradually increase the sum of the four costs ...
//    Don't look at higher cost solutions til various combinations have been inspected
//    That cutoff quantity is called "tiles_restart" in the program.
//    Then all that has to be done is locate a set that does not have overlaps - the first one encountered will be the best answer.

// If the cost function is more complicated then the search will not be so simple,
//   because the location of each region will affect the cost amount of itself and the other ones too.

   doCount();

   //showSorted();

   //cout << " - - - - -- - - - -- \n";

   doSort();

   showSorted();

   // do complicated loop to search for best combination of four squares
    // simplified by the fact they don't interact to change each other's cost in v 0.1
    // tiles_limit is the max "cost" to consider (cost is perverse - todo: rename it)

    // todo: improve the iteration so it does not re-do all the work each time the target is relaxed
    // and also make it more readable I hope, maybe by abstracting the iterator or pre-computing somehow.

   doSolution();

    return 0;
}
<|endoftext|>


<commit_before>// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include "ucs2_utf16.h"
// --------------------------------------------------------------------------
std::codecvt_base::result Arabica::Internal::utf16_2_ucs2(bool be,
                       char const* from, char const* from_end, char const*& from_next,
                       wchar_t* to, wchar_t* to_limit, wchar_t*& to_next)
{
  from_next = from;
  to_next = to;

  while((from_next+1 < from_end) && (to_next < to_limit))
	{
    wchar_t b1 = static_cast<wchar_t>(*from_next++);
    wchar_t b2 = static_cast<wchar_t>(*from_next++);

    *to_next++ = be ? ((b1 << 8) + b2) : ((b2 << 8) + b1);
  } // while

  return (from_next == from_end) ? std::codecvt_base::ok : std::codecvt_base::partial;
} // utf16_2_ucs2

std::codecvt_base::result Arabica::Internal::ucs2_2_utf16(bool be,
                        wchar_t const* from, wchar_t const* from_end, wchar_t const*& from_next,
                        char* to, char* to_limit, char*& to_next)
{
  from_next = from;
  to_next = to;

  while(from_next < from_end)
  {
    if(to_next + 2 >= to_limit)
      return std::codecvt_base::partial;

    wchar_t ch = *from_next;
    unsigned char lb = static_cast<unsigned char>(ch & 0xFF);
    unsigned char hb = static_cast<unsigned char>((ch >> 8) & 0xFF);

    if(be)
    { // big endian
      *to_next++ = hb;
      *to_next++ = lb;
    }
    else
    { // little endian
      *to_next++ = lb;
      *to_next++ = hb;
    }

    ++from_next;
  } // while(from_next < from_end)

  return std::codecvt_base::ok;
} // ucs2_2_utf8

// end of file
<commit_msg>bug fix<commit_after>// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include "ucs2_utf16.h"
// --------------------------------------------------------------------------
std::codecvt_base::result Arabica::Internal::utf16_2_ucs2(bool be,
                       char const* from, char const* from_end, char const*& from_next,
                       wchar_t* to, wchar_t* to_limit, wchar_t*& to_next)
{
  from_next = from;
  to_next = to;

  while((from_next+1 < from_end) && (to_next < to_limit))
	{
    wchar_t b1 = static_cast<unsigned char>(*from_next++);
    wchar_t b2 = static_cast<unsigned char>(*from_next++);

    *to_next++ = be ? ((b1 << 8) + b2) : ((b2 << 8) + b1);
  } // while

  return (from_next == from_end) ? std::codecvt_base::ok : std::codecvt_base::partial;
} // utf16_2_ucs2

std::codecvt_base::result Arabica::Internal::ucs2_2_utf16(bool be,
                        wchar_t const* from, wchar_t const* from_end, wchar_t const*& from_next,
                        char* to, char* to_limit, char*& to_next)
{
  from_next = from;
  to_next = to;

  while(from_next < from_end)
  {
    if(to_next + 2 >= to_limit)
      return std::codecvt_base::partial;

    wchar_t ch = *from_next;
    unsigned char lb = static_cast<unsigned char>(ch & 0xFF);
    unsigned char hb = static_cast<unsigned char>((ch >> 8) & 0xFF);

    if(be)
    { // big endian
      *to_next++ = hb;
      *to_next++ = lb;
    }
    else
    { // little endian
      *to_next++ = lb;
      *to_next++ = hb;
    }

    ++from_next;
  } // while(from_next < from_end)

  return std::codecvt_base::ok;
} // ucs2_2_utf8

// end of file
<|endoftext|>


<commit_before>#include "listservices.h"
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

using namespace std;

struct ScientistComparison {
    bool operator ()(scientistList i, scientistList j) {return (i.fullName() < j.fullName());}
};

string listServices::getFirstNameFromList(int i)
{
    string name;
    name = _computerScientists[i].getFirstName();
    return name;
}

string listServices::getLastNameFromList(int i)
{
    string name;
    name = _computerScientists[i].getLastName();
    return name;
}

string listServices::fullNameFromList(int i) const
{
    string a = _computerScientists[i].fullName();
    return a;
}

int listServices::dobFromList(int i) const
{
    int a = _computerScientists[i].dob();
    return a;
}

int listServices::dodFromList(int i) const
{
    int a = _computerScientists[i].dod();
    return a;
}

char listServices::getSexFromList(int i) const
{
    char a = _computerScientists[i].getSex();
    return a;
}

int listServices::getAwardsFromList(int i) const
{
    int a = _computerScientists[i].getAwards();
    return a;
}

listServices::listServices()
{
        scientistList nextScientist;
        nextScientist.readFile(_computerScientists);
}

vector<scientistList> listServices::sortByName()
{
    vector<scientistList> sortedByName;

    ScientistComparison cmp;

    std::sort(sortedByName.begin(), sortedByName.end(), cmp);

    return sortedByName;
}
vector<scientistList> listServices::sortByBirth()
{
    vector<scientistList> sortedList;
    int currentSmallest;

    for(unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        currentSmallest = _computerScientists[i].dob();
        for(unsigned int j = i; j < _computerScientists.size(); j++)
        {
           if(_computerScientists[i].dob() < currentSmallest)
           {
               scientistList temp;
               temp = _computerScientists[i];
               _computerScientists[i] = _computerScientists[j];
               _computerScientists[i] = temp;
               sortedList.push_back(temp);
           }
        }
    }
    return sortedList;
}

vector<scientistList>   listServices::sortByAlive()
{
    vector<scientistList> sortedList;
    int currentYear;

  for(unsigned int i = 0; i < _computerScientists.size(); i++)
  {
      currentYear = _computerScientists[i].dod();
      for(unsigned int j = i ; j < _computerScientists.size(); j++)
      {
          // if the year of death is listed as 0, the scientist is still alive.  This loop puts the living scientists first in the vector.
          if(_computerScientists[j].dod() == 0)
          {
              scientistList temp = _computerScientists[i];
              _computerScientists[i] = _computerScientists[j];
              _computerScientists[j] = temp;
          }

      }
  }
sortedList = _computerScientists;
return sortedList;
}

vector<scientistList>   listServices::sortByAward()
{

    vector<scientistList> sortedList;
    int currentSmallest;

    for(unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        currentSmallest = _computerScientists[i].getAwards();
        for(unsigned int j = i; j < _computerScientists.size(); j++)
        { //in the if sentence below, a 0 in getAwards indicates that the scientist has never received the award.
           if(_computerScientists[i].getAwards() < currentSmallest && _computerScientists[i].getAwards() != 0)
           {
               scientistList temp;
               temp = _computerScientists[i];
               _computerScientists[i] = _computerScientists[j];
               _computerScientists[i] = temp;
           }
        }
    }
    sortedList = _computerScientists;
    return sortedList;
}

void   listServices::addNew(string firstName, string lastName, char gender, int birthYear, int deathYear, int awardYear)
{
    scientistList newScientist(firstName, lastName, gender, birthYear, deathYear, awardYear);
    _computerScientists.push_back(newScientist);
}

vector<scientistList> listServices::searchLastName(string lastName)
{
    vector<scientistList> matchingLastNames;
    for (unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        if (lastName == _computerScientists[i].getLastName())
        {
            matchingLastNames.push_back(_computerScientists[i]);
        }
    }
    return matchingLastNames;
}

vector<scientistList> listServices::searchFirstName(string firstName)
{
    vector<scientistList> matchingFirstNames;
    for (unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        if (firstName == _computerScientists[i].getLastName())
        {
            matchingFirstNames.push_back(_computerScientists[i]);
        }
    }
    return matchingFirstNames;
}

vector<scientistList> listServices::searchBirth(int birthYear)
{
    vector<scientistList> matchingBirthYears;

    for(unsigned int i = 0; i < _computerScientists.size(); i++)
    {
      if (birthYear == _computerScientists[i].dob())
      {
          matchingBirthYears.push_back(_computerScientists[i]);
      }
    }

    return matchingBirthYears;
}

vector<scientistList> listServices::searchAlive(int deathYear)
{
    vector<scientistList> livingScientists;

    for(unsigned int k = 0; k < _computerScientists.size(); k++)
    {
        if(_computerScientists[k].dod() == 0)
        {
            livingScientists.push_back(_computerScientists[k]);
        }
    }
    return livingScientists;
}

vector<scientistList> listServices::searchAward(int awardYear)
{
    vector<scientistList> matchingAwardYear;
    for (unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        if (awardYear == _computerScientists[i].getAwards())
        {
            matchingAwardYear.push_back(_computerScientists[i]);
        }
    }
    return matchingAwardYear;
}

void listServices::changeTo(vector<scientistList> rhs)
{
    _computerScientists  = rhs;
}

int listServices::getSize ()
{
    return _computerScientists.size();
}

<commit_msg>Commented the listServices class<commit_after>#include "listservices.h"
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

using namespace std;

struct ScientistComparison {
    bool operator ()(scientistList i, scientistList j) {return (i.fullName() < j.fullName());}
};

string listServices::getFirstNameFromList(int i)
{
    string name;
    name = _computerScientists[i].getFirstName();
    return name;
}

string listServices::getLastNameFromList(int i)
{
    string name;
    name = _computerScientists[i].getLastName();
    return name;
}

string listServices::fullNameFromList(int i) const
{
    string a = _computerScientists[i].fullName();
    return a;
}

int listServices::dobFromList(int i) const
{
    int a = _computerScientists[i].dob();
    return a;
}

int listServices::dodFromList(int i) const
{
    int a = _computerScientists[i].dod();
    return a;
}

char listServices::getSexFromList(int i) const
{
    char a = _computerScientists[i].getSex();
    return a;
}

int listServices::getAwardsFromList(int i) const
{
    int a = _computerScientists[i].getAwards();
    return a;
}

listServices::listServices()
{
        scientistList nextScientist;
        nextScientist.readFile(_computerScientists);
}

vector<scientistList> listServices::sortByName()
{
    vector<scientistList> sortedByName;

    ScientistComparison cmp;

    std::sort(sortedByName.begin(), sortedByName.end(), cmp);

    return sortedByName;
}

//This function sorts the scientists by their birth year in ascending order.
//In every iteration it finds the lowest birth year, barring the one it found in the last loop and puts it in the index corresponding to the loop number.
vector<scientistList> listServices::sortByBirth()
{
    int currentSmallest;

    for(unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        currentSmallest = _computerScientists[i].dob();  //in the first iteration, the smallest number is the first number
        for(unsigned int j = i; j < _computerScientists.size(); j++)
        {
           if(_computerScientists[i].dob() < currentSmallest)
           {
               scientistList temp;
               temp = _computerScientists[i];
               _computerScientists[i] = _computerScientists[j];
               _computerScientists[i] = temp;
           }
        }
    }

    return _computerScientists;
}
//This function sorts the vector of scientists by status.  It puts all living scientists first in the vector.
vector<scientistList>   listServices::sortByAlive()
{
  for(unsigned int i = 0; i < _computerScientists.size(); i++)
  {
      int currentYear;
      currentYear = _computerScientists[i].dod();
      for(unsigned int j = i ; j < _computerScientists.size(); j++)
      {
          // if the year of death is listed as 0, the scientist is still alive.  This loop puts the living scientists first in the vector.
          if(_computerScientists[j].dod() == 0)
          {
              scientistList temp = _computerScientists[i];
              _computerScientists[i] = _computerScientists[j];
              _computerScientists[j] = temp;
          }

      }
  }
return _computerScientists;
}
// This function sorts the vector of scientists by what year they received the Turing award in ascending order.
//It puts the recipients of the award first, followed by those who did not receive it.
vector<scientistList>   listServices::sortByAward()
{

    vector<scientistList> sortedList;
    int currentSmallest;

    for(unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        currentSmallest = _computerScientists[i].getAwards();
        for(unsigned int j = i; j < _computerScientists.size(); j++)
        { //In the if sentence below, a 0 in getAwards indicates that the scientist has never received the award.
          //This if statement switches the current index being checked with the index we are attempting to put the next lowest year in
          //if and only if the scientist won the award before the scientist who is currently stored at that index.
           if(_computerScientists[i].getAwards() < currentSmallest && _computerScientists[i].getAwards() != 0)
           {
               scientistList temp;
               temp = _computerScientists[i];
               _computerScientists[i] = _computerScientists[j];
               _computerScientists[i] = temp;
           }
        }
    }
    sortedList = _computerScientists;
    return sortedList;
}
//This function adds a new scientist to the list.  It creates a new instance of scientistList by calling a constructor that adds a new entry to the .txt file.
void   listServices::addNew(string firstName, string lastName, char gender, int birthYear, int deathYear, int awardYear)
{
    scientistList newScientist(firstName, lastName, gender, birthYear, deathYear, awardYear);
    _computerScientists.push_back(newScientist);
}
//This function creates and returns a new vector containing only the scientists whose last names match the name being searched.
//The name being searched is the string that is taken in as an argument.
vector<scientistList> listServices::searchLastName(string lastName)
{
    vector<scientistList> matchingLastNames;
    for (unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        //If the names match, the scientist is added to the new vector.
        if (lastName == _computerScientists[i].getLastName())
        {
            matchingLastNames.push_back(_computerScientists[i]);
        }
    }
    return matchingLastNames;
}

//This function creates and returns a new vector containing only the scientists whose first names match the name being searched.
//The name being searched is the string that is taken in as an argument.
vector<scientistList> listServices::searchFirstName(string firstName)
{
    vector<scientistList> matchingFirstNames;
    for (unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        if (firstName == _computerScientists[i].getLastName())
        {
            matchingFirstNames.push_back(_computerScientists[i]);
        }
    }
    return matchingFirstNames;
}

//This function creates and returns a new vector containing only the scientists whose birth years match the year being searched.
//The year being searched is the integer that is taken in as an argument.
vector<scientistList> listServices::searchBirth(int birthYear)
{
    vector<scientistList> matchingBirthYears;

    for(unsigned int i = 0; i < _computerScientists.size(); i++)
    {
      if (birthYear == _computerScientists[i].dob())
      {
          matchingBirthYears.push_back(_computerScientists[i]);
      }
    }

    return matchingBirthYears;
}

//This function creates and returns a new vector containing only the scientists whose death years match the year being searched.
//The year being searched is the integer that is taken in as an argument.
vector<scientistList> listServices::searchAlive(int deathYear)
{
    vector<scientistList> matchingScientists;

    for(unsigned int k = 0; k < _computerScientists.size(); k++)
    {
        if(_computerScientists[k].dod() == deathYear)
        {
            matchingScientists.push_back(_computerScientists[k]);
        }
    }
    return matchingScientists;
}
//This function creates and returns a new vector containing only the scientists who received the Turing award in the year that is being searched.
//The year being searched is the integer that is taken in as an argument.
vector<scientistList> listServices::searchAward(int awardYear)
{
    vector<scientistList> matchingAwardYear;
    for (unsigned int i = 0; i < _computerScientists.size(); i++)
    {
        if (awardYear == _computerScientists[i].getAwards())
        {
            matchingAwardYear.push_back(_computerScientists[i]);
        }
    }
    return matchingAwardYear;
}

// This function is used to assign a vector rhs to another vector
void listServices::changeTo(vector<scientistList> rhs)
{
    _computerScientists  = rhs;
}

// This function returns the size of the vector in the listServices instance.
int listServices::getSize ()
{
    return _computerScientists.size();
}

<|endoftext|>