<commit_before>#include"panelview.h"

PMonitor::PMonitor(void) : Dialog(false)
{
	const int width = qApp->desktop()->rect().width();
	const int height = qApp->desktop()->rect().height();

	setSceneRect(0, 0, width, height);
	setViewportUpdateMode(QGraphicsView::NoViewportUpdate);

	setAttribute(Qt::WA_PaintUnclipped);
	setAttribute(Qt::WA_NoSystemBackground);
	setAttribute(Qt::WA_NoBackground);
	setCacheMode(QGraphicsView::CacheNone);
	setOptimizationFlags(
		QGraphicsView::DontSavePainterState |
		QGraphicsView::DontAdjustForAntialiasing);

	viewport()->setAttribute(Qt::WA_TranslucentBackground, false);
	scene()->setItemIndexMethod(QGraphicsScene::NoIndex);

	rootContext()->setContextProperty("screenWidth", width);
	rootContext()->setContextProperty("screenHeight", height);

	setSource(QUrl::fromLocalFile("/usr/share/meego-ux-panels/main.qml"));
}

PanelView::PanelView(void) : Dialog(false),
		QDeclarativeImageProvider(QDeclarativeImageProvider::Pixmap)
{

	const int width = qApp->desktop()->rect().width();
	const int height = qApp->desktop()->rect().height();

	int j, k, total=1, cur_width, cur_height=0;
	QList<QObject*> tmp;
	QDeclarativeItem *dec;
	QObject *i;

	r = new PMonitor();

	if((i = r->rootObject()->findChild<QDeclarativeItem *>("appPage")) == NULL |
	   (i = i->findChild<QDeclarativeItem *>("PC")) == NULL |
	   (i = i->findChild<QDeclarativeItem *>("PLV")) == NULL) {
		qFatal("Upgrade your version of MeeGo-UX-Panels");
	}
	fwidth = i->property("contentWidth").toInt();
	r->rootObject()->setProperty("width", fwidth);
	r->rootObject()->setProperty("height", height);

	QObject::connect(r->scene(), SIGNAL(changed(const QList<QRectF>&)),
			this, SLOT(invalidate(void)));

	setSceneRect(0, 0, width, height);

	const int p_width = fwidth /  NUM_C;
	const int p_height = height / NUM_R;
	for(j = 0; j < NUM_P; j++) {
		cache[j] = new QPixmap(p_width, p_height);
	}

	invalidate();
	engine()->addImageProvider(QLatin1String("gen"), this);

	setSource(QUrl::fromLocalFile("/usr/share/meego-ux-daemon/real.qml"));
	rootObject()->setProperty("contentWidth", fwidth);
	rootObject()->setProperty("contentHeight", height);
	rootObject()->setProperty("width", width);
	rootObject()->setProperty("height", height);

	dec =  qobject_cast<QDeclarativeItem*>(rootObject());
	tmp = dec->children();

	for(j = 0; j < NUM_R; j++) {
		cur_width = 0;
		for(k = 0; k < NUM_C; k++) {
			tmp.at(total)->setProperty("width", p_width);
			tmp.at(total)->setProperty("height", p_height);
			tmp.at(total)->setProperty("x", cur_width);
			tmp.at(total)->setProperty("y", cur_height);

			QString meh = QString(ISRC);
			meh += QString::number(total-1);
			tmp.at(total)->setProperty("source", meh);

			cur_width += p_width;
			total++;
		}
		cur_height += p_height;
	}

	setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);

	setOptimizationFlags(
		QGraphicsView::DontSavePainterState |
		QGraphicsView::DontAdjustForAntialiasing);

	setCacheMode(QGraphicsView::CacheBackground);
	scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
	viewport()->setAttribute(Qt::WA_PaintUnclipped);

	create_bg();
}

PanelView::~PanelView(void)
{
	int i;

	for(i = 0; i < NUM_P; i++) {
		delete cache[i];
	}

	delete r;
	delete background;
	delete bg_window;

}

void PanelView::keyPressEvent(QKeyEvent *e)
{
	r->keyPressEvent(e);
	return;
}

void PanelView::keyReleaseEvent(QKeyEvent *e)
{
	r->keyReleaseEvent(e);
	return;
}

void PanelView::mouseDoubleClickEvent(QMouseEvent *e)
{
	r->mouseDoubleClickEvent(e);
	return;
}

void PanelView::mousePressEvent(QMouseEvent *e)
{
	QDeclarativeItem *i;

	i = qobject_cast<QDeclarativeItem *>(rootObject());
	QPoint j(e->x() + i->property("contentX").toDouble(), e->y());
	QMouseEvent k(e->type(), j, e->button(), e->buttons(), e->modifiers());

	bg_window->mousePressEvent(e);
	r->mousePressEvent(&k);
	QDeclarativeView::mousePressEvent(e);
	return;
}

void PanelView::mouseReleaseEvent(QMouseEvent *e)
{
	bg_window->mouseReleaseEvent(e);
	r->mouseReleaseEvent(e);
	QDeclarativeView::mouseReleaseEvent(e);
	return;
}

void PanelView::tabletEvent(QTabletEvent *e)
{
	r->tabletEvent(e);
	return;
}

QPixmap PanelView::requestPixmap(const QString &id, QSize *size,
		const QSize &resize)
{
	int i = id.toInt();
	while(i >= NUM_P) { i -= NUM_P; }
	return *cache[i];
}

void PanelView::invalidate(void)
{
	int i,j,k,m;

	QPixmap *old, *tmp;
	QPainter p;

	QDeclarativeItem *dec;
	QList<QObject *> kids;
	QString src;

	const int height = qApp->desktop()->rect().height();
	const int p_width = fwidth /  NUM_C;
	const int p_height = height / NUM_R;
	const QRgb tran  = QColor(Qt::transparent).rgb();
	QRgb bg_color;

	dec = qobject_cast<QDeclarativeItem *>(rootObject());
	if(dec != NULL) {
		kids = dec->children();
	}

	int total = 0;
	for(i = 0; i < NUM_R; i++) {
		for(j = 0; j < NUM_C; j++) {
			old = cache[total];

			QImage img(p_width, p_height,QImage::Format_ARGB32);

			p.begin(&img);
			r->viewport()->render(&p, QPoint(),
				 QRegion( p_width * j, p_height * i,
					  p_width, p_height));
			p.end();

			if(total == 0) {
				bg_color = img.pixel(0,0);
			}

			tmp = new QPixmap(p_width, p_height);
			tmp->convertFromImage(img,
				Qt::ColorOnly | Qt::NoOpaqueDetection);
			QBitmap mask = QBitmap::fromImage(
					img.createMaskFromColor(bg_color));
			tmp->setMask(mask);

			cache[total] = tmp;
			delete old;

			if(dec != NULL) {
				src = kids.at(total+1)->property("source").toString();
				k = src.right( src.size() - ISRC_LEN).toInt();
				src.truncate(ISRC_LEN);
				k += NUM_P;
				src += QString::number(k);
				kids.at(total+1)->setProperty("source", src);
			}

			total++;
		}
	}
	viewport()->update();
	return;
}

void PanelView::create_bg(void)
{
	const int width = qApp->desktop()->rect().width();
	const int height = qApp->desktop()->rect().height();

	bg_window = new PMonitor();
	bg_window->setSource(QUrl::fromLocalFile("/usr/share/meego-ux-daemon/background.qml"));
	background = new QPixmap(width, height);

	QObject::connect(bg_window->scene(), SIGNAL(changed(const QList<QRectF>&)),
			this, SLOT(bg_changed(void)));
}

void PanelView::bg_changed(void)
{
	QPainter bg_painter(background);
	bg_window->viewport()->render(&bg_painter);
	bg_painter.end();
	QBrush br(*background);
	br.setStyle(Qt::TexturePattern);
	setBackgroundBrush(br);

	scene()->invalidate(QRectF(0,0,0,0), QGraphicsScene::BackgroundLayer);
}

<commit_msg>Switch QImage format from ARGB32 to ARGB32_Premultiplied<commit_after>#include"panelview.h"

PMonitor::PMonitor(void) : Dialog(false)
{
	const int width = qApp->desktop()->rect().width();
	const int height = qApp->desktop()->rect().height();

	setSceneRect(0, 0, width, height);
	setViewportUpdateMode(QGraphicsView::NoViewportUpdate);

	setAttribute(Qt::WA_PaintUnclipped);
	setAttribute(Qt::WA_NoSystemBackground);
	setAttribute(Qt::WA_NoBackground);
	setCacheMode(QGraphicsView::CacheNone);
	setOptimizationFlags(
		QGraphicsView::DontSavePainterState |
		QGraphicsView::DontAdjustForAntialiasing);

	viewport()->setAttribute(Qt::WA_TranslucentBackground, false);
	scene()->setItemIndexMethod(QGraphicsScene::NoIndex);

	rootContext()->setContextProperty("screenWidth", width);
	rootContext()->setContextProperty("screenHeight", height);

	setSource(QUrl::fromLocalFile("/usr/share/meego-ux-panels/main.qml"));
}

PanelView::PanelView(void) : Dialog(false),
		QDeclarativeImageProvider(QDeclarativeImageProvider::Pixmap)
{

	const int width = qApp->desktop()->rect().width();
	const int height = qApp->desktop()->rect().height();

	int j, k, total=1, cur_width, cur_height=0;
	QList<QObject*> tmp;
	QDeclarativeItem *dec;
	QObject *i;

	r = new PMonitor();

	if((i = r->rootObject()->findChild<QDeclarativeItem *>("appPage")) == NULL |
	   (i = i->findChild<QDeclarativeItem *>("PC")) == NULL |
	   (i = i->findChild<QDeclarativeItem *>("PLV")) == NULL) {
		qFatal("Upgrade your version of MeeGo-UX-Panels");
	}
	fwidth = i->property("contentWidth").toInt();
	r->rootObject()->setProperty("width", fwidth);
	r->rootObject()->setProperty("height", height);

	QObject::connect(r->scene(), SIGNAL(changed(const QList<QRectF>&)),
			this, SLOT(invalidate(void)));

	setSceneRect(0, 0, width, height);

	const int p_width = fwidth /  NUM_C;
	const int p_height = height / NUM_R;
	for(j = 0; j < NUM_P; j++) {
		cache[j] = new QPixmap(p_width, p_height);
	}

	invalidate();
	engine()->addImageProvider(QLatin1String("gen"), this);

	setSource(QUrl::fromLocalFile("/usr/share/meego-ux-daemon/real.qml"));
	rootObject()->setProperty("contentWidth", fwidth);
	rootObject()->setProperty("contentHeight", height);
	rootObject()->setProperty("width", width);
	rootObject()->setProperty("height", height);

	dec =  qobject_cast<QDeclarativeItem*>(rootObject());
	tmp = dec->children();

	for(j = 0; j < NUM_R; j++) {
		cur_width = 0;
		for(k = 0; k < NUM_C; k++) {
			tmp.at(total)->setProperty("width", p_width);
			tmp.at(total)->setProperty("height", p_height);
			tmp.at(total)->setProperty("x", cur_width);
			tmp.at(total)->setProperty("y", cur_height);

			QString meh = QString(ISRC);
			meh += QString::number(total-1);
			tmp.at(total)->setProperty("source", meh);

			cur_width += p_width;
			total++;
		}
		cur_height += p_height;
	}

	setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);

	setOptimizationFlags(
		QGraphicsView::DontSavePainterState |
		QGraphicsView::DontAdjustForAntialiasing);

	setCacheMode(QGraphicsView::CacheBackground);
	scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
	viewport()->setAttribute(Qt::WA_PaintUnclipped);

	create_bg();
}

PanelView::~PanelView(void)
{
	int i;

	for(i = 0; i < NUM_P; i++) {
		delete cache[i];
	}

	delete r;
	delete background;
	delete bg_window;

}

void PanelView::keyPressEvent(QKeyEvent *e)
{
	r->keyPressEvent(e);
	return;
}

void PanelView::keyReleaseEvent(QKeyEvent *e)
{
	r->keyReleaseEvent(e);
	return;
}

void PanelView::mouseDoubleClickEvent(QMouseEvent *e)
{
	r->mouseDoubleClickEvent(e);
	return;
}

void PanelView::mousePressEvent(QMouseEvent *e)
{
	QDeclarativeItem *i;

	i = qobject_cast<QDeclarativeItem *>(rootObject());
	QPoint j(e->x() + i->property("contentX").toDouble(), e->y());
	QMouseEvent k(e->type(), j, e->button(), e->buttons(), e->modifiers());

	bg_window->mousePressEvent(e);
	r->mousePressEvent(&k);
	QDeclarativeView::mousePressEvent(e);
	return;
}

void PanelView::mouseReleaseEvent(QMouseEvent *e)
{
	bg_window->mouseReleaseEvent(e);
	r->mouseReleaseEvent(e);
	QDeclarativeView::mouseReleaseEvent(e);
	return;
}

void PanelView::tabletEvent(QTabletEvent *e)
{
	r->tabletEvent(e);
	return;
}

QPixmap PanelView::requestPixmap(const QString &id, QSize *size,
		const QSize &resize)
{
	int i = id.toInt();
	while(i >= NUM_P) { i -= NUM_P; }
	return *cache[i];
}

void PanelView::invalidate(void)
{
	int i,j,k,m;

	QPixmap *old, *tmp;
	QPainter p;

	QDeclarativeItem *dec;
	QList<QObject *> kids;
	QString src;

	const int height = qApp->desktop()->rect().height();
	const int p_width = fwidth /  NUM_C;
	const int p_height = height / NUM_R;
	const QRgb tran  = QColor(Qt::transparent).rgb();
	QRgb bg_color;

	dec = qobject_cast<QDeclarativeItem *>(rootObject());
	if(dec != NULL) {
		kids = dec->children();
	}

	int total = 0;
	for(i = 0; i < NUM_R; i++) {
		for(j = 0; j < NUM_C; j++) {
			old = cache[total];

			QImage img(p_width, p_height,QImage::Format_ARGB32_Premultiplied);

			p.begin(&img);
			r->viewport()->render(&p, QPoint(),
				 QRegion( p_width * j, p_height * i,
					  p_width, p_height));
			p.end();

			if(total == 0) {
				bg_color = img.pixel(0,0);
			}

			tmp = new QPixmap(p_width, p_height);
			tmp->convertFromImage(img,
				Qt::ColorOnly | Qt::NoOpaqueDetection);
			QBitmap mask = QBitmap::fromImage(
					img.createMaskFromColor(bg_color));
			tmp->setMask(mask);

			cache[total] = tmp;
			delete old;

			if(dec != NULL) {
				src = kids.at(total+1)->property("source").toString();
				k = src.right( src.size() - ISRC_LEN).toInt();
				src.truncate(ISRC_LEN);
				k += NUM_P;
				src += QString::number(k);
				kids.at(total+1)->setProperty("source", src);
			}

			total++;
		}
	}
	viewport()->update();
	return;
}

void PanelView::create_bg(void)
{
	const int width = qApp->desktop()->rect().width();
	const int height = qApp->desktop()->rect().height();

	bg_window = new PMonitor();
	bg_window->setSource(QUrl::fromLocalFile("/usr/share/meego-ux-daemon/background.qml"));
	background = new QPixmap(width, height);

	QObject::connect(bg_window->scene(), SIGNAL(changed(const QList<QRectF>&)),
			this, SLOT(bg_changed(void)));
}

void PanelView::bg_changed(void)
{
	QPainter bg_painter(background);
	bg_window->viewport()->render(&bg_painter);
	bg_painter.end();
	QBrush br(*background);
	br.setStyle(Qt::TexturePattern);
	setBackgroundBrush(br);

	scene()->invalidate(QRectF(0,0,0,0), QGraphicsScene::BackgroundLayer);
}

<|endoftext|>


<commit_before>#include "libtorrent/upnp.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/connection_queue.hpp"
#include <boost/bind.hpp>
#include <boost/ref.hpp>

using namespace libtorrent;

void callback(int tcp, int udp, std::string const& err)
{
	std::cerr << "tcp: " << tcp << ", udp: " << udp << ", error: \"" << err << "\"\n";
}

int main(int argc, char* argv[])
{
	io_service ios;
	std::string user_agent = "test agent";

	if (argc != 3)
	{
		std::cerr << "usage: " << argv[0] << " tcp-port udp-port" << std::endl;
		return 1;
	}

	connection_queue cc(ios);
	upnp upnp_handler(ios, cc, address_v4(), user_agent, &callback);

	deadline_timer timer(ios);
	timer.expires_from_now(seconds(2));
	timer.async_wait(boost::bind(&io_service::stop, boost::ref(ios)));

	std::cerr << "broadcasting for UPnP device" << std::endl;

	ios.reset();
	ios.run();

	upnp_handler.set_mappings(atoi(argv[1]), atoi(argv[2]));
	timer.expires_from_now(seconds(5));
	timer.async_wait(boost::bind(&io_service::stop, boost::ref(ios)));
	std::cerr << "mapping ports TCP: " << argv[1]
		<< " UDP: " << argv[2] << std::endl;

	ios.reset();
	ios.run();
	std::cerr << "removing mappings" << std::endl;
	upnp_handler.close();

	ios.reset();
	ios.run();
	std::cerr << "closing" << std::endl;
}

<commit_msg>fixed bug in test_upnp program<commit_after>#include "libtorrent/upnp.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/connection_queue.hpp"
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/intrusive_ptr.hpp>

using namespace libtorrent;

void callback(int tcp, int udp, std::string const& err)
{
	std::cerr << "tcp: " << tcp << ", udp: " << udp << ", error: \"" << err << "\"\n";
}

int main(int argc, char* argv[])
{
	io_service ios;
	std::string user_agent = "test agent";

	if (argc != 3)
	{
		std::cerr << "usage: " << argv[0] << " tcp-port udp-port" << std::endl;
		return 1;
	}

	connection_queue cc(ios);
	boost::intrusive_ptr<upnp> upnp_handler = new upnp(ios, cc, address_v4(), user_agent, &callback);

	deadline_timer timer(ios);
	timer.expires_from_now(seconds(2));
	timer.async_wait(boost::bind(&io_service::stop, boost::ref(ios)));

	std::cerr << "broadcasting for UPnP device" << std::endl;

	ios.reset();
	ios.run();

	upnp_handler->set_mappings(atoi(argv[1]), atoi(argv[2]));
	timer.expires_from_now(seconds(5));
	timer.async_wait(boost::bind(&io_service::stop, boost::ref(ios)));
	std::cerr << "mapping ports TCP: " << argv[1]
		<< " UDP: " << argv[2] << std::endl;

	ios.reset();
	ios.run();
	std::cerr << "removing mappings" << std::endl;
	upnp_handler->close();

	ios.reset();
	ios.run();
	std::cerr << "closing" << std::endl;
}

<|endoftext|>


<commit_before>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// 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 <gtest/gtest.h>

#include <string>

#include "rcl/rcl.h"
#include "rcl/node.h"

#include "../memory_tools.hpp"
#include "../scope_exit.hpp"
#include "rcl/error_handling.h"

class TestNodeFixture : public::testing::Test
{
public:
  void SetUp()
  {
    set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
    set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
    set_on_unexpected_free_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED FREE";});
    start_memory_checking();
  }

  void TearDown()
  {
    assert_no_malloc_end();
    assert_no_realloc_end();
    assert_no_free_end();
    stop_memory_checking();
    set_on_unexpected_malloc_callback(nullptr);
    set_on_unexpected_realloc_callback(nullptr);
    set_on_unexpected_free_callback(nullptr);
  }
};

void *
failing_malloc(size_t size, void * state)
{
  (void)(size);
  (void)(state);
  return nullptr;
}

void *
failing_realloc(void * pointer, size_t size, void * state)
{
  (void)(pointer);
  (void)(size);
  (void)(state);
  return nullptr;
}

void
failing_free(void * pointer, void * state)
{
  (void)pointer;
  (void)state;
}

/* Tests the node accessors, i.e. rcl_node_get_* functions.
 */
TEST_F(TestNodeFixture, test_rcl_node_accessors) {
  stop_memory_checking();
  rcl_ret_t ret;
  // Initialize rcl with rcl_init().
  ret = rcl_init(0, nullptr, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret);  // Shutdown later after invalid node.
  // Create an invalid node (rcl_shutdown).
  rcl_node_t invalid_node = rcl_get_zero_initialized_node();
  const char * name = "node_name";
  rcl_node_options_t default_options = rcl_node_get_default_options();
  default_options.domain_id = 42;  // Set the domain id to something explicit.
  ret = rcl_node_init(&invalid_node, name, &default_options);
  ASSERT_EQ(RCL_RET_OK, ret);
  auto rcl_invalid_node_exit = make_scope_exit([&invalid_node]() {
    stop_memory_checking();
    rcl_ret_t ret = rcl_node_fini(&invalid_node);
    EXPECT_EQ(RCL_RET_OK, ret);
  });
  ret = rcl_shutdown();  // Shutdown to invalidate the node.
  ASSERT_EQ(RCL_RET_OK, ret);
  ret = rcl_init(0, nullptr, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret);
  auto rcl_shutdown_exit = make_scope_exit([]() {
    stop_memory_checking();
    rcl_ret_t ret = rcl_shutdown();
    ASSERT_EQ(RCL_RET_OK, ret);
  });
  // Create a zero init node.
  rcl_node_t zero_node = rcl_get_zero_initialized_node();
  // Create a normal node.
  rcl_node_t node = rcl_get_zero_initialized_node();
  ret = rcl_node_init(&node, name, &default_options);
  ASSERT_EQ(RCL_RET_OK, ret);
  auto rcl_node_exit = make_scope_exit([&node]() {
    stop_memory_checking();
    rcl_ret_t ret = rcl_node_fini(&node);
    EXPECT_EQ(RCL_RET_OK, ret);
  });
  // Test rcl_node_get_name().
  const char * actual_node_name;
  actual_node_name = rcl_node_get_name(nullptr);
  EXPECT_EQ(nullptr, actual_node_name);
  rcl_reset_error();
  actual_node_name = rcl_node_get_name(&zero_node);
  EXPECT_EQ(nullptr, actual_node_name);
  rcl_reset_error();
  actual_node_name = rcl_node_get_name(&invalid_node);
  EXPECT_EQ(nullptr, actual_node_name);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  actual_node_name = rcl_node_get_name(&node);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_TRUE(actual_node_name ? true : false);
  if (actual_node_name) {
    EXPECT_EQ(std::string(name), std::string(actual_node_name));
  }
  // Test rcl_node_get_options().
  const rcl_node_options_t * actual_options;
  actual_options = rcl_node_get_options(nullptr);
  EXPECT_EQ(nullptr, actual_options);
  rcl_reset_error();
  actual_options = rcl_node_get_options(&zero_node);
  EXPECT_EQ(nullptr, actual_options);
  rcl_reset_error();
  actual_options = rcl_node_get_options(&invalid_node);
  EXPECT_EQ(nullptr, actual_options);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  actual_options = rcl_node_get_options(&node);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_NE(nullptr, actual_options);
  if (actual_options) {
    EXPECT_EQ(default_options.allocator.allocate, actual_options->allocator.allocate);
    EXPECT_EQ(default_options.domain_id, actual_options->domain_id);
  }
  // Test rcl_node_get_domain_id().
  size_t actual_domain_id;
  ret = rcl_node_get_domain_id(nullptr, &actual_domain_id);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ret = rcl_node_get_domain_id(&zero_node, &actual_domain_id);
  EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
  rcl_reset_error();
  ret = rcl_node_get_domain_id(&invalid_node, &actual_domain_id);
  EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  ret = rcl_node_get_domain_id(&node, &actual_domain_id);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_EQ(RCL_RET_OK, ret);
  if (RCL_RET_OK == ret) {
    EXPECT_EQ(42, actual_domain_id);
  }
  // Test rcl_node_get_rmw_handle().
  rmw_node_t * node_handle;
  node_handle = rcl_node_get_rmw_handle(nullptr);
  EXPECT_EQ(nullptr, node_handle);
  rcl_reset_error();
  node_handle = rcl_node_get_rmw_handle(&zero_node);
  EXPECT_EQ(nullptr, node_handle);
  rcl_reset_error();
  node_handle = rcl_node_get_rmw_handle(&invalid_node);
  EXPECT_EQ(nullptr, node_handle);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  node_handle = rcl_node_get_rmw_handle(&node);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_NE(nullptr, node_handle);
  // Test rcl_node_get_rcl_instance_id().
  uint64_t instance_id;
  instance_id = rcl_node_get_rcl_instance_id(nullptr);
  EXPECT_EQ(0, instance_id);
  rcl_reset_error();
  instance_id = rcl_node_get_rcl_instance_id(&zero_node);
  EXPECT_EQ(0, instance_id);
  rcl_reset_error();
  instance_id = rcl_node_get_rcl_instance_id(&invalid_node);
  EXPECT_NE(0, instance_id);
  EXPECT_NE(42, instance_id);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  instance_id = rcl_node_get_rcl_instance_id(&node);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_NE(0, instance_id);
}

/* Tests the node life cycle, including rcl_node_init() and rcl_node_fini().
 */
TEST_F(TestNodeFixture, test_rcl_node_life_cycle) {
  stop_memory_checking();
  rcl_ret_t ret;
  rcl_node_t node = rcl_get_zero_initialized_node();
  const char * name = "node_name";
  rcl_node_options_t default_options = rcl_node_get_default_options();
  // Trying to init before rcl_init() should fail.
  ret = rcl_node_init(&node, name, &default_options);
  ASSERT_EQ(RCL_RET_NOT_INIT, ret) << "Expected RCL_RET_NOT_INIT";
  rcl_reset_error();
  // Initialize rcl with rcl_init().
  ret = rcl_init(0, nullptr, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret);
  auto rcl_shutdown_exit = make_scope_exit([]() {
    rcl_ret_t ret = rcl_shutdown();
    ASSERT_EQ(RCL_RET_OK, ret);
  });
  // Try invalid arguments.
  ret = rcl_node_init(nullptr, name, &default_options);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ret = rcl_node_init(&node, nullptr, &default_options);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ret = rcl_node_init(&node, name, nullptr);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  // Try with invalid allocator.
  rcl_node_options_t options_with_invalid_allocator = rcl_node_get_default_options();
  options_with_invalid_allocator.allocator.allocate = nullptr;
  options_with_invalid_allocator.allocator.deallocate = nullptr;
  options_with_invalid_allocator.allocator.reallocate = nullptr;
  ret = rcl_node_init(&node, name, &options_with_invalid_allocator);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << "Expected RCL_RET_INVALID_ARGUMENT";
  rcl_reset_error();
  node = rcl_get_zero_initialized_node();
  // Try with failing allocator.
  rcl_node_options_t options_with_failing_allocator = rcl_node_get_default_options();
  options_with_failing_allocator.allocator.allocate = failing_malloc;
  options_with_failing_allocator.allocator.deallocate = failing_free;
  options_with_failing_allocator.allocator.reallocate = failing_realloc;
  ret = rcl_node_init(&node, name, &options_with_failing_allocator);
  EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << "Expected RCL_RET_BAD_ALLOC";
  rcl_reset_error();
  node = rcl_get_zero_initialized_node();
  // Try fini with invalid arguments.
  ret = rcl_node_fini(nullptr);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << "Expected RCL_RET_INVALID_ARGUMENT";
  rcl_reset_error();
  // Try fini with an uninitialized node.
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  // Try a normal init and fini.
  ret = rcl_node_init(&node, name, &default_options);
  EXPECT_EQ(RCL_RET_OK, ret);
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  node = rcl_get_zero_initialized_node();
  // Try repeated init and fini calls.
  ret = rcl_node_init(&node, name, &default_options);
  EXPECT_EQ(RCL_RET_OK, ret);
  ret = rcl_node_init(&node, name, &default_options);
  EXPECT_EQ(RCL_RET_ALREADY_INIT, ret) << "Expected RCL_RET_ALREADY_INIT";
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  node = rcl_get_zero_initialized_node();
  // Try with a specific domain id.
  rcl_node_options_t options_with_custom_domain_id = rcl_node_get_default_options();
  options_with_custom_domain_id.domain_id = 42;
  ret = rcl_node_init(&node, name, &options_with_custom_domain_id);
  EXPECT_EQ(RCL_RET_OK, ret);
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  node = rcl_get_zero_initialized_node();
}
<commit_msg>allow fail of custom domain id on Win/OpenSplice<commit_after>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// 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 <gtest/gtest.h>

#include <string>

#include "rcl/rcl.h"
#include "rcl/node.h"
#include "rmw/rmw.h"  // For rmw_get_implementation_identifier.

#include "../memory_tools.hpp"
#include "../scope_exit.hpp"
#include "rcl/error_handling.h"

class TestNodeFixture : public::testing::Test
{
public:
  void SetUp()
  {
    set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";});
    set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";});
    set_on_unexpected_free_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED FREE";});
    start_memory_checking();
  }

  void TearDown()
  {
    assert_no_malloc_end();
    assert_no_realloc_end();
    assert_no_free_end();
    stop_memory_checking();
    set_on_unexpected_malloc_callback(nullptr);
    set_on_unexpected_realloc_callback(nullptr);
    set_on_unexpected_free_callback(nullptr);
  }
};

void *
failing_malloc(size_t size, void * state)
{
  (void)(size);
  (void)(state);
  return nullptr;
}

void *
failing_realloc(void * pointer, size_t size, void * state)
{
  (void)(pointer);
  (void)(size);
  (void)(state);
  return nullptr;
}

void
failing_free(void * pointer, void * state)
{
  (void)pointer;
  (void)state;
}

bool is_opensplice =
  std::string(rmw_get_implementation_identifier()).find("opensplice") != std::string::npos;
#if defined(WIN32)
bool is_windows = true;
#else
bool is_windows = false;
#endif

/* Tests the node accessors, i.e. rcl_node_get_* functions.
 */
TEST_F(TestNodeFixture, test_rcl_node_accessors) {
  stop_memory_checking();
  rcl_ret_t ret;
  // Initialize rcl with rcl_init().
  ret = rcl_init(0, nullptr, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret);  // Shutdown later after invalid node.
  // Create an invalid node (rcl_shutdown).
  rcl_node_t invalid_node = rcl_get_zero_initialized_node();
  const char * name = "node_name";
  rcl_node_options_t default_options = rcl_node_get_default_options();
  default_options.domain_id = 42;  // Set the domain id to something explicit.
  ret = rcl_node_init(&invalid_node, name, &default_options);
  if (is_windows && is_opensplice) {
    // On Windows with OpenSplice, setting the domain id is not expected to work.
    ASSERT_NE(RCL_RET_OK, ret);
    // So retry with the default domain id setting (uses the environment as is).
    default_options.domain_id = rcl_node_get_default_options().domain_id;
    ret = rcl_node_init(&invalid_node, name, &default_options);
    ASSERT_EQ(RCL_RET_OK, ret);
  } else {
    // This is the normal check (not windows and windows if not opensplice)
    ASSERT_EQ(RCL_RET_OK, ret);
  }
  auto rcl_invalid_node_exit = make_scope_exit([&invalid_node]() {
    stop_memory_checking();
    rcl_ret_t ret = rcl_node_fini(&invalid_node);
    EXPECT_EQ(RCL_RET_OK, ret);
  });
  ret = rcl_shutdown();  // Shutdown to invalidate the node.
  ASSERT_EQ(RCL_RET_OK, ret);
  ret = rcl_init(0, nullptr, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret);
  auto rcl_shutdown_exit = make_scope_exit([]() {
    stop_memory_checking();
    rcl_ret_t ret = rcl_shutdown();
    ASSERT_EQ(RCL_RET_OK, ret);
  });
  // Create a zero init node.
  rcl_node_t zero_node = rcl_get_zero_initialized_node();
  // Create a normal node.
  rcl_node_t node = rcl_get_zero_initialized_node();
  ret = rcl_node_init(&node, name, &default_options);
  ASSERT_EQ(RCL_RET_OK, ret);
  auto rcl_node_exit = make_scope_exit([&node]() {
    stop_memory_checking();
    rcl_ret_t ret = rcl_node_fini(&node);
    EXPECT_EQ(RCL_RET_OK, ret);
  });
  // Test rcl_node_get_name().
  const char * actual_node_name;
  actual_node_name = rcl_node_get_name(nullptr);
  EXPECT_EQ(nullptr, actual_node_name);
  rcl_reset_error();
  actual_node_name = rcl_node_get_name(&zero_node);
  EXPECT_EQ(nullptr, actual_node_name);
  rcl_reset_error();
  actual_node_name = rcl_node_get_name(&invalid_node);
  EXPECT_EQ(nullptr, actual_node_name);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  actual_node_name = rcl_node_get_name(&node);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_TRUE(actual_node_name ? true : false);
  if (actual_node_name) {
    EXPECT_EQ(std::string(name), std::string(actual_node_name));
  }
  // Test rcl_node_get_options().
  const rcl_node_options_t * actual_options;
  actual_options = rcl_node_get_options(nullptr);
  EXPECT_EQ(nullptr, actual_options);
  rcl_reset_error();
  actual_options = rcl_node_get_options(&zero_node);
  EXPECT_EQ(nullptr, actual_options);
  rcl_reset_error();
  actual_options = rcl_node_get_options(&invalid_node);
  EXPECT_EQ(nullptr, actual_options);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  actual_options = rcl_node_get_options(&node);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_NE(nullptr, actual_options);
  if (actual_options) {
    EXPECT_EQ(default_options.allocator.allocate, actual_options->allocator.allocate);
    EXPECT_EQ(default_options.domain_id, actual_options->domain_id);
  }
  // Test rcl_node_get_domain_id().
  size_t actual_domain_id;
  ret = rcl_node_get_domain_id(nullptr, &actual_domain_id);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ret = rcl_node_get_domain_id(&zero_node, &actual_domain_id);
  EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
  rcl_reset_error();
  ret = rcl_node_get_domain_id(&invalid_node, &actual_domain_id);
  EXPECT_EQ(RCL_RET_NODE_INVALID, ret);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  ret = rcl_node_get_domain_id(&node, &actual_domain_id);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_EQ(RCL_RET_OK, ret);
  if (RCL_RET_OK == ret && (!is_windows || !is_opensplice)) {
    // Can only expect the domain id to be 42 if not windows or not opensplice.
    EXPECT_EQ(42, actual_domain_id);
  }
  // Test rcl_node_get_rmw_handle().
  rmw_node_t * node_handle;
  node_handle = rcl_node_get_rmw_handle(nullptr);
  EXPECT_EQ(nullptr, node_handle);
  rcl_reset_error();
  node_handle = rcl_node_get_rmw_handle(&zero_node);
  EXPECT_EQ(nullptr, node_handle);
  rcl_reset_error();
  node_handle = rcl_node_get_rmw_handle(&invalid_node);
  EXPECT_EQ(nullptr, node_handle);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  node_handle = rcl_node_get_rmw_handle(&node);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_NE(nullptr, node_handle);
  // Test rcl_node_get_rcl_instance_id().
  uint64_t instance_id;
  instance_id = rcl_node_get_rcl_instance_id(nullptr);
  EXPECT_EQ(0, instance_id);
  rcl_reset_error();
  instance_id = rcl_node_get_rcl_instance_id(&zero_node);
  EXPECT_EQ(0, instance_id);
  rcl_reset_error();
  instance_id = rcl_node_get_rcl_instance_id(&invalid_node);
  EXPECT_NE(0, instance_id);
  EXPECT_NE(42, instance_id);
  rcl_reset_error();
  start_memory_checking();
  assert_no_malloc_begin();
  assert_no_realloc_begin();
  assert_no_free_begin();
  instance_id = rcl_node_get_rcl_instance_id(&node);
  assert_no_malloc_end();
  assert_no_realloc_end();
  assert_no_free_end();
  stop_memory_checking();
  EXPECT_NE(0, instance_id);
}

/* Tests the node life cycle, including rcl_node_init() and rcl_node_fini().
 */
TEST_F(TestNodeFixture, test_rcl_node_life_cycle) {
  stop_memory_checking();
  rcl_ret_t ret;
  rcl_node_t node = rcl_get_zero_initialized_node();
  const char * name = "node_name";
  rcl_node_options_t default_options = rcl_node_get_default_options();
  // Trying to init before rcl_init() should fail.
  ret = rcl_node_init(&node, name, &default_options);
  ASSERT_EQ(RCL_RET_NOT_INIT, ret) << "Expected RCL_RET_NOT_INIT";
  rcl_reset_error();
  // Initialize rcl with rcl_init().
  ret = rcl_init(0, nullptr, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret);
  auto rcl_shutdown_exit = make_scope_exit([]() {
    rcl_ret_t ret = rcl_shutdown();
    ASSERT_EQ(RCL_RET_OK, ret);
  });
  // Try invalid arguments.
  ret = rcl_node_init(nullptr, name, &default_options);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ret = rcl_node_init(&node, nullptr, &default_options);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ret = rcl_node_init(&node, name, nullptr);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  // Try with invalid allocator.
  rcl_node_options_t options_with_invalid_allocator = rcl_node_get_default_options();
  options_with_invalid_allocator.allocator.allocate = nullptr;
  options_with_invalid_allocator.allocator.deallocate = nullptr;
  options_with_invalid_allocator.allocator.reallocate = nullptr;
  ret = rcl_node_init(&node, name, &options_with_invalid_allocator);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << "Expected RCL_RET_INVALID_ARGUMENT";
  rcl_reset_error();
  node = rcl_get_zero_initialized_node();
  // Try with failing allocator.
  rcl_node_options_t options_with_failing_allocator = rcl_node_get_default_options();
  options_with_failing_allocator.allocator.allocate = failing_malloc;
  options_with_failing_allocator.allocator.deallocate = failing_free;
  options_with_failing_allocator.allocator.reallocate = failing_realloc;
  ret = rcl_node_init(&node, name, &options_with_failing_allocator);
  EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << "Expected RCL_RET_BAD_ALLOC";
  rcl_reset_error();
  node = rcl_get_zero_initialized_node();
  // Try fini with invalid arguments.
  ret = rcl_node_fini(nullptr);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << "Expected RCL_RET_INVALID_ARGUMENT";
  rcl_reset_error();
  // Try fini with an uninitialized node.
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  // Try a normal init and fini.
  ret = rcl_node_init(&node, name, &default_options);
  EXPECT_EQ(RCL_RET_OK, ret);
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  node = rcl_get_zero_initialized_node();
  // Try repeated init and fini calls.
  ret = rcl_node_init(&node, name, &default_options);
  EXPECT_EQ(RCL_RET_OK, ret);
  ret = rcl_node_init(&node, name, &default_options);
  EXPECT_EQ(RCL_RET_ALREADY_INIT, ret) << "Expected RCL_RET_ALREADY_INIT";
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  ret = rcl_node_fini(&node);
  EXPECT_EQ(RCL_RET_OK, ret);
  node = rcl_get_zero_initialized_node();
  // Try with a specific domain id.
  rcl_node_options_t options_with_custom_domain_id = rcl_node_get_default_options();
  options_with_custom_domain_id.domain_id = 42;
  ret = rcl_node_init(&node, name, &options_with_custom_domain_id);
  if (is_windows && is_opensplice) {
    // A custom domain id is not expected to work on Windows with Opensplice.
    EXPECT_NE(RCL_RET_OK, ret);
    node = rcl_get_zero_initialized_node();
  } else {
    // This is the normal check.
    EXPECT_EQ(RCL_RET_OK, ret);
    ret = rcl_node_fini(&node);
    EXPECT_EQ(RCL_RET_OK, ret);
    node = rcl_get_zero_initialized_node();
  }
}
<|endoftext|>


<commit_before>/* vim: set sw=4 ts=4: */
/*
 * BindingConverter.cpp
 * Implements an AST Consumer that outputs clay bindings
 *
 */

#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

#include "llvm/Config/config.h"
#include "llvm/Support/raw_ostream.h"

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "llvm/ADT/Triple.h"

#include "BindingsConverter.h"

using namespace clang;
using namespace llvm;

BindingsConverter::BindingsConverter(ostream& out)
    : out(out) {
}

string BindingsConverter::allocateName(const string &base)
{
    if (!allocatedNames.count(base)) {
        allocatedNames.insert(base);
        return base;
    }
    unsigned i = 0;
    string s;
    while (true) {
        ostringstream out;
        out << base << i;
        s = out.str();
        if (!allocatedNames.count(s))
            break;
        ++i;
    }
    allocatedNames.insert(s);
    return s;
}

string BindingsConverter::convertBuiltinType(const BuiltinType *type) {
    switch (type->getKind()) {
    case BuiltinType::Void : return "Void";

    case BuiltinType::Bool : return "Bool";

    case BuiltinType::Char_U : return "CUChar";
    case BuiltinType::UChar : return "CUChar";
    case BuiltinType::UShort : return "UShort";
    case BuiltinType::UInt : return "UInt";
    case BuiltinType::ULong : return "CULong";
    case BuiltinType::ULongLong : return "UInt64";

    case BuiltinType::Char_S : return "CChar";
    case BuiltinType::SChar : return "CChar";
    case BuiltinType::Short : return "Short";
    case BuiltinType::Int : return "Int";
    case BuiltinType::Long : return "CLong";
    case BuiltinType::LongLong : return "Int64";

    case BuiltinType::Float : return "Float";
    case BuiltinType::Double : return "Double";

    default : {
        ostringstream out;
        out << type->getKind();
        return "UnsupportedCBuiltinType" + out.str();
    }
    }
}

string BindingsConverter::convertFPType(FunctionNoProtoType *type)
{
    const Type *rt = type->getResultType().getTypePtr();
    return "CCodePointer[" + convertType(rt) + "]";
}

string BindingsConverter::convertFPType(FunctionProtoType *type)
{
    ostringstream sout;
    sout << "CCodePointer[";
    FunctionProtoType::arg_type_iterator i, e;
    for (i = type->arg_type_begin(), e = type->arg_type_end(); i != e; ++i) {
        const Type *argType = i->getTypePtr();
        sout << convertType(argType) << ",";
    }
    const Type *rt = type->getResultType().getTypePtr();
    sout << convertType(rt) << "]";
    return sout.str();
}

string BindingsConverter::convertType(const Type *type)
{
    const Type *ctype = type->getCanonicalTypeUnqualified().getTypePtr();
    if (ctype->getTypeClass() == Type::Builtin)
        return convertBuiltinType((const BuiltinType *)ctype);

    switch (type->getTypeClass()) {
    case Type::Typedef : {
        TypedefType *t = (TypedefType *)type;
        TypedefDecl *decl = t->getDecl();
        string name = decl->getName().str();
        const string &outName = typedefNames[name];
        assert(!outName.empty());
        return outName;
    }
    case Type::Record : {
        RecordType *t = (RecordType *)type;
        RecordDecl *decl = t->getDecl();
        if (decl->isUnion())
            return "AUnionType";
        string name = decl->getName().str();
        if (name.empty()) {
            assert(anonRecordNames.count(decl));
            return anonRecordNames[decl];
        }
        if (recordBodies.count(name)) {
            return recordNames[name];
        }
        return "Opaque";
    }
    case Type::Enum :
        return "Int";
    case Type::Pointer : {
        PointerType *t = (PointerType *)type;
        const Type *pt = t->getPointeeType().getTypePtr();
        switch (pt->getTypeClass()) {
        case Type::FunctionNoProto :
            return convertFPType((FunctionNoProtoType *)pt);
        case Type::FunctionProto :
            return convertFPType((FunctionProtoType *)pt);
        default :
            break;
        }
        if (pt->getTypeClass() == Type::Record) {
            RecordType *rt = (RecordType *)pt;
            RecordDecl *decl = rt->getDecl();
            string name = decl->getName().str();
            if (!name.empty() && !recordBodies.count(name))
                return "OpaquePointer";
        }
        string inner = convertType(pt);
        if (inner == "Void")
            return "RawPointer";
        return "Pointer[" + inner + "]";
    }
    case Type::ConstantArray : {
        ConstantArrayType *t = (ConstantArrayType *)type;
        ostringstream sout;
        sout << "Array[" << convertType(t->getElementType().getTypePtr());
        sout << "," << t->getSize().getZExtValue() << "]";
        return sout.str();
    }
    case Type::IncompleteArray : {
        IncompleteArrayType *t = (IncompleteArrayType *)type;
        const Type *et = t->getElementType().getTypePtr();
        return "Pointer[" + convertType(et) + "]";
    }
    default : {
        string str = type->getCanonicalTypeInternal().getAsString();
        cerr << "unknown type: " << str << '\n';
        return "UnknownType";
    }
    }
}

// Handle top level declarations observed in the program
void BindingsConverter::HandleTopLevelDecl(DeclGroupRef DG)
{
    for (DeclGroupRef::iterator it = DG.begin(); it != DG.end(); ++it) {
        Decl *decl = *it;
        decls.push_back(decl);

        switch (decl->getKind()) {
        case Decl::Record : {
            RecordDecl *x = (RecordDecl *)decl;
            string name = x->getName().str();
            if (!x->isUnion() &&
                x->isDefinition())
            {
                if (name.empty()) {
                    string outName = allocateName("UnnamedRecord");
                    anonRecordNames[x] = outName;
                }
                else {
                    assert(!recordBodies.count(name));
                    recordBodies[name] = x;
                    string outName = allocateName(name);
                    recordNames[name] = outName;
                }
            }
            break;
        }
        case Decl::Typedef : {
            TypedefDecl *x = (TypedefDecl *)decl;
            string name = x->getName().str();
            string outName = allocateName(name);
            typedefNames[name] = outName;
            break;
        }
        default :
            break;
        }
    }
}

void BindingsConverter::generate()
{
    generateHeader();
    for (unsigned i = 0; i < decls.size(); ++i) {
        Decl *decl = decls[i];
        switch (decl->getKind()) {
        case Decl::Typedef : {
            TypedefDecl *x = (TypedefDecl *)decl;
            string name = x->getName().str();
            const Type *t = x->getTypeSourceInfo()->getType().getTypePtr();
            string type = convertType(t);
            out << '\n';
            out << "static " << typedefNames[name] << " = "
                << convertType(t) << ";" << '\n';
            break;
        }
        case Decl::Enum : {
            EnumDecl *x = (EnumDecl *)decl;
            EnumDecl::enumerator_iterator i = x->enumerator_begin();
            EnumDecl::enumerator_iterator e = x->enumerator_end();
            out << '\n';
            for (; i != e; ++i) {
                EnumConstantDecl *y = *i;
                out << "static " << y->getName().str() << " = "
                    << y->getInitVal().getZExtValue() << ";\n";
            }
            break;
        }
        case Decl::Record : {
            RecordDecl *x = (RecordDecl *)decl;
            string name = x->getName().str();
            if (!x->isUnion() &&
                x->isDefinition())
            {
                string outName = name.empty() ?
                    anonRecordNames[x] : recordNames[name];
                out << '\n';
                out << "record " << outName << " {\n";
                RecordDecl::field_iterator i, e;
                int index = 0;
                for (i = x->field_begin(), e = x->field_end(); i != e; ++i) {
                    FieldDecl *y = *i;
                    string fname = y->getName().str();
                    const Type *t = y->getType().getTypePtr();
                    out << "    ";
                    if (fname.empty())
                        out << "unnamed_field" << index;
                    else
                        out << fname;
                    out << " : " << convertType(t) << ";\n";
                    ++index;
                }
                out << "}\n";
            }
            break;
        }
        case Decl::Function : {
            FunctionDecl *x = (FunctionDecl *)decl;
            string name = x->getName().str();
            if (!x->isThisDeclarationADefinition() &&
                !x->isInlineSpecified() &&
                (x->getStorageClass() == FunctionDecl::Extern ||
                 x->getStorageClass() == FunctionDecl::None) &&
                !externsDeclared.count(name))
            {
                externsDeclared.insert(name);
                out << '\n';
                out << "external " << name << "(";
                FunctionDecl::param_iterator i, e;
                int index = 0;
                for (i = x->param_begin(), e = x->param_end(); i != e; ++i) {
                    ParmVarDecl *y = *i;
                    string pname = y->getName().str();
                    if (index != 0)
                        out << ",";
                    out << "\n    ";
                    if (pname.empty())
                        out << "argument" << index;
                    else
                        out << pname;
                    const Type *t = y->getType().getTypePtr();
                    out << " : " << convertType(t);
                    ++index;
                }
                const Type *ft = x->getType().getTypePtr();
                if (ft->getTypeClass() == Type::FunctionProto) {
                    FunctionProtoType *fpt = (FunctionProtoType *)ft;
                    if (fpt->isVariadic()) {
                        if (index != 0)
                            out << ",";
                        out << "\n    ";
                        out << "...";
                    }
                }
                const Type *rt = x->getResultType().getTypePtr();
                out << ") : " << convertType(rt) << ";\n";
            }
            break;
        }
        case Decl::Var : {
            VarDecl *x = (VarDecl *)decl;
            string name = x->getName().str();
            if ((x->getStorageClass() == VarDecl::Extern) &&
                !x->hasInit() &&
                !externsDeclared.count(name))
            {
                externsDeclared.insert(name);
                const Type *t = x->getType().getTypePtr();
                out << '\n';
                out << "external " << name << " : "
                    << convertType(t) << ";\n";
            }
            break;
        }
        default :
            break;
        }
    }
}

void BindingsConverter::generateHeader()
{
    out << "// Auto-Generated by BindingsGenerator\n";
    out << '\n';
    out << "import types.*;\n";
    out << "import operators.*;\n";
    out << "import numbers.*;\n";
    out << "import pointers.*;\n";
    out << '\n';
    out << "private static OpaquePointer = RawPointer;\n";
    out << "private static UnknownType = Int;\n";
    out << "private static AUnionType = Int;\n";
    out << '\n';
}
<commit_msg>in the bindings generator, added support for (non-pointer) function type typedefs.<commit_after>/* vim: set sw=4 ts=4: */
/*
 * BindingConverter.cpp
 * Implements an AST Consumer that outputs clay bindings
 *
 */

#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

#include "llvm/Config/config.h"
#include "llvm/Support/raw_ostream.h"

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "llvm/ADT/Triple.h"

#include "BindingsConverter.h"

using namespace clang;
using namespace llvm;

BindingsConverter::BindingsConverter(ostream& out)
    : out(out) {
}

string BindingsConverter::allocateName(const string &base)
{
    if (!allocatedNames.count(base)) {
        allocatedNames.insert(base);
        return base;
    }
    unsigned i = 0;
    string s;
    while (true) {
        ostringstream out;
        out << base << i;
        s = out.str();
        if (!allocatedNames.count(s))
            break;
        ++i;
    }
    allocatedNames.insert(s);
    return s;
}

string BindingsConverter::convertBuiltinType(const BuiltinType *type) {
    switch (type->getKind()) {
    case BuiltinType::Void : return "Void";

    case BuiltinType::Bool : return "Bool";

    case BuiltinType::Char_U : return "CUChar";
    case BuiltinType::UChar : return "CUChar";
    case BuiltinType::UShort : return "UShort";
    case BuiltinType::UInt : return "UInt";
    case BuiltinType::ULong : return "CULong";
    case BuiltinType::ULongLong : return "UInt64";

    case BuiltinType::Char_S : return "CChar";
    case BuiltinType::SChar : return "CChar";
    case BuiltinType::Short : return "Short";
    case BuiltinType::Int : return "Int";
    case BuiltinType::Long : return "CLong";
    case BuiltinType::LongLong : return "Int64";

    case BuiltinType::Float : return "Float";
    case BuiltinType::Double : return "Double";

    default : {
        ostringstream out;
        out << type->getKind();
        return "UnsupportedCBuiltinType" + out.str();
    }
    }
}

string BindingsConverter::convertFPType(FunctionNoProtoType *type)
{
    const Type *rt = type->getResultType().getTypePtr();
    return "CCodePointer[" + convertType(rt) + "]";
}

string BindingsConverter::convertFPType(FunctionProtoType *type)
{
    ostringstream sout;
    sout << "CCodePointer[";
    FunctionProtoType::arg_type_iterator i, e;
    for (i = type->arg_type_begin(), e = type->arg_type_end(); i != e; ++i) {
        const Type *argType = i->getTypePtr();
        sout << convertType(argType) << ",";
    }
    const Type *rt = type->getResultType().getTypePtr();
    sout << convertType(rt) << "]";
    return sout.str();
}

string BindingsConverter::convertType(const Type *type)
{
    const Type *ctype = type->getCanonicalTypeUnqualified().getTypePtr();
    if (ctype->getTypeClass() == Type::Builtin)
        return convertBuiltinType((const BuiltinType *)ctype);

    switch (type->getTypeClass()) {
    case Type::Typedef : {
        TypedefType *t = (TypedefType *)type;
        TypedefDecl *decl = t->getDecl();
        string name = decl->getName().str();
        const string &outName = typedefNames[name];
        assert(!outName.empty());
        return outName;
    }
    case Type::Record : {
        RecordType *t = (RecordType *)type;
        RecordDecl *decl = t->getDecl();
        if (decl->isUnion())
            return "AUnionType";
        string name = decl->getName().str();
        if (name.empty()) {
            assert(anonRecordNames.count(decl));
            return anonRecordNames[decl];
        }
        if (recordBodies.count(name)) {
            return recordNames[name];
        }
        return "Opaque";
    }
    case Type::Enum :
        return "Int";
    case Type::Pointer : {
        PointerType *t = (PointerType *)type;
        const Type *pt = t->getPointeeType().getTypePtr();
        const Type *pt2 = pt->getCanonicalTypeUnqualified().getTypePtr();
        switch (pt2->getTypeClass()) {
        case Type::FunctionNoProto :
            return convertFPType((FunctionNoProtoType *)pt2);
        case Type::FunctionProto :
            return convertFPType((FunctionProtoType *)pt2);
        default :
            break;
        }
        if (pt->getTypeClass() == Type::Record) {
            RecordType *rt = (RecordType *)pt;
            RecordDecl *decl = rt->getDecl();
            string name = decl->getName().str();
            if (!name.empty() && !recordBodies.count(name))
                return "OpaquePointer";
        }
        string inner = convertType(pt);
        if (inner == "Void")
            return "RawPointer";
        return "Pointer[" + inner + "]";
    }
    case Type::ConstantArray : {
        ConstantArrayType *t = (ConstantArrayType *)type;
        ostringstream sout;
        sout << "Array[" << convertType(t->getElementType().getTypePtr());
        sout << "," << t->getSize().getZExtValue() << "]";
        return sout.str();
    }
    case Type::IncompleteArray : {
        IncompleteArrayType *t = (IncompleteArrayType *)type;
        const Type *et = t->getElementType().getTypePtr();
        return "Pointer[" + convertType(et) + "]";
    }
    default : {
        string str = type->getCanonicalTypeInternal().getAsString();
        cerr << "unknown type: " << str << '\n';
        return "UnknownType";
    }
    }
}

// Handle top level declarations observed in the program
void BindingsConverter::HandleTopLevelDecl(DeclGroupRef DG)
{
    for (DeclGroupRef::iterator it = DG.begin(); it != DG.end(); ++it) {
        Decl *decl = *it;
        decls.push_back(decl);

        switch (decl->getKind()) {
        case Decl::Record : {
            RecordDecl *x = (RecordDecl *)decl;
            string name = x->getName().str();
            if (!x->isUnion() &&
                x->isDefinition())
            {
                if (name.empty()) {
                    string outName = allocateName("UnnamedRecord");
                    anonRecordNames[x] = outName;
                }
                else {
                    assert(!recordBodies.count(name));
                    recordBodies[name] = x;
                    string outName = allocateName(name);
                    recordNames[name] = outName;
                }
            }
            break;
        }
        case Decl::Typedef : {
            TypedefDecl *x = (TypedefDecl *)decl;
            const Type *t = x->getTypeSourceInfo()->getType().getTypePtr();
            if (!t->isFunctionType()) {
                string name = x->getName().str();
                string outName = allocateName(name);
                typedefNames[name] = outName;
            }
            break;
        }
        default :
            break;
        }
    }
}

void BindingsConverter::generate()
{
    generateHeader();
    for (unsigned i = 0; i < decls.size(); ++i) {
        Decl *decl = decls[i];
        switch (decl->getKind()) {
        case Decl::Typedef : {
            TypedefDecl *x = (TypedefDecl *)decl;
            string name = x->getName().str();
            const Type *t = x->getTypeSourceInfo()->getType().getTypePtr();
            if (!t->isFunctionType()) {
                string type = convertType(t);
                out << '\n';
                out << "static " << typedefNames[name] << " = "
                    << convertType(t) << ";" << '\n';
            }
            break;
        }
        case Decl::Enum : {
            EnumDecl *x = (EnumDecl *)decl;
            EnumDecl::enumerator_iterator i = x->enumerator_begin();
            EnumDecl::enumerator_iterator e = x->enumerator_end();
            out << '\n';
            for (; i != e; ++i) {
                EnumConstantDecl *y = *i;
                out << "static " << y->getName().str() << " = "
                    << y->getInitVal().getZExtValue() << ";\n";
            }
            break;
        }
        case Decl::Record : {
            RecordDecl *x = (RecordDecl *)decl;
            string name = x->getName().str();
            if (!x->isUnion() &&
                x->isDefinition())
            {
                string outName = name.empty() ?
                    anonRecordNames[x] : recordNames[name];
                out << '\n';
                out << "record " << outName << " {\n";
                RecordDecl::field_iterator i, e;
                int index = 0;
                for (i = x->field_begin(), e = x->field_end(); i != e; ++i) {
                    FieldDecl *y = *i;
                    string fname = y->getName().str();
                    const Type *t = y->getType().getTypePtr();
                    out << "    ";
                    if (fname.empty())
                        out << "unnamed_field" << index;
                    else
                        out << fname;
                    out << " : " << convertType(t) << ";\n";
                    ++index;
                }
                out << "}\n";
            }
            break;
        }
        case Decl::Function : {
            FunctionDecl *x = (FunctionDecl *)decl;
            string name = x->getName().str();
            if (!x->isThisDeclarationADefinition() &&
                !x->isInlineSpecified() &&
                (x->getStorageClass() == FunctionDecl::Extern ||
                 x->getStorageClass() == FunctionDecl::None) &&
                !externsDeclared.count(name))
            {
                externsDeclared.insert(name);
                out << '\n';
                out << "external " << name << "(";
                FunctionDecl::param_iterator i, e;
                int index = 0;
                for (i = x->param_begin(), e = x->param_end(); i != e; ++i) {
                    ParmVarDecl *y = *i;
                    string pname = y->getName().str();
                    if (index != 0)
                        out << ",";
                    out << "\n    ";
                    if (pname.empty())
                        out << "argument" << index;
                    else
                        out << pname;
                    const Type *t = y->getType().getTypePtr();
                    out << " : " << convertType(t);
                    ++index;
                }
                const Type *ft = x->getType().getTypePtr();
                if (ft->getTypeClass() == Type::FunctionProto) {
                    FunctionProtoType *fpt = (FunctionProtoType *)ft;
                    if (fpt->isVariadic()) {
                        if (index != 0)
                            out << ",";
                        out << "\n    ";
                        out << "...";
                    }
                }
                const Type *rt = x->getResultType().getTypePtr();
                out << ") : " << convertType(rt) << ";\n";
            }
            break;
        }
        case Decl::Var : {
            VarDecl *x = (VarDecl *)decl;
            string name = x->getName().str();
            if ((x->getStorageClass() == VarDecl::Extern) &&
                !x->hasInit() &&
                !externsDeclared.count(name))
            {
                externsDeclared.insert(name);
                const Type *t = x->getType().getTypePtr();
                out << '\n';
                out << "external " << name << " : "
                    << convertType(t) << ";\n";
            }
            break;
        }
        default :
            break;
        }
    }
}

void BindingsConverter::generateHeader()
{
    out << "// Auto-Generated by BindingsGenerator\n";
    out << '\n';
    out << "import types.*;\n";
    out << "import operators.*;\n";
    out << "import numbers.*;\n";
    out << "import pointers.*;\n";
    out << '\n';
    out << "private static OpaquePointer = RawPointer;\n";
    out << "private static UnknownType = Int;\n";
    out << "private static AUnionType = Int;\n";
    out << '\n';
}
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2007. Use, modification and distribution is
// subject to 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)

#include <libtorrent/peer_info.hpp>
#include <libtorrent/bitfield.hpp>
#include <boost/python.hpp>
#include <boost/python/iterator.hpp>

using namespace boost::python;
using namespace libtorrent;

int get_last_active(peer_info const& pi)
{
    return total_seconds(pi.last_active);
}

int get_last_request(peer_info const& pi)
{
    return total_seconds(pi.last_request);
}

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
str get_country(peer_info const& pi)
{
    return str(pi.country, 2);
}
#endif

tuple get_ip(peer_info const& pi)
{
    return make_tuple(boost::lexical_cast<std::string>(pi.ip.address()), pi.ip.port());
}

list get_pieces(peer_info const& pi)
{
    list ret;

    for (bitfield::const_iterator i = pi.pieces.begin()
        , end(pi.pieces.end()); i != end; ++i)
    {
        ret.append(*i);
    }
    return ret;
}

void bind_peer_info()
{
    scope pi = class_<peer_info>("peer_info")
        .def_readonly("flags", &peer_info::flags)
        .def_readonly("source", &peer_info::source)
        .def_readonly("read_state", &peer_info::read_state)
        .def_readonly("write_state", &peer_info::write_state)
        .add_property("ip", get_ip)
        .def_readonly("up_speed", &peer_info::up_speed)
        .def_readonly("down_speed", &peer_info::down_speed)
        .def_readonly("payload_up_speed", &peer_info::payload_up_speed)
        .def_readonly("payload_down_speed", &peer_info::payload_down_speed)
        .def_readonly("total_download", &peer_info::total_download)
        .def_readonly("total_upload", &peer_info::total_upload)
        .def_readonly("pid", &peer_info::pid)
        .add_property("pieces", get_pieces)
        .def_readonly("upload_limit", &peer_info::upload_limit)
        .def_readonly("download_limit", &peer_info::download_limit)
        .add_property("last_request", get_last_request)
        .add_property("last_active", get_last_active)
        .def_readonly("send_buffer_size", &peer_info::send_buffer_size)
        .def_readonly("used_send_buffer", &peer_info::used_send_buffer)
        .def_readonly("num_hashfails", &peer_info::num_hashfails)
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .add_property("country", get_country)
#endif
#ifndef TORRENT_DISABLE_GEO_IP
        .def_readonly("inet_as_name", &peer_info::inet_as_name)
        .def_readonly("inet_as", &peer_info::inet_as)
#endif
        .def_readonly("load_balancing", &peer_info::load_balancing)
        .def_readonly("download_queue_length", &peer_info::download_queue_length)
        .def_readonly("upload_queue_length", &peer_info::upload_queue_length)
        .def_readonly("failcount", &peer_info::failcount)
        .def_readonly("downloading_piece_index", &peer_info::downloading_piece_index)
        .def_readonly("downloading_block_index", &peer_info::downloading_block_index)
        .def_readonly("downloading_progress", &peer_info::downloading_progress)
        .def_readonly("downloading_total", &peer_info::downloading_total)
        .def_readonly("client", &peer_info::client)
        .def_readonly("connection_type", &peer_info::connection_type)
        .def_readonly("remote_dl_rate", &peer_info::remote_dl_rate)
        .def_readonly("pending_disk_bytes", &peer_info::pending_disk_bytes)
        .def_readonly("send_quota", &peer_info::send_quota)
        .def_readonly("receive_quota", &peer_info::receive_quota)
        .def_readonly("rtt", &peer_info::rtt)
        .def_readonly("progress", &peer_info::progress)
        ;

    // flags
    pi.attr("interesting") = (int)peer_info::interesting;
    pi.attr("choked") = (int)peer_info::choked;
    pi.attr("remote_interested") = (int)peer_info::remote_interested;
    pi.attr("remote_choked") = (int)peer_info::remote_choked;
    pi.attr("supports_extensions") = (int)peer_info::supports_extensions;
    pi.attr("local_connection") = (int)peer_info::local_connection;
    pi.attr("handshake") = (int)peer_info::handshake;
    pi.attr("connecting") = (int)peer_info::connecting;
    pi.attr("queued") = (int)peer_info::queued;
    pi.attr("on_parole") = (int)peer_info::on_parole;
    pi.attr("seed") = (int)peer_info::seed;
#ifndef TORRENT_DISABLE_ENCRYPTION
    pi.attr("rc4_encrypted") = (int)peer_info::rc4_encrypted;
    pi.attr("plaintext_encrypted") = (int)peer_info::plaintext_encrypted;
#endif

    // connection_type
    pi.attr("standard_bittorrent") = (int)peer_info::standard_bittorrent;
    pi.attr("web_seed") = (int)peer_info::web_seed;

    // source
    pi.attr("tracker") = (int)peer_info::tracker;
    pi.attr("dht") = (int)peer_info::dht;
    pi.attr("pex") = (int)peer_info::pex;
    pi.attr("lsd") = (int)peer_info::lsd;
    pi.attr("resume_data") = (int)peer_info::resume_data;

    // read/write state
    pi.attr("bw_idle") = (int)peer_info::bw_idle;
    pi.attr("bw_torrent") = (int)peer_info::bw_torrent;
    pi.attr("bw_global") = (int)peer_info::bw_global;
    pi.attr("bw_network") = (int)peer_info::bw_network;
}

<commit_msg>Remove un-necessary cast<commit_after>// Copyright Daniel Wallin 2007. Use, modification and distribution is
// subject to 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)

#include <libtorrent/peer_info.hpp>
#include <libtorrent/bitfield.hpp>
#include <boost/python.hpp>
#include <boost/python/iterator.hpp>

using namespace boost::python;
using namespace libtorrent;

int get_last_active(peer_info const& pi)
{
    return total_seconds(pi.last_active);
}

int get_last_request(peer_info const& pi)
{
    return total_seconds(pi.last_request);
}

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
str get_country(peer_info const& pi)
{
    return str(pi.country, 2);
}
#endif

tuple get_ip(peer_info const& pi)
{
    return make_tuple(pi.ip.address().to_string(), pi.ip.port());
}

list get_pieces(peer_info const& pi)
{
    list ret;

    for (bitfield::const_iterator i = pi.pieces.begin()
        , end(pi.pieces.end()); i != end; ++i)
    {
        ret.append(*i);
    }
    return ret;
}

void bind_peer_info()
{
    scope pi = class_<peer_info>("peer_info")
        .def_readonly("flags", &peer_info::flags)
        .def_readonly("source", &peer_info::source)
        .def_readonly("read_state", &peer_info::read_state)
        .def_readonly("write_state", &peer_info::write_state)
        .add_property("ip", get_ip)
        .def_readonly("up_speed", &peer_info::up_speed)
        .def_readonly("down_speed", &peer_info::down_speed)
        .def_readonly("payload_up_speed", &peer_info::payload_up_speed)
        .def_readonly("payload_down_speed", &peer_info::payload_down_speed)
        .def_readonly("total_download", &peer_info::total_download)
        .def_readonly("total_upload", &peer_info::total_upload)
        .def_readonly("pid", &peer_info::pid)
        .add_property("pieces", get_pieces)
        .def_readonly("upload_limit", &peer_info::upload_limit)
        .def_readonly("download_limit", &peer_info::download_limit)
        .add_property("last_request", get_last_request)
        .add_property("last_active", get_last_active)
        .def_readonly("send_buffer_size", &peer_info::send_buffer_size)
        .def_readonly("used_send_buffer", &peer_info::used_send_buffer)
        .def_readonly("num_hashfails", &peer_info::num_hashfails)
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .add_property("country", get_country)
#endif
#ifndef TORRENT_DISABLE_GEO_IP
        .def_readonly("inet_as_name", &peer_info::inet_as_name)
        .def_readonly("inet_as", &peer_info::inet_as)
#endif
        .def_readonly("load_balancing", &peer_info::load_balancing)
        .def_readonly("download_queue_length", &peer_info::download_queue_length)
        .def_readonly("upload_queue_length", &peer_info::upload_queue_length)
        .def_readonly("failcount", &peer_info::failcount)
        .def_readonly("downloading_piece_index", &peer_info::downloading_piece_index)
        .def_readonly("downloading_block_index", &peer_info::downloading_block_index)
        .def_readonly("downloading_progress", &peer_info::downloading_progress)
        .def_readonly("downloading_total", &peer_info::downloading_total)
        .def_readonly("client", &peer_info::client)
        .def_readonly("connection_type", &peer_info::connection_type)
        .def_readonly("remote_dl_rate", &peer_info::remote_dl_rate)
        .def_readonly("pending_disk_bytes", &peer_info::pending_disk_bytes)
        .def_readonly("send_quota", &peer_info::send_quota)
        .def_readonly("receive_quota", &peer_info::receive_quota)
        .def_readonly("rtt", &peer_info::rtt)
        .def_readonly("progress", &peer_info::progress)
        ;

    // flags
    pi.attr("interesting") = (int)peer_info::interesting;
    pi.attr("choked") = (int)peer_info::choked;
    pi.attr("remote_interested") = (int)peer_info::remote_interested;
    pi.attr("remote_choked") = (int)peer_info::remote_choked;
    pi.attr("supports_extensions") = (int)peer_info::supports_extensions;
    pi.attr("local_connection") = (int)peer_info::local_connection;
    pi.attr("handshake") = (int)peer_info::handshake;
    pi.attr("connecting") = (int)peer_info::connecting;
    pi.attr("queued") = (int)peer_info::queued;
    pi.attr("on_parole") = (int)peer_info::on_parole;
    pi.attr("seed") = (int)peer_info::seed;
#ifndef TORRENT_DISABLE_ENCRYPTION
    pi.attr("rc4_encrypted") = (int)peer_info::rc4_encrypted;
    pi.attr("plaintext_encrypted") = (int)peer_info::plaintext_encrypted;
#endif

    // connection_type
    pi.attr("standard_bittorrent") = (int)peer_info::standard_bittorrent;
    pi.attr("web_seed") = (int)peer_info::web_seed;

    // source
    pi.attr("tracker") = (int)peer_info::tracker;
    pi.attr("dht") = (int)peer_info::dht;
    pi.attr("pex") = (int)peer_info::pex;
    pi.attr("lsd") = (int)peer_info::lsd;
    pi.attr("resume_data") = (int)peer_info::resume_data;

    // read/write state
    pi.attr("bw_idle") = (int)peer_info::bw_idle;
    pi.attr("bw_torrent") = (int)peer_info::bw_torrent;
    pi.attr("bw_global") = (int)peer_info::bw_global;
    pi.attr("bw_network") = (int)peer_info::bw_network;
}

<|endoftext|>


<commit_before>#include <string>
#include <sstream>
#include <utility>
#include <cstdlib>
#include <memory>
#include <cstdio>
#include <cstring>
#include <iostream>

#include "token.hh"
#include "test_util.hh"
#include "describe.hh"

#define PRINT_BUFSIZE 100

using namespace std;

static bool result;

template<typename T>
void check_copy_move(const Token& tok){
  // constructor
  {
    Token tok_c_con(tok);
    if(tok.type() != tok_c_con.type() || tok.get<T>() != tok_c_con.get<T>()){
      cerr << "[failed] on copy construct: ";
      goto error;
    }else{
      Token tok_m_con{move(tok_c_con)};
      if(tok.type() != tok_m_con.type() || tok.get<T>() != tok_m_con.get<T>()){
        cerr << "[failed] on move construct ";
        goto error;
      }
    }
  }

  // operator=
  {
    Token tok_c_op = tok;
    if(tok.type() != tok_c_op.type() || tok.get<T>() != tok_c_op.get<T>()){
      cerr << "[failed] on copy operator= ";
      goto error;
    }else{
      Token tok_m_op = move(tok_c_op);
      if(tok.type() != tok_m_op.type() || tok.get<T>() != tok_m_op.get<T>()){
        cerr << "[failed] on move operator= ";
        goto error;
      }
    }
  }

  return;

 error:
  result = false;
  describe(zs::err, tok);
  cerr << '\n';
  return;
}

template<typename T, typename Pos>
void fail_message(Token::Type t, istream& f, const Pos& b_pos,
                  const Token& tok, const T& expect){
  // extract input from stream

  f.seekg(b_pos);

  string buf;
  std::getline(f, buf);

  cerr << "[failed] input='" << buf << "', expect type='" << stringify(t);
  cerr << ", expected str='" << expect << "'";
  cerr << "\n\tgotten token: ";
  describe(zs::err, tok);
  cerr << '\n';

  result = false;
}

// for error case
template<>
inline
Token::Type Token::get<Token::Type>() const{
  return type_;
}

void check(istream& f){
  static const auto type = Token::Type::uninitialized;
  auto init_pos = f.tellg();

  Token tok;
  with_expect_error([&]() -> void{
      tok = tokenize(f);
    });

  if(tok.type() != type){
    fail_message(type, f, init_pos, tok, "uninitialized");
    return;
  }

  check_copy_move<Token::Type>(tok);
}

void check(const string& input){
  stringstream ss(input);
  check(ss);
}

// for normal cases
template<Token::Type type,
         typename ex_type = typename to_type<Token::Type, type>::type>
void check_generic(istream& f, const ex_type& expect){
  auto init_pos = f.tellg();

  const Token tok = tokenize(f);

  if(tok.type() != type || tok.get<ex_type>() != expect){
    fail_message(type, f, init_pos, tok, expect);
    return;
  }

  check_copy_move<ex_type>(tok);
}

template<Token::Type T>
void check(istream& f, const string& expect){
  check_generic<T>(f, expect);
}

template<Token::Type T>
void check(const string& input, const string& expect){
  stringstream ss(input);
  check<T>(ss, expect);
}

#define check_ident check<Token::Type::identifier>
#define check_string check<Token::Type::string>

inline
bool operator==(const Number& n1, const Number& n2){
  return eqv(n1, n2);
}

inline
bool operator!=(const Number& n1, const Number& n2){
  return !eqv(n1, n2);
}

// to be fixed!!!
ostream& operator<<(ostream& o, const Number& n){
  describe(zs::err, n);
  return o;
}

void check(istream& f, const Number& n){
  check_generic<Token::Type::number>(f, n);
}

void check(istream& f, bool expect){
  check_generic<Token::Type::boolean>(f, expect);
}

void check(istream& f, char expect){
  check_generic<Token::Type::character>(f, expect);
}

// to be fixed!!!
ostream& operator<<(ostream& o, Token::Notation n){
  describe(zs::err, n);
  fputc('\'', zs::err);
  return o;
}

void check(istream& f, Token::Notation n){
  check_generic<Token::Type::notation>(f, n);
}

template<typename T>
void check(const string& input, T&& expect){
  stringstream ss(input);
  check(ss, expect);
}

#define N Token::Notation

int main(){
  result = true;
  open_null_stream();

  // identifier
  check_ident("lambda", "lambda");
  check_ident("q", "q");
  check_ident("list->vector", "list->vector");
  check_ident("soup", "soup");
  check_ident("+", "+");
  check_ident("V17a", "V17a");
  check_ident("<=?", "<=?");
  check_ident("a34kTMNs", "a34kTMNs");
  check_ident("the-word-resursin-has-many-meanings", "the-word-resursin-has-many-meanings");

  check_ident("+",  "+");
  check_ident("-",  "-");
  check_ident("...",  "...");

  check(".."); // error
  check("...."); // error

  // spaces & comments
  check_ident("   abc", "abc");
  check_ident("   abc    def ", "abc");
  check_ident(" ;hogehoge\n   abc", "abc");
  check(" ;hogehoge\n", static_cast<char>(EOF));
  check_ident("   abc;fhei", "abc");

  // boolean
  check("#t", true);
  check("#f", false);

  // number
  check("+1", Number{1l});
  check("#x16", Number{0x16l});

  // character
  check("#\\");
  check("#\\a", 'a');
  check("#\\b", 'b');
  check("#\\x", 'x');
  check("#\\s", 's');
  check("#\\space", ' ');
  check("#\\newline", '\n');

  // string
  check("\"");
  check_string("\"\"", "");
  check_string("\"a\"", "a");
  check_string("\"abcd\nedf jfkdj\"", "abcd\nedf jfkdj");
  check_string("\"\\\"\\\"\"", "\"\"");

  // error
  check("#z");

  // consecutive access
  {
    char teststr[] = "(a . b)#(c 'd) e ...;comment\nf +11 `(,x ,@y \"ho()ge\")";
    stringstream ss(teststr);

    check(ss, N::l_paren);
    check_ident(ss, "a");
    check(ss, N::dot);
    check_ident(ss, "b");
    check(ss, N::r_paren);
    check(ss, N::vector_paren);
    check_ident(ss, "c");
    check(ss, N::quote);
    check_ident(ss, "d");
    check(ss, N::r_paren);
    check_ident(ss, "e");
    check_ident(ss, "...");

    check_ident(ss, "f");
    check(ss, Number{11l});
    check(ss, N::quasiquote);
    check(ss, N::l_paren);
    check(ss, N::comma);
    check_ident(ss, "x");
    check(ss, N::comma_at);
    check_ident(ss, "y");
    check_string(ss, "ho()ge");
    check(ss, N::r_paren);

    check(ss, static_cast<char>(EOF));
  }

  return (result) ? EXIT_SUCCESS : EXIT_FAILURE;
}
<commit_msg>replaces FILE -> C++ stream in token-test (2)<commit_after>#include <string>
#include <sstream>
#include <utility>
#include <cstdlib>
#include <memory>
#include <cstdio>
#include <cstring>
#include <iostream>

#include "token.hh"
#include "test_util.hh"
#include "describe.hh"

#define PRINT_BUFSIZE 100

using namespace std;

static bool result;

template<typename T>
void check_copy_move(const Token& tok){
  // constructor
  {
    Token tok_c_con(tok);
    if(tok.type() != tok_c_con.type() || tok.get<T>() != tok_c_con.get<T>()){
      cerr << "[failed] on copy construct: ";
      goto error;
    }else{
      Token tok_m_con{move(tok_c_con)};
      if(tok.type() != tok_m_con.type() || tok.get<T>() != tok_m_con.get<T>()){
        cerr << "[failed] on move construct ";
        goto error;
      }
    }
  }

  // operator=
  {
    Token tok_c_op = tok;
    if(tok.type() != tok_c_op.type() || tok.get<T>() != tok_c_op.get<T>()){
      cerr << "[failed] on copy operator= ";
      goto error;
    }else{
      Token tok_m_op = move(tok_c_op);
      if(tok.type() != tok_m_op.type() || tok.get<T>() != tok_m_op.get<T>()){
        cerr << "[failed] on move operator= ";
        goto error;
      }
    }
  }

  return;

 error:
  result = false;
  describe(zs::err, tok);
  cerr << '\n';
  return;
}

template<typename T, typename Pos>
void fail_message(Token::Type t, istream& f, const Pos& b_pos,
                  const Token& tok, const T& expect){
  // extract input from stream

  f.seekg(b_pos);

  string buf;
  std::getline(f, buf);

  cerr << "[failed] input='" << buf << "', expect type='" << stringify(t);
  cerr << ", expected str='" << expect << "'";
  cerr << "\n\tgotten token: ";
  describe(zs::err, tok);
  cerr << '\n';

  result = false;
}

// for error case
template<>
inline
Token::Type Token::get<Token::Type>() const{
  return type_;
}

void check(istream& f){
  static const auto type = Token::Type::uninitialized;
  auto init_pos = f.tellg();

  Token tok;
  with_expect_error([&]() -> void{
      tok = tokenize(f);
    });

  if(tok.type() != type){
    fail_message(type, f, init_pos, tok, "uninitialized");
    return;
  }

  check_copy_move<Token::Type>(tok);
}

void check(const string& input){
  stringstream ss(input);
  check(ss);
}

// for normal cases
template<typename T>
void check_generic(istream& f, const T& expect,
                   Token::Type type = to_tag<Token::Type, T>()){
  auto init_pos = f.tellg();

  const Token tok = tokenize(f);

  if(tok.type() != type || tok.get<T>() != expect){
    fail_message(type, f, init_pos, tok, expect);
    return;
  }

  check_copy_move<T>(tok);
}

template<Token::Type T>
void check(istream& f, const string& expect){
  check_generic(f, expect, T);
}

template<Token::Type T>
void check(const string& input, const string& expect){
  stringstream ss(input);
  check<T>(ss, expect);
}

#define check_ident check<Token::Type::identifier>
#define check_string check<Token::Type::string>

inline
bool operator==(const Number& n1, const Number& n2){
  return eqv(n1, n2);
}

inline
bool operator!=(const Number& n1, const Number& n2){
  return !eqv(n1, n2);
}

// to be fixed!!!
ostream& operator<<(ostream& o, const Number& n){
  describe(zs::err, n);
  return o;
}

// to be fixed!!!
ostream& operator<<(ostream& o, Token::Notation n){
  describe(zs::err, n);
  fputc('\'', zs::err);
  return o;
}

template<typename T>
void check(istream& f, const T& n){
  check_generic(f, n);
}

template<typename T>
void check(const string& input, T&& expect){
  stringstream ss(input);
  check(ss, expect);
}

#define N Token::Notation

int main(){
  result = true;
  open_null_stream();

  // identifier
  check_ident("lambda", "lambda");
  check_ident("q", "q");
  check_ident("list->vector", "list->vector");
  check_ident("soup", "soup");
  check_ident("+", "+");
  check_ident("V17a", "V17a");
  check_ident("<=?", "<=?");
  check_ident("a34kTMNs", "a34kTMNs");
  check_ident("the-word-resursin-has-many-meanings", "the-word-resursin-has-many-meanings");

  check_ident("+",  "+");
  check_ident("-",  "-");
  check_ident("...",  "...");

  check(".."); // error
  check("...."); // error

  // spaces & comments
  check_ident("   abc", "abc");
  check_ident("   abc    def ", "abc");
  check_ident(" ;hogehoge\n   abc", "abc");
  check(" ;hogehoge\n", static_cast<char>(EOF));
  check_ident("   abc;fhei", "abc");

  // boolean
  check("#t", true);
  check("#f", false);

  // number
  check("+1", Number{1l});
  check("#x16", Number{0x16l});

  // character
  check("#\\");
  check("#\\a", 'a');
  check("#\\b", 'b');
  check("#\\x", 'x');
  check("#\\s", 's');
  check("#\\space", ' ');
  check("#\\newline", '\n');

  // string
  check("\"");
  check_string("\"\"", "");
  check_string("\"a\"", "a");
  check_string("\"abcd\nedf jfkdj\"", "abcd\nedf jfkdj");
  check_string("\"\\\"\\\"\"", "\"\"");

  // error
  check("#z");

  // consecutive access
  {
    char teststr[] = "(a . b)#(c 'd) e ...;comment\nf +11 `(,x ,@y \"ho()ge\")";
    stringstream ss(teststr);

    check(ss, N::l_paren);
    check_ident(ss, "a");
    check(ss, N::dot);
    check_ident(ss, "b");
    check(ss, N::r_paren);
    check(ss, N::vector_paren);
    check_ident(ss, "c");
    check(ss, N::quote);
    check_ident(ss, "d");
    check(ss, N::r_paren);
    check_ident(ss, "e");
    check_ident(ss, "...");

    check_ident(ss, "f");
    check(ss, Number{11l});
    check(ss, N::quasiquote);
    check(ss, N::l_paren);
    check(ss, N::comma);
    check_ident(ss, "x");
    check(ss, N::comma_at);
    check_ident(ss, "y");
    check_string(ss, "ho()ge");
    check(ss, N::r_paren);

    check(ss, static_cast<char>(EOF));
  }

  return (result) ? EXIT_SUCCESS : EXIT_FAILURE;
}
<|endoftext|>