text:
/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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/>.
 */
#ifndef LIBBITCOIN_BLOCKCHAIN_LEVELDB_BLOCKCHAIN_HPP
#define LIBBITCOIN_BLOCKCHAIN_LEVELDB_BLOCKCHAIN_HPP

#include <bitcoin/blockchain/blockchain.hpp>

#include <boost/interprocess/sync/file_lock.hpp>
#include <leveldb/db.h>

#include <bitcoin/blockchain/organizer.hpp>
#include <bitcoin/utility/subscriber.hpp>
#include <bitcoin/threadpool.hpp>

namespace libbitcoin {

class leveldb_common;
typedef std::shared_ptr<leveldb_common> leveldb_common_ptr;

class leveldb_blockchain
  : public blockchain
{
public:
    // Used by internal components so need public definition here
    typedef subscriber<
        const std::error_code&, size_t, const block_list&, const block_list&>
            reorganize_subscriber_type;

    typedef std::function<void (const std::error_code)> start_handler;

    leveldb_blockchain(threadpool& pool);
    ~leveldb_blockchain();

    // Non-copyable
    leveldb_blockchain(const leveldb_blockchain&) = delete;
    void operator=(const leveldb_blockchain&) = delete;

    void start(const std::string& prefix, start_handler handle_start);
    void stop();

    void store(const block_type& block,
        store_block_handler handle_store);
    void import(const block_type& block, size_t height,
        import_block_handler handle_import);

    // fetch block header by height
    void fetch_block_header(size_t height,
        fetch_handler_block_header handle_fetch);
    // fetch block header by hash
    void fetch_block_header(const hash_digest& block_hash,
        fetch_handler_block_header handle_fetch);
    // fetch transaction hashes in block by height
    void fetch_block_transaction_hashes(size_t height,
        fetch_handler_block_transaction_hashes handle_fetch);
    // fetch transaction hashes in block by hash
    void fetch_block_transaction_hashes(const hash_digest& block_hash,
        fetch_handler_block_transaction_hashes handle_fetch);
    // fetch height of block by hash
    void fetch_block_height(const hash_digest& block_hash,
        fetch_handler_block_height handle_fetch);
    // fetch height of latest block
    void fetch_last_height(fetch_handler_last_height handle_fetch);
    // fetch transaction by hash
    void fetch_transaction(const hash_digest& transaction_hash,
        fetch_handler_transaction handle_fetch);
    // fetch height and offset within block of transaction by hash
    void fetch_transaction_index(const hash_digest& transaction_hash,
        fetch_handler_transaction_index handle_fetch);
    // fetch spend of an output point
    void fetch_spend(const output_point& outpoint,
        fetch_handler_spend handle_fetch);
    // fetch outputs, values and spends for an address.
    void fetch_history(const payment_address& address,
        fetch_handler_history handle_fetch, size_t from_height=0);

    void subscribe_reorganize(reorganize_handler handle_reorganize);

private:
    typedef std::atomic<size_t> seqlock_type;
    typedef std::unique_ptr<leveldb::DB> database_ptr;
    typedef std::unique_ptr<leveldb::Comparator> comparator_ptr;

    typedef std::function<bool (size_t)> perform_read_functor;

    bool initialize(const std::string& prefix);

    void begin_write();

    template <typename Handler, typename... Args>
    void finish_write(Handler handler, Args&&... args)
    {
        ++seqlock_;
        // seqlock is now even again.
        BITCOIN_ASSERT(seqlock_ % 2 == 0);
        handler(std::forward<Args>(args)...);
    }

    void do_store(const block_type& block,
        store_block_handler handle_store);
    void do_import(const block_type& block, size_t height,
        import_block_handler handle_import);

    // Uses sequence looks to try to read shared data.
    // Try to initiate asynchronous read operation. If it fails then
    // sleep for a small amount of time and then retry read operation.
    void fetch(perform_read_functor perform_read);

    template <typename Handler, typename... Args>
    bool finish_fetch(size_t slock, Handler handler, Args&&... args)
    {
        if (slock != seqlock_)
            return false;
        handler(std::forward<Args>(args)...);
        return true;
    }

    bool fetch_block_header_by_height(size_t height,
        fetch_handler_block_header handle_fetch, size_t slock);
    bool fetch_block_header_by_hash(const hash_digest& block_hash,
        fetch_handler_block_header handle_fetch, size_t slock);
    bool do_fetch_block_height(const hash_digest& block_hash,
        fetch_handler_block_height handle_fetch, size_t slock);
    bool do_fetch_last_height(
        fetch_handler_last_height handle_fetch, size_t slock);
    bool do_fetch_transaction(const hash_digest& transaction_hash,
        fetch_handler_transaction handle_fetch, size_t slock);
    bool do_fetch_transaction_index(const hash_digest& transaction_hash,
        fetch_handler_transaction_index handle_fetch, size_t slock);
    bool do_fetch_spend(const output_point& outpoint,
        fetch_handler_spend handle_fetch, size_t slock);
    bool do_fetch_history(const payment_address& address,
        fetch_handler_history handle_fetch, size_t from_height, size_t slock);

    io_service& ios_;
    // Queue for writes to the blockchain.
    async_strand strand_;
    // Queue for serializing reorganization handler calls.
    async_strand reorg_strand_;
    // Lock the database directory with a file lock.
    boost::interprocess::file_lock flock_;
    // seqlock used for writes.
    seqlock_type seqlock_;

    // Comparator to order blocks by height logically.
    // Otherwise the last block in the database
    // might not be the largest height in our blockchain.
    comparator_ptr height_comparator_;
    leveldb::Options open_options_;

    // Blocks indexed by height.
    //   block height -> block header + list(tx_hashes)
    database_ptr db_block_;
    // Block heights indexed by hash (a secondary lookup table).
    //   block hash -> block height
    database_ptr db_block_hash_;
    // Transactions indexed by hash.
    //   tx hash -> tx height + tx index + tx
    database_ptr db_tx_;
    // Lookup whether an output point is spent.
    // Value is the input point spend.
    //   outpoint -> inpoint spend
    database_ptr db_spend_;

    // Address to list of output points + values
    database_ptr db_credit_;
    // Address to list of spend input points.
    database_ptr db_debit_;

    leveldb_common_ptr common_;
    // Organize stuff
    orphans_pool_ptr orphans_;
    chain_keeper_ptr chain_;
    organizer_ptr organize_;

    reorganize_subscriber_type::ptr reorganize_subscriber_;
};

} // namespace libbitcoin

#endif

max_stars_repo_name: mousewu/bcclient

max_issues_repo_name: mousewu/bcclient

max_forks_repo_name: mousewu/bcclient


text:
//
//  Copyright 2012 MultiMC Contributors
//
//    Licensed 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 "insticonlist.h"

#include "resources/insticons.h"

#include "utils/apputils.h"

#include <wx/filename.h>
#include <wx/dir.h>
#include <boost/concept_check.hpp>
#include <iostream>

#include "appsettings.h"
// #define DEBUG_ICONS

wxString InstIconList::getRealIconKeyForEasterEgg ( wxString key, wxString name )
{
	if (key == "default")
	{
		if (name.Lower().Contains("btw") ||
			name.Lower().Contains("better then wolves") || // Because some people are stupid :D
			name.Lower().Contains("better than wolves"))
		{
			return "herobrine";
		}
		else if (name.Lower().Contains("direwolf"))
		{
			return "enderman";
		}
	}
	return key;
}

InstIconList* InstIconList::pInstance = 0;

const int allowedImgExtensionsCount = 5;
const wxString allowedImgExtensions[] =
{
	".bmp",
	".gif",
	".jpg", ".jpeg",
	".png",
};

struct InstIconDef
{
	InstIconDef(wxString key, wxString name, wxImage image, wxImage image128)
	{
		this->name = name;
		this->key = key;
		this->image = image;
		this->image128 = image128;
	}
	InstIconDef(wxString key, wxString name, wxImage image)
	{
		this->name = name;
		this->key = key;
		this->image = image;
		this->image128 = image;
	}

	wxString name;
	wxString key;
	wxImage image;
	wxImage image128;
};

wxImage tintImage( wxImage to_colorize, wxColour col)
{
	wxImage highlightIcon(to_colorize.GetWidth(),to_colorize.GetHeight());
	bool do_alpha = false;
	if(to_colorize.HasAlpha())
	{
		highlightIcon.InitAlpha();
		do_alpha = true;
	}
	else if(to_colorize.HasMask())
	{
		highlightIcon.SetMaskFromImage(to_colorize,to_colorize.GetMaskRed(),to_colorize.GetMaskGreen(),to_colorize.GetMaskBlue());
	}
	for(int x = 0; x < highlightIcon.GetWidth(); x++)
	{
		for(int y = 0; y < highlightIcon.GetHeight(); y++)
		{
			to_colorize.GetData();
			unsigned char srcR = to_colorize.GetRed(x,y);
			unsigned char srcG = to_colorize.GetGreen(x,y);
			unsigned char srcB = to_colorize.GetBlue(x,y);
			highlightIcon.SetRGB(x,y,(srcR + col.Red())/2,(srcG + col.Green())/2, (srcB + col.Blue())/2);
			if(do_alpha)
				highlightIcon.SetAlpha(x,y,to_colorize.GetAlpha(x,y));
		}
	}
	return highlightIcon;
}

InstIconList::InstIconList(int width, int height, wxString customIconDirName)
{
	if (customIconDirName == wxEmptyString)
		customIconDirName = settings->GetIconsDir().GetFullPath();

	this->width = width;
	this->height = height;

	const InstIconDef builtInIcons[] =
	{
		InstIconDef("default", _("Default icon"), wxMEMORY_IMAGE(grass)),
		InstIconDef("grass", _("Grass block"), wxMEMORY_IMAGE(grass)),
		InstIconDef("dirt", _("Dirt block"), wxMEMORY_IMAGE(dirt)),
		InstIconDef("stone", _("Stone block"), wxMEMORY_IMAGE(stone)),
		InstIconDef("planks", _("Planks"), wxMEMORY_IMAGE(planks)),
		InstIconDef("iron", _("Solid iron"), wxMEMORY_IMAGE(iron)),
		InstIconDef("gold", _("Shiny gold"), wxMEMORY_IMAGE(gold)),
		InstIconDef("diamond", _("Diamond!"), wxMEMORY_IMAGE(diamond)),
		InstIconDef("tnt", _("TNT"), wxMEMORY_IMAGE(tnt)),
		InstIconDef("enderman",_("Enderman"), wxMEMORY_IMAGE(enderman)),
		InstIconDef("ftb-logo",_("FTB logo"), wxMEMORY_IMAGE(ftb_logo), wxMEMORY_IMAGE(ftb_logo128)),
		InstIconDef("ftb-glow",_("FTB glow"), wxMEMORY_IMAGE(ftb_glow), wxMEMORY_IMAGE(ftb_glow128)),
		InstIconDef("infinity",_("Infinity"), wxMEMORY_IMAGE(infinity), wxMEMORY_IMAGE(infinity128)),
		InstIconDef("netherstar",_("Nether Star"), wxMEMORY_IMAGE(netherstar), wxMEMORY_IMAGE(netherstar128)),
		InstIconDef("creeper",_("Creeper"), wxMEMORY_IMAGE(creeper), wxMEMORY_IMAGE(creeper128)),
		InstIconDef("square creeper",_("Square creeper"), wxMEMORY_IMAGE(squarecreeper), wxMEMORY_IMAGE(squarecreeper128)),
		InstIconDef("skeleton",_("Skeleton"), wxMEMORY_IMAGE(skeleton), wxMEMORY_IMAGE(skeleton128)),
		InstIconDef("gear",_("Golden gear"), wxMEMORY_IMAGE(gear), wxMEMORY_IMAGE(gear128)),
		InstIconDef("magitech",_("Magitech"), wxMEMORY_IMAGE(magitech), wxMEMORY_IMAGE(magitech128)),
		InstIconDef("enderpearl",_("Enderpearl"), wxMEMORY_IMAGE(enderpearl), wxMEMORY_IMAGE(enderpearl128)),
		InstIconDef("herobrine",_("Herobrine"), wxMEMORY_IMAGE(herobrine), wxMEMORY_IMAGE(herobrine128)),
		InstIconDef("meat",_("The Meat"), wxMEMORY_IMAGE(meat), wxMEMORY_IMAGE(meat128)),
		InstIconDef("chicken",_("Chicken"), wxMEMORY_IMAGE(chicken), wxMEMORY_IMAGE(chicken128)),
		InstIconDef("steve",_("Steve"), wxMEMORY_IMAGE(steve), wxMEMORY_IMAGE(steve128)),
		InstIconDef("derp",_("Derp"), wxMEMORY_IMAGE(derp)),
	};
	const int builtInIconCount = sizeof(builtInIcons)/sizeof(InstIconDef);

	for (int i = 0; i < builtInIconCount; i++)
	{
#ifdef DEBUG_ICONS
		if(!builtInIcons[i].image.HasAlpha())
		{
			wxLogMessage(_("Image %d %s has no alpha."), i, builtInIcons[i].key.c_str()  );
		}
#endif
		wxImage highlightIcon = tintImage(builtInIcons[i].image,wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
		Add(builtInIcons[i].image, highlightIcon, builtInIcons[i].image128, builtInIcons[i].key, builtInIcons[i].name);
	}

	if (wxDirExists(customIconDirName))
	{
		wxDir customIconDir(customIconDirName);

		if (!customIconDir.IsOpened())
			return;

		wxString iconFile;

		if (customIconDir.GetFirst(&iconFile))
		{
			do
			{
				// Check file extensions
				bool isAllowedImage = false;
				for (int i = 0; i < allowedImgExtensionsCount; i++)
				{
					if (iconFile.Lower().EndsWith(allowedImgExtensions[i]))
					{
						isAllowedImage = true;
						break;
					}
				}
				if (!isAllowedImage)
					continue;

				if (!AddFile(Path::Combine(customIconDirName, iconFile)))
				{
					if(customIconDir.GetNext(&iconFile))
						continue;
					break;
				}
			} while (customIconDir.GetNext(&iconFile));
		}
	}
}

bool InstIconList::Add(const wxImage image, const wxImage hlimage, const wxImage image128, const wxString key, const wxString name,
	const wxString filename)
{
	InstIcon *defIcon = nullptr;
	if (iconMap.count(key) > 0)
	{
		defIcon = new InstIcon(iconMap[key]);
	}
	wxImage newbig = image128;
	if(image128.GetWidth() != 128 || image128.GetHeight() != 128)
	{
		newbig.Rescale(128,128);
	}

	if (image.GetWidth() != 32 || image.GetHeight() != 32)
	{
		wxImage newImg(image);
		wxImage newHLImg(hlimage);
		newImg.Rescale(32, 32);
		newHLImg.Rescale(32, 32);
#ifdef DEBUG_ICONS
		if(!newImg.HasAlpha())
		{
			wxLogMessage(_("Image %s has no alpha after rescaling."), key.c_str()  );
		}
#endif

		InstIcon newInstIcon(key, name, newImg, newHLImg, newbig, filename, defIcon);
		newInstIcon.deleteDefIconOnDestroy = false;
		iconMap[key] = newInstIcon;
	}
	else
	{
		InstIcon newInstIcon(key, name, image, hlimage, newbig, filename, defIcon);
		newInstIcon.deleteDefIconOnDestroy = false;
		iconMap[key] = newInstIcon;
	}
	return true;
}

bool InstIconList::AddFile(const wxString fileName)
{
	wxFileName iconFileName(fileName);
	wxImage image(iconFileName.GetFullPath());
	if(!image.IsOk())
	{
		return false;
	}
	wxString iconKey = iconFileName.GetName();
	wxImage highlightIcon = tintImage(image,wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
	return Add(image,highlightIcon, image, iconKey, iconKey, iconFileName.GetFullPath());
}

bool InstIconList::RemoveIcon(const wxString key)
{
	if (iconMap.count(key) <= 0)
		return false;

	InstIcon *defIcon = iconMap[key].m_defIcon;

	iconMap[key].deleteDefIconOnDestroy = false;
	iconMap.erase(iconMap.find(key));

	if (defIcon != nullptr)
	{
		iconMap[key] = InstIcon(*defIcon);
	}
	return true;
}

wxImageList *InstIconList::CreateImageList() const
{
	wxImageList *newImgList = new wxImageList(width, height);

	for (InstIconMap::const_iterator iter = iconMap.begin(); iter != iconMap.end(); iter++)
	{
		newImgList->Add(iter->second.m_image);
	}
	return newImgList;
}

int InstIconList::GetCount() const
{
	return iconMap.size();
}

wxImage& InstIconList::getImageForKey(wxString key)
{
	if(!iconMap.count(key))
	{
		return iconMap["default"].m_image;
	}
	return iconMap[key].m_image;
}

wxImage& InstIconList::getHLImageForKey(wxString key)
{
	if(!iconMap.count(key))
	{
		return iconMap["default"].m_hlImage;
	}
	return iconMap[key].m_hlImage;
}

wxImage& InstIconList::getImage128ForKey ( wxString key )
{
	if(!iconMap.count(key))
	{
		return iconMap["default"].m_image128;
	}
	return iconMap[key].m_image128;
}

wxString& InstIconList::getFileNameForKey(wxString key)
{
	if(!iconMap.count(key))
	{
		return iconMap["default"].m_fileName;
	}
	return iconMap[key].m_fileName;
}

const InstIconMap &InstIconList::GetIconMap() const
{
	return iconMap;
}

InstIcon::InstIcon(wxString key, wxString name, wxImage image, wxImage hlImage, wxImage image128,
	wxString fileName, InstIcon *defIcon)
	: m_key(key), m_name(name), m_image(image), m_hlImage(hlImage), m_image128(image128), m_fileName(fileName)
{
	m_defIcon = defIcon;
	deleteDefIconOnDestroy = true;
}

InstIcon::InstIcon(const InstIcon &iIcon)
	: m_key(iIcon.m_key), m_image(iIcon.m_image), m_hlImage(iIcon.m_hlImage),
	  m_image128(iIcon.m_image128), m_fileName(iIcon.m_fileName),
	  m_name(iIcon.m_name)
{
	m_defIcon = iIcon.m_defIcon;
	deleteDefIconOnDestroy = true;
}

InstIcon::InstIcon()
{
	m_defIcon = nullptr;
	deleteDefIconOnDestroy = true;
}

InstIcon::~InstIcon()
{
	if (m_defIcon != nullptr && deleteDefIconOnDestroy)
		delete m_defIcon;
}

ext: cpp


text:
#pragma once

#include <vector>

#include <Eigen/Core>
#include <Eigen/SparseCore>

#include <utils/eigen_ext.hpp>

namespace ipc::rigid {

class OptimizationProblem {
public:
    virtual ~OptimizationProblem() = default;

    /// Compute the objective function f(x)
    virtual double compute_objective(
        const Eigen::VectorXd& x,
        Eigen::VectorXd& grad,
        Eigen::SparseMatrix<double>& hess,
        bool compute_grad = true,
        bool compute_hess = true) = 0;

    // --------------------------------------------------------------------
    // Convience functions
    // --------------------------------------------------------------------

    virtual double compute_objective(const Eigen::VectorXd& x) final
    {
        Eigen::VectorXd grad;
        Eigen::SparseMatrix<double> hess;
        return compute_objective(
            x, grad, hess,
            /*compute_grad=*/false, /*compute_hess=*/false);
    }

    virtual double
    compute_objective(const Eigen::VectorXd& x, Eigen::VectorXd& grad) final
    {
        Eigen::SparseMatrix<double> hess;
        return compute_objective(
            x, grad, hess,
            /*compute_grad=*/true, /*compute_hess=*/false);
    }

    virtual void update_augmented_lagrangian(const Eigen::VectorXd& x) {}
    virtual bool
    are_equality_constraints_satisfied(const Eigen::VectorXd& x) const
    {
        return true;
    }

    /// @returns the number of variables
    virtual int num_vars() const = 0;

    /// @returns A vector of booleans indicating if a DoF is fixed.
    virtual const VectorXb& is_dof_fixed() const = 0;

    virtual Eigen::VectorXi free_dof() const
    {
        const VectorXb& is_fixed = is_dof_fixed();
        Eigen::VectorXi free_dof(is_fixed.size() - is_fixed.count());
        for (int i = 0, j = 0; i < is_fixed.size(); i++) {
            if (!is_fixed(i)) {
                free_dof(j++) = i;
            }
        }
        return free_dof;
    }

    /// Determine if there is a collision between two configurations
    virtual bool
    has_collisions(const Eigen::VectorXd& xi, const Eigen::VectorXd& xj) = 0;

    /// Compute the earliest time of impact between two configurations
    virtual double compute_earliest_toi(
        const Eigen::VectorXd& xi, const Eigen::VectorXd& xj) = 0;

    virtual bool is_ccd_aligned_with_newton_update() = 0;

    /// Compute the minimum distance among geometry
    virtual double compute_min_distance(const Eigen::VectorXd& x) const = 0;

    /// Get the world coordinates of the vertices
    virtual Eigen::MatrixXd world_vertices(const Eigen::VectorXd& x) const = 0;

    /// Get the length of the diagonal of the worlds bounding box
    virtual double world_bbox_diagonal() const = 0;

    /// Get the mass matrix
    virtual DiagonalMatrixXd mass_matrix() const = 0;

    /// Get the average mass
    virtual double average_mass() const = 0;

    /// Get the time-step
    virtual double timestep() const = 0;

    virtual bool is_barrier_problem() const { return false; }
    virtual bool is_constrained_problem() const { return false; }
};

/// Helper Functions for checking finite differences
/// ------------------------------------------------
Eigen::VectorXd eval_grad_objective_approx(
    OptimizationProblem& problem, const Eigen::VectorXd& x);
Eigen::MatrixXd eval_hess_objective_approx(
    OptimizationProblem& problem, const Eigen::VectorXd& x);

} // namespace ipc::rigid

ext: hpp

max_stars_repo_name: ipc-sim/rigid-ipc

max_issues_repo_name: ipc-sim/rigid-ipc

max_forks_repo_name: ipc-sim/rigid-ipc


text:
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 <thrift/async/TEvhttpServer.h>
#include <thrift/async/TAsyncBufferProcessor.h>
#include <thrift/transport/TBufferTransports.h>
#include <boost/scoped_ptr.hpp>
#include <evhttp.h>
#include <event2/buffer.h>
#include <event2/buffer_compat.h>
#include <iostream>

#ifndef HTTP_INTERNAL // libevent < 2
#define HTTP_INTERNAL 500
#endif

using apache::thrift::transport::TMemoryBuffer;

namespace apache {
namespace thrift {
namespace async {

struct TEvhttpServer::RequestContext {
  struct evhttp_request* req;
  boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> ibuf;
  boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> obuf;

  RequestContext(struct evhttp_request* req);
};

TEvhttpServer::TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor)
  : processor_(processor), eb_(NULL), eh_(NULL) {
}

TEvhttpServer::TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor, int port)
  : processor_(processor), eb_(NULL), eh_(NULL) {
  // Create event_base and evhttp.
  eb_ = event_base_new();
  if (eb_ == NULL) {
    throw TException("event_base_new failed");
  }
  eh_ = evhttp_new(eb_);
  if (eh_ == NULL) {
    event_base_free(eb_);
    throw TException("evhttp_new failed");
  }

  // Bind to port.
  int ret = evhttp_bind_socket(eh_, NULL, port);
  if (ret < 0) {
    evhttp_free(eh_);
    event_base_free(eb_);
    throw TException("evhttp_bind_socket failed");
  }

  // Register a handler.  If you use the other constructor,
  // you will want to do this yourself.
  // Don't forget to unregister before destorying this TEvhttpServer.
  evhttp_set_cb(eh_, "/", request, (void*)this);
}

TEvhttpServer::~TEvhttpServer() {
  if (eh_ != NULL) {
    evhttp_free(eh_);
  }
  if (eb_ != NULL) {
    event_base_free(eb_);
  }
}

int TEvhttpServer::serve() {
  if (eb_ == NULL) {
    throw TException("Unexpected call to TEvhttpServer::serve");
  }
  return event_base_dispatch(eb_);
}

TEvhttpServer::RequestContext::RequestContext(struct evhttp_request* req)
  : req(req),
    ibuf(new TMemoryBuffer(EVBUFFER_DATA(req->input_buffer),
                           static_cast<uint32_t>(EVBUFFER_LENGTH(req->input_buffer)))),
    obuf(new TMemoryBuffer()) {
}

void TEvhttpServer::request(struct evhttp_request* req, void* self) {
  try {
    static_cast<TEvhttpServer*>(self)->process(req);
  } catch (std::exception& e) {
    evhttp_send_reply(req, HTTP_INTERNAL, e.what(), 0);
  }
}

void TEvhttpServer::process(struct evhttp_request* req) {
  RequestContext* ctx = new RequestContext(req);
  return processor_->process(apache::thrift::stdcxx::bind(&TEvhttpServer::complete,
                                                          this,
                                                          ctx,
                                                          apache::thrift::stdcxx::placeholders::_1),
                             ctx->ibuf,
                             ctx->obuf);
}

void TEvhttpServer::complete(RequestContext* ctx, bool success) {
  (void)success;
  boost::scoped_ptr<RequestContext> ptr(ctx);

  int code = success ? 200 : 400;
  const char* reason = success ? "OK" : "Bad Request";

  int rv = evhttp_add_header(ctx->req->output_headers, "Content-Type", "application/x-thrift");
  if (rv != 0) {
    // TODO: Log an error.
    std::cerr << "evhttp_add_header failed " << __FILE__ << ":" << __LINE__ << std::endl;
  }

  struct evbuffer* buf = evbuffer_new();
  if (buf == NULL) {
    // TODO: Log an error.
    std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << std::endl;
  } else {
    uint8_t* obuf;
    uint32_t sz;
    ctx->obuf->getBuffer(&obuf, &sz);
    int ret = evbuffer_add(buf, obuf, sz);
    if (ret != 0) {
      // TODO: Log an error.
      std::cerr << "evhttp_add failed with " << ret << " " << __FILE__ << ":" << __LINE__
                << std::endl;
    }
  }

  evhttp_send_reply(ctx->req, code, reason, buf);
  if (buf != NULL) {
    evbuffer_free(buf);
  }
}

struct event_base* TEvhttpServer::getEventBase() {
  return eb_;
}
}
}
} // apache::thrift::async

max_stars_repo_name: arculus/thrift

max_issues_repo_name: arculus/thrift

max_forks_repo_name: arculus/thrift


text:
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/vinniefalco/http_io
//

// Test that header file is self-contained.
#include <boost/http_io/error.hpp>

#include "test_suite.hpp"

namespace boost {
namespace http_io {

class error_test
{
public:
    void
    run()
    {
    }
};

TEST_SUITE(error_test, "boost.http_io.error");

} // http_io
} // boost


text:
#include <veil/budget.h>
#include <test/test_veil.h>
#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(monthly_rewards_tests, BasicTestingSetup)

/**
 *  Tests to make suret that the proper rewards are sent with the given block height
 */

BOOST_AUTO_TEST_CASE(testRewardAfterSet)
{
    CAmount nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment = 0;
    int nBlocksPerPeriod = 43200;
    veil::Budget().GetBlockRewards(1, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 50 * COIN);
    BOOST_CHECK(nFounderPayment == 10 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nLabPayment == 10 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nBudgetPayment == 30 * nBlocksPerPeriod * COIN);

    veil::Budget().GetBlockRewards(2, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 50 * COIN);
    BOOST_CHECK(nFounderPayment == 0);
    BOOST_CHECK(nLabPayment == 0);
    BOOST_CHECK(nBudgetPayment == 0);

    veil::Budget().GetBlockRewards(nBlocksPerPeriod, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 50 * COIN);
    BOOST_CHECK(nFounderPayment == 10 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nLabPayment == 10 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nBudgetPayment == 30 * nBlocksPerPeriod * COIN);

    veil::Budget().GetBlockRewards(nBlocksPerPeriod + 1, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 50 * COIN);
    BOOST_CHECK(nFounderPayment == 0);
    BOOST_CHECK(nLabPayment == 0);
    BOOST_CHECK(nBudgetPayment == 0);

    veil::Budget().GetBlockRewards(12 * nBlocksPerPeriod, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 40 * COIN);
    BOOST_CHECK(nFounderPayment == 8 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nLabPayment == 8 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nBudgetPayment == 24 * nBlocksPerPeriod * COIN);

    veil::Budget().GetBlockRewards(12 * nBlocksPerPeriod + 1, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 40 * COIN);
    BOOST_CHECK(nFounderPayment == 0);
    BOOST_CHECK(nLabPayment == 0);
    BOOST_CHECK(nBudgetPayment == 0);

    veil::Budget().GetBlockRewards(24 * nBlocksPerPeriod, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 30 * COIN);
    BOOST_CHECK(nFounderPayment == 6 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nLabPayment == 6 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nBudgetPayment == 18 * nBlocksPerPeriod * COIN);

    veil::Budget().GetBlockRewards(24 * nBlocksPerPeriod + 1, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 30 * COIN);
    BOOST_CHECK(nFounderPayment == 0);
    BOOST_CHECK(nLabPayment == 0);
    BOOST_CHECK(nBudgetPayment == 0);

    veil::Budget().GetBlockRewards(36 * nBlocksPerPeriod, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 20 * COIN);
    BOOST_CHECK(nFounderPayment == 4 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nLabPayment == 4 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nBudgetPayment == 12 * nBlocksPerPeriod * COIN);

    veil::Budget().GetBlockRewards(36 * nBlocksPerPeriod + 1, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 20 * COIN);
    BOOST_CHECK(nFounderPayment == 0);
    BOOST_CHECK(nLabPayment == 0);
    BOOST_CHECK(nBudgetPayment == 0);

    veil::Budget().GetBlockRewards(48 * nBlocksPerPeriod, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 10 * COIN);
    BOOST_CHECK(nFounderPayment == 2 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nLabPayment == 2 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nBudgetPayment == 6 * nBlocksPerPeriod * COIN);

    veil::Budget().GetBlockRewards(48 * nBlocksPerPeriod + 1, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 10 * COIN);
    BOOST_CHECK(nFounderPayment == 0);
    BOOST_CHECK(nLabPayment == 0);
    BOOST_CHECK(nBudgetPayment == 0);

    veil::Budget().GetBlockRewards(60 * nBlocksPerPeriod, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 10 * COIN);
    BOOST_CHECK(nFounderPayment == 0);
    BOOST_CHECK(nLabPayment == 2 * nBlocksPerPeriod * COIN);
    BOOST_CHECK(nBudgetPayment == 8 * nBlocksPerPeriod * COIN);

    veil::Budget().GetBlockRewards(60 * nBlocksPerPeriod + 1, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);

    BOOST_CHECK(nBlockReward == 10 * COIN);
    BOOST_CHECK(nFounderPayment == 0);
    BOOST_CHECK(nLabPayment == 0);
    BOOST_CHECK(nBudgetPayment == 0);

}

/**
 * Tests to make sure that in a 12 month period, 12 rewards have been
 * given
 */
BOOST_AUTO_TEST_CASE(countRwards)
{

    CAmount nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment = 0;
    int nBlockRewardsCount = 0;
    int nRewardsCount = 0;

    for(int i = 0; i <= 518399; i++) {
        veil::Budget().GetBlockRewards(i, nBlockReward, nFounderPayment, nLabPayment, nBudgetPayment);
        if(nFounderPayment > 0)
            nRewardsCount++;
        if(nBlockReward > 0)
            nBlockRewardsCount++;
    }

    BOOST_CHECK(nRewardsCount == 12);
    BOOST_CHECK(nBlockRewardsCount == 518399);
}

BOOST_AUTO_TEST_SUITE_END()


text:
// Copyright 2013-2019 Stanford University
//
// Licensed 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 <chrono>
#include <iostream>
#include <sys/time.h>

#include "src/ext/cpputil/include/command_line/command_line.h"
#include "src/ext/cpputil/include/io/column.h"
#include "src/ext/cpputil/include/io/console.h"
#include "src/ext/cpputil/include/io/filterstream.h"
#include "src/ext/cpputil/include/signal/debug_handler.h"

#include "src/cfg/cfg_transforms.h"
#include "src/expr/expr.h"
#include "src/expr/expr_parser.h"
#include "src/tunit/tunit.h"
#include "src/search/progress_callback.h"
#include "src/search/new_best_correct_callback.h"
#include "src/search/statistics_callback.h"
#include "src/search/failed_verification_action.h"
#include "src/search/postprocessing.h"
#include "src/validator/learner.h"

#include "tools/args/search.inc"
#include "tools/args/target.inc"
#include "tools/gadgets/cost_function.h"
#include "tools/gadgets/correctness_cost.h"
#include "tools/gadgets/functions.h"
#include "tools/gadgets/learner.h"
#include "tools/gadgets/sandbox.h"
#include "tools/gadgets/search.h"
#include "tools/gadgets/search_state.h"
#include "tools/gadgets/seed.h"
#include "tools/gadgets/solver.h"
#include "tools/gadgets/target.h"
#include "tools/gadgets/testcases.h"
#include "tools/gadgets/transform_pools.h"
#include "tools/gadgets/verifier.h"
#include "tools/gadgets/weighted_transform.h"
#include "tools/io/postprocessing.h"
#include "tools/io/failed_verification_action.h"

#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
namespace fs = boost::filesystem;

using namespace cpputil;
using namespace std;
using namespace stoke;
using namespace chrono;

auto& io = Heading::create("Output Options:");
auto& out = ValueArg<string>::create("out")
            .alternate("o")
            .usage("<path/to/file.s>")
            .description("File to write successful results to")
            .default_val("result.s");

auto& results_arg = ValueArg<string>::create("results")
                    .usage("<path/to/dir>")
                    .description("Path to the directory where new best correct rewrites are being stored.  Rewrites are verified before being stored (using the same verification settings as the final verification).")
                    .default_val("");

auto& machine_output_arg = ValueArg<string>::create("machine_output")
                           .usage("<path/to/file.s>")
                           .description("Machine-readable output (result and statistics)");

auto& stats = Heading::create("Statistics Options:");
auto& stat_int =
  ValueArg<size_t>::create("statistics_interval")
  .usage("<int>")
  .description("Number of iterations between statistics updates")
  .default_val(1000000);

auto& automation_heading = Heading::create("Automation Options:");

auto& timeout_iterations_arg =
  cpputil::ValueArg<size_t>::create("timeout_iterations")
  .usage("<int>")
  .description("Total number of iterations before giving up (across all cycles)")
  .default_val(100000000);

auto& timeout_seconds_arg =
  cpputil::ValueArg<double>::create("timeout_seconds")
  .usage("<double>")
  .description("Total number of seconds before giving up (across all cycles), or 0 for no timeout")
  .default_val(0);

auto& failed_verification_action =
  ValueArg<FailedVerificationAction, FailedVerificationActionReader, FailedVerificationActionWriter>::create("failed_verification_action")
  .usage("(quit|add_counterexample)")
  .description("Action to take when the verification at the end fails")
  .default_val(FailedVerificationAction::ADD_COUNTEREXAMPLE);

auto& cycle_timeout_arg =
  ValueArg<string, cpputil::LineReader<>>::create("cycle_timeout")
  .usage("<string>")
  .description("The timeout (as number of iterations) per cycle.  Can be a comma-separated list, where the first element is used for the first cycle, and so on.  Can also be an expression involving the variable 'i' that refers to the current cycle (starting at 1); expressions include integer constants, the variable 'i', and binary operators: +, -, *, /, ** (exponentiation), >>, << (shifts), ==, !=, <=, <, >, >= (comparisons), % (modulo), |, & (binary and/or).  The last expression in the list is used for all following cycles.")
  .default_val("10000, 10000, 10000, 10000, 10000, 2**i * 1000");

auto& postprocessing_arg =
  ValueArg<Postprocessing, PostprocessingReader, PostprocessingWriter>::create("postprocessing")
  .usage("(none|simple|full)")
  .description("Postprocessing of the program found by STOKE (simple removes nops and unreachable blocks, and full additionally removes redundant statements without side-effects)")
  .default_val(Postprocessing::FULL);

auto& no_progress_update_arg =
  cpputil::FlagArg::create("no_progress_update")
  .description("Don't show a progress update whenever a new best program is discovered");

void sep(ostream& os, string c = "*") {
  for (size_t i = 0; i < 80; ++i) {
    os << c;
  }
  os << endl << endl;
}

static Cost lowest_cost = 0;
static Cost lowest_correct = 0;
static Cost starting_cost = 0;

void show_state(const SearchState& state, ostream& os) {
  ofilterstream<Column> ofs(os);
  ofs.filter().padding(5);

  auto best_yet = state.best_yet;
  CfgTransforms::remove_unreachable(best_yet);
  CfgTransforms::remove_nop(best_yet);

  lowest_cost = state.best_yet_cost;
  ofs << "Lowest Cost Discovered (" << state.best_yet_cost << ")" << endl;
  ofs << endl;
  ofs << best_yet.get_code();
  ofs.filter().next();

  auto best_correct = state.best_correct;
  CfgTransforms::remove_unreachable(best_correct);
  CfgTransforms::remove_nop(best_correct);

  lowest_correct = state.best_correct_cost;
  ofs << "Lowest Known Correct Cost (" << state.best_correct_cost << ")" << endl;
  ofs << endl;
  ofs << best_correct.get_code();
  ofs.filter().done();
}

void pcb(const ProgressCallbackData& data, void* arg) {
  ostream& os = *((ostream*)arg);

  os << "Progress Update: " << endl;
  os << endl;

  show_state(data.state, os);

  os << endl << endl;
  sep(os);
}

struct ScbArg {
  ostream* os;
  uint32_t** cost_stats;
};

void show_statistics(const StatisticsCallbackData& data, ostream& os) {
  os << "Iterations:                    " << data.iterations << endl;
  os << "Elapsed Time:                  " << data.elapsed.count() << "s" << endl;
  os << "Iterations/s:                  " << (data.iterations / data.elapsed.count()) << endl;
  os << endl;
  os << "Starting cost:                 " << starting_cost << endl;
  os << "Lowest cost:                   " << lowest_cost << endl;
  os << "Lowest correct cost:           " << lowest_correct << endl;
  os << endl;

  ofilterstream<Column> ofs(os);
  ofs.filter().padding(5);

  const WeightedTransform* transform = static_cast<const WeightedTransform*>(data.transform);

  Statistics total;
  for (size_t i = 0; i < transform->size(); ++i) {
    total += data.move_statistics[i];
  }

  ofs << "Move Type" << endl;
  ofs << endl;
  for (size_t i = 0; i < transform->size(); ++i) {
    ofs << transform->get_transform(i)->get_name() << endl;
  }
  ofs << endl;
  ofs << "Total";
  ofs.filter().next();

  ofs << "Proposed" << endl;
  ofs << endl;
  for (size_t i = 0; i < transform->size(); ++i) {
    ofs << 100 * (double)data.move_statistics[i].num_proposed / data.iterations << "%" << endl;
  }
  ofs << endl;
  ofs << 100 * (double)total.num_proposed / data.iterations << "%";
  ofs.filter().next();

  ofs << "Succeeded" << endl;
  ofs << endl;
  for (size_t i = 0; i < transform->size(); ++i) {
    ofs << 100 * (double)data.move_statistics[i].num_succeeded / data.iterations << "%" << endl;
  }
  ofs << endl;
  ofs << 100 * (double)total.num_succeeded / data.iterations << "%";
  ofs.filter().next();

  ofs << "Accepted" << endl;
  ofs << endl;
  for (size_t i = 0; i < transform->size(); ++i) {
    ofs << 100 * (double)data.move_statistics[i].num_accepted / data.iterations << "%" << endl;
  }
  ofs << endl;
  ofs << 100 * (double)total.num_accepted / data.iterations << "%";
  ofs.filter().done();
}

void scb(const StatisticsCallbackData& data, void* arg) {
  ScbArg sa = *((ScbArg*)arg);
  ostream& os = *(sa.os);
  uint32_t** cost_stats = sa.cost_stats;

  os << "Statistics Update: " << endl;
  os << endl;
  show_statistics(data, os);

  os << endl << endl;
  sep(os);
}

void show_final_update(const StatisticsCallbackData& stats, SearchState& state,
                       size_t total_restarts,
                       size_t total_iterations, time_point<steady_clock> start,
                       duration<double> search_elapsed,
                       bool verified,
                       bool timeout) {
  auto total_elapsed = duration_cast<duration<double>>(steady_clock::now() - start);
  sep(Console::msg(), "#");
  Console::msg() << "Final update:" << endl << endl;
  Console::msg() << "Total search iterations:       " << total_iterations << endl;
  Console::msg() << "Number of attempted searches:  " << total_restarts << endl;
  Console::msg() << "Total search time:             " << search_elapsed.count() << "s" << endl;
  Console::msg() << "Total time:                    " << total_elapsed.count() << "s" << endl;
  Console::msg() << endl << "Statistics of last search" << endl << endl;
  // get the state first (because it updates some static variables)
  ostringstream stream;
  show_state(state, stream);
  show_statistics(stats, Console::msg());
  Console::msg() << endl << endl;
  Console::msg() << stream.str();
  Console::msg() << endl << endl;
  sep(Console::msg(), "#");

  // output machine-readable result
  if (machine_output_arg.has_been_provided()) {
    auto code_to_string = [](x64asm::Code code) {
      stringstream ss;
      ss << code;
      auto res = regex_replace(ss.str(), regex("\n"), "\\n");
      return res;
    };

    ofstream f;
    f.open(machine_output_arg.value());
    f << "{" << endl;
    f << "  \"success\": " << (state.success ? "true" : "false") << "," << endl;
    f << "  \"interrupted\": " << (state.interrupted ? "true" : "false") << "," << endl;
    f << "  \"timeout\": " << (timeout ? "true" : "false") << "," << endl;
    f << "  \"verified\": " << (verified ? "true" : "false") << "," << endl;
    f << "  \"statistics\": {" << endl;
    f << "    \"total_iterations\": " << total_iterations << "," << endl;
    f << "    \"total_attempted_searches\": " << total_restarts << "," << endl;
    f << "    \"total_search_time\": " << search_elapsed.count() << "," << endl;
    f << "    \"total_time\": " << total_elapsed.count() << endl;
    f << "  }," << endl;
    f << "  \"best_yet\": {" << endl;
    f << "    \"cost\": " << state.best_yet_cost << "," << endl;
    f << "    \"code\": \"" << code_to_string(state.best_yet.get_code()) << "\"" << endl;
    f << "  }," << endl;
    f << "  \"best_correct\": {" << endl;
    f << "    \"cost\": " << state.best_correct_cost << "," << endl;
    f << "    \"code\": \"" << code_to_string(state.best_correct.get_code()) << "\"" << endl;
    f << "  }" << endl;
    f << "}" << endl;
    f.close();
  }
}

void new_best_correct_callback(const NewBestCorrectCallbackData& data, void* arg) {

  if (results_arg.has_been_provided()) {
    Console::msg() << "Verifying improved rewrite..." << endl;

    auto state = data.state;
    auto data = (pair<VerifierGadget&, TargetGadget&>*)arg;
    auto verifier = data->first;
    auto target = data->second;

    // perform the postprocessing
    Cfg res(state.current);
    if (postprocessing_arg == Postprocessing::FULL) {
      CfgTransforms::remove_redundant(res);
      CfgTransforms::remove_unreachable(res);
      CfgTransforms::remove_nop(res);
    } else if (postprocessing_arg == Postprocessing::SIMPLE) {
      CfgTransforms::remove_unreachable(res);
      CfgTransforms::remove_nop(res);
    } else {
      // Do nothing.
    }

    // verify the new best correct rewrite
    const auto verified = verifier.verify(target, res);

    if (verifier.has_error()) {
      Console::msg() << "The verifier encountered an error: " << verifier.error() << endl << endl;
    }

    // save to file if verified
    if (verified) {
      Console::msg() << "Verified!  Saving result..." << endl << endl;
      // next name for result file
      string name = "";
      bool done = false;
      do {
        name = results_arg.value() + "/result-" + to_string(state.last_result_id) + ".s";
        state.last_result_id += 1;
        ifstream f(name.c_str());
        done = !f.good();
      } while (!done);

      // write output
      ofstream outfile;
      outfile.open(name);
      outfile << res.get_function();
      outfile.close();
    } else {
      Console::msg() << "Verification failed."  << endl << endl;
      if (verifier.counter_examples_available()) {
        Console::msg() << "Counterexample: " << endl;
        for (auto it : verifier.get_counter_examples()) {
          Console::msg() << it << endl;
        }
      }
    }

  } else {
    cout << "No action on new best correct" << endl;

  }

}

vector<string>& split(string& s, const string& delim, vector<string>& result) {
  auto pos = string::npos;
  while ((pos = s.find(delim)) != string::npos) {
    result.push_back(s.substr(0, pos));
    s.erase(0, pos + delim.length());
  }
  result.push_back(s);
  return result;
}

int main(int argc, char** argv) {
  const auto start = steady_clock::now();
  duration<double> search_elapsed = duration<double>(0.0);

  CommandLineConfig::strict_with_convenience(argc, argv);
  DebugHandler::install_sigsegv();
  DebugHandler::install_sigill();

  // create results dir if necessary
  if (results_arg.has_been_provided()) {
    fs::path result_dir(results_arg.value());
    if (!fs::is_directory(result_dir)) {
      fs::create_directories(result_dir);
    }
  }

  SeedGadget seed;
  FunctionsGadget aux_fxns;
  TargetGadget target(aux_fxns, init_arg == Init::ZERO);

  TrainingSetGadget training_set(seed);
  SandboxGadget training_sb(training_set, aux_fxns);

  TransformPoolsGadget transform_pools(target, aux_fxns, seed);
  WeightedTransformGadget transform(transform_pools, seed);
  SearchGadget search(&transform, seed);

  TestSetGadget test_set(seed);
  SandboxGadget test_sb(test_set, aux_fxns);

  PerformanceSetGadget perf_set(seed);
  SandboxGadget perf_sb(perf_set, aux_fxns);

  CorrectnessCostGadget holdout_fxn(target, &test_sb);
  InvariantLearnerGadget learner(seed, target, rewrite);
  VerifierGadget verifier(test_sb, holdout_fxn, learner);

  ScbArg scb_arg {&Console::msg(), nullptr};
  search.set_statistics_callback(scb, &scb_arg)
  .set_statistics_interval(stat_int);
  if (!no_progress_update_arg.value()) {
    search.set_progress_callback(pcb, &Console::msg());
  }
  auto nbcc_data = pair<VerifierGadget&, TargetGadget&>(verifier, target);
  search.set_new_best_correct_callback(new_best_correct_callback, &nbcc_data);

  size_t total_iterations = 0;
  size_t total_restarts = 0;

  // attempt to parse cycle_timeout argument
  vector<string> parts;
  vector<Expr<size_t>*> cycle_timeouts;
  for (auto& part : split(cycle_timeout_arg.value(), ",", parts)) {
    function<bool (const string&)> f = [](const string& s) -> bool { return s == "i"; };
    auto parser = ExprParser<size_t>(part, f);
    if (parser.has_error()) {
      Console::error() << "Error parsing cycle timeout expression '" << part << "': " << parser.get_error() << endl;
    }
    cycle_timeouts.push_back(parser.get());
  }

  if (strategy_arg.value() == "none" &&
      failed_verification_action.value() == FailedVerificationAction::ADD_COUNTEREXAMPLE) {
    Console::error() << "No verification is performed, thus no counterexample can be added (--failed_verification_action add_counterexample and --strategy none are not compatible)." << endl;
  }

  string final_msg;
  SearchStateGadget state(target, aux_fxns);
  for (size_t i = 0; ; ++i) {
    CostFunctionGadget fxn(target, &training_sb, &perf_sb);

    // determine iteration timeout
    Expr<size_t>* timeout_expr = i >= cycle_timeouts.size() ? cycle_timeouts[cycle_timeouts.size()-1] : cycle_timeouts[i];
    function<size_t (const string&)> f2 = [i](const string& s) -> size_t { return i; };
    size_t cur_timeout = (*timeout_expr)(f2);
    size_t timeout_left = cur_timeout;
    if (timeout_iterations_arg.value()) {
      timeout_left = std::max(0UL, timeout_iterations_arg.value() - total_iterations);
    }
    search.set_timeout_itr(std::min(cur_timeout, timeout_left));

    Console::msg() << "Running search (timeout is " << cur_timeout << " iterations";
    // timeout in seconds
    if (timeout_seconds_arg.value() != 0) {
      auto time_remaining = duration_cast<duration<double>>(steady_clock::now() - start) + duration<double>(timeout_seconds_arg.value());
      if (time_remaining <= steady_clock::duration::zero()) {
        show_final_update(search.get_statistics(), state, total_restarts, total_iterations, start, search_elapsed, false, true);
        Console::error(1) << "Search terminated unsuccessfully; unable to discover a new rewrite!" << endl;
      }
      search.set_timeout_sec(time_remaining);
      Console::msg() << " / " << time_remaining.count() << " seconds";
    }
    Console::msg() << "):" << endl << endl;
    state = SearchStateGadget(target, aux_fxns);

    // Run the initial cost function
    // Used by statistics output and a sanity check
    auto initial_cost = fxn(state.current);
    if (!initial_cost.first && init_arg == Init::TARGET) {
      Console::warn() << "Initial state has non-zero correctness cost with --init target.";
    }
    starting_cost = initial_cost.second;
    lowest_cost = initial_cost.second;
    if (initial_cost.first) {
      lowest_correct = initial_cost.second;
    } else {
      lowest_correct = 0;
    }

    const auto start_search = steady_clock::now();
    search.run(target, fxn, init_arg, state, aux_fxns);
    search_elapsed += duration_cast<duration<double>>(steady_clock::now() - start_search);

    total_iterations += search.get_statistics().iterations;
    total_restarts++;

    if (state.interrupted) {
      Console::msg() << endl;
      show_final_update(search.get_statistics(), state, total_restarts, total_iterations, start, search_elapsed, false, false);
      Console::msg() << "Search interrupted!" << endl;
      exit(1);
    }

    const auto verified = verifier.verify(target, state.best_correct);

    if (verifier.has_error()) {
      Console::msg() << "The verifier encountered an error:" << endl;
      Console::msg() << verifier.error() << endl;
    }

    if (!state.success) {
      Console::msg() << "Unable to discover a new correct rewrite before timing out... " << endl << endl;
    } else if (!verified) {
      Console::msg() << "Unable to verify new rewrite..." << endl << endl;
    } else {
      if (strategy_arg.value() == "none") {
        final_msg = "Search terminated successfully (but no verification was performed)!";
      } else {
        final_msg = "Search terminated successfully with a verified rewrite!";
      }
      break;
    }

    sep(Console::msg());

    if (timeout_iterations_arg.value() && total_iterations >= timeout_iterations_arg.value()) {
      show_final_update(search.get_statistics(), state, total_restarts, total_iterations, start, search_elapsed, verified, true);
      Console::error(1) << "Search terminated unsuccessfully; unable to discover a new rewrite!" << endl;
    }

    if (!verified && verifier.counter_examples_available() && failed_verification_action.value() == FailedVerificationAction::ADD_COUNTEREXAMPLE) {
      Console::msg() << "Restarting search using new testcase (counterexample from verifier):" << endl << endl;
      Console::msg() << verifier.get_counter_examples()[0] << endl << endl;
      training_sb.insert_input(verifier.get_counter_examples()[0]);
    } else {
      Console::msg() << "Restarting search" << endl;
    }
  }

  if (postprocessing_arg == Postprocessing::FULL) {
    CfgTransforms::remove_redundant(state.best_correct);
    CfgTransforms::remove_unreachable(state.best_correct);
    CfgTransforms::remove_nop(state.best_correct);
  } else if (postprocessing_arg == Postprocessing::SIMPLE) {
    CfgTransforms::remove_unreachable(state.best_correct);
    CfgTransforms::remove_nop(state.best_correct);
  } else {
    // Do nothing.
  }

  auto final_stats = search.get_statistics();
  show_final_update(final_stats, state, total_restarts, total_iterations, start, search_elapsed, true, false);
  Console::msg() << final_msg << endl;

  ofstream ofs(out.value());
  ofs << state.best_correct.get_function();

  return 0;
}

ext: cc