<commit_before>/* <x0/request.hpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#ifndef x0_http_request_hpp
#define x0_http_request_hpp (1)

#include <x0/buffer.hpp>
#include <x0/header.hpp>
#include <x0/fileinfo.hpp>
#include <x0/types.hpp>
#include <x0/api.hpp>
#include <string>
#include <vector>
#include <boost/tuple/tuple.hpp>
#include <boost/logic/tribool.hpp>

namespace x0 {

//! \addtogroup core
//@{

/**
 * \brief a client HTTP reuqest object, holding the parsed x0 request data.
 *
 * \see header, response, connection, server
 */
struct request
{
public:
	class reader;

public:
	explicit request(x0::connection& connection);

	/// the TCP/IP connection this request has been sent through
	x0::connection& connection;

public: // request properties
	/// HTTP request method, e.g. HEAD, GET, POST, PUT, etc.
	buffer_ref method;

	/// parsed request uri
	buffer_ref uri;

	/// decoded path-part
	buffer_ref path;

	/// the final entity to be served, for example the full path to the file on disk.
	fileinfo_ptr fileinfo;

	/// decoded query-part
	buffer_ref query;

	/// HTTP protocol version major part that this request was formed in
	int http_version_major;
	/// HTTP protocol version minor part that this request was formed in
	int http_version_minor;

	/// request headers
	std::vector<x0::request_header> headers;

	/** retrieve value of a given request header */
	buffer_ref header(const std::string& name) const;

	/// body
	std::string body;

public: // accumulated request data
	/// username this client has authenticated with.
	buffer_ref username;

	/// the document root directory for this request.
	std::string document_root;

//	std::string if_modified_since;		//!< "If-Modified-Since" request header value, if specified.
//	std::shared_ptr<range_def> range;	//!< parsed "Range" request header

public: // utility methods
	bool supports_protocol(int major, int minor) const;
	std::string hostid() const;
};

/**
 * \brief implements the HTTP request parser.
 *
 * \see request, connection
 */
class request::reader
{
public:
	enum state
	{
		method_start,
		method,
		uri_start,
		uri,
		http_version_h,
		http_version_t_1,
		http_version_t_2,
		http_version_p,
		http_version_slash,
		http_version_major_start,
		http_version_major,
		http_version_minor_start,
		http_version_minor,
		expecting_newline_1,
		header_line_start,
		header_lws,
		header_name,
		space_before_header_value,
		header_value,
		expecting_newline_2,
		expecting_newline_3,
		reading_body
	};

private:
	state state_;
	std::size_t left_;

private:
	static inline bool is_char(int ch);
	static inline bool is_ctl(int ch);
	static inline bool is_tspecial(int ch);
	static inline bool is_digit(int ch);

	static inline bool url_decode(buffer_ref& url);

public:
	reader();

	void reset();

	/** parses partial HTTP request.
	 *
	 * \param r request to fill with parsed data
	 * \param data buffer holding the (possibly partial) data of the request to be parsed.
	 *
	 * \retval true request has been fully parsed.
	 * \retval false HTTP request parser error (should result into bad_request if possible.)
	 * \retval indeterminate parsial request parsed successfully but more input is needed to complete parsing.
	 */
	inline boost::tribool parse(request& req, const buffer_ref& data);
};

// {{{ request impl
inline request::request(x0::connection& conn) :
	connection(conn)
{
}

inline bool request::supports_protocol(int major, int minor) const
{
	if (major == http_version_major && minor <= http_version_minor)
		return true;

	if (major < http_version_major)
		return true;

	return false;
}
// }}}

// {{{ request::reader impl
inline bool request::reader::is_char(int ch)
{
	return ch >= 0 && ch < 127;
}

inline bool request::reader::is_ctl(int ch)
{
	return (ch >= 0 && ch <= 31) || ch == 127;
}

inline bool request::reader::is_tspecial(int ch)
{
	switch (ch)
	{
		case '(':
		case ')':
		case '<':
		case '>':
		case '@':
		case ',':
		case ';':
		case ':':
		case '\\':
		case '"':
		case '/':
		case '[':
		case ']':
		case '?':
		case '=':
		case '{':
		case '}':
		case ' ':
		case '\t':
			return true;
		default:
			return false;
	}
}

inline bool request::reader::is_digit(int ch)
{
	return ch >= '0' && ch <= '9';
}

inline bool request::reader::url_decode(buffer_ref& url)
{
	std::size_t left = url.offset();
	std::size_t right = left + url.size();
	std::size_t i = left; // read pos
	std::size_t d = left; // write pos
	buffer& value = url.buffer();

	while (i != right)
	{
		if (value[i] == '%')
		{
			if (i + 3 <= right)
			{
				int ival;
				std::istringstream is(value.substr(i + 1, 2)); //! \todo optimize
				if (is >> std::hex >> ival)
				{
					value[d++] = static_cast<char>(ival);
					i += 3;
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}
		else if (value[i] == '+')
		{
			value[d++] = ' ';
			++i;
		}
		else if (d != i)
		{
			value[d++] = value[i++];
		}
		else
		{
			++d;
			++i;
		}
	}

	url = value.ref(left, d - left);
	return true;
}

inline request::reader::reader() :
	state_(method_start), left_(0)
{
}

inline void request::reader::reset()
{
	state_ = method_start;
	left_ = 0;
}

inline boost::tribool request::reader::parse(request& r, const buffer_ref& data)
{
	std::size_t cur = data.offset();
	std::size_t count = cur + data.size();
	buffer_ref::const_iterator i = data.begin();

	for (; cur != count; ++cur)
	{
		char input = *i++;

		switch (state_)
		{
			case method_start:
				if (!is_char(input) || is_ctl(input) || is_tspecial(input))
					return false;

				state_ = method;
				break;
			case method:
				if (input == ' ')
				{
					r.method = data.buffer().ref(left_, cur - left_);
					state_ = uri;
					left_ = cur + 1;
				}
				else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
					return false;

				break;
			case uri_start:
				if (is_ctl(input))
					return false;

				state_ = uri;
				break;
			case uri:
				if (input == ' ')
				{
					r.uri = data.buffer().ref(left_, cur - left_);
					left_ = cur + 1;

					if (!url_decode(r.uri))
						return false;

					std::size_t n = r.uri.find("?");
					if (n != std::string::npos)
					{
						r.path = r.uri.ref(0, n);
						r.query = r.uri.ref(n + 1);
					}
					else
					{
						r.path = r.uri;
					}

					if (r.path.empty() || r.path[0] != '/' || r.path.find("..") != std::string::npos)
						return false;

					state_ = http_version_h;
				}
				else if (is_ctl(input))
					return false;

				break;
			case http_version_h:
				if (input != 'H')
					return false;

				state_ = http_version_t_1;
				break;
			case http_version_t_1:
				if (input != 'T')
					return false;

				state_ = http_version_t_2;
				break;
			case http_version_t_2:
				if (input != 'T')
					return false;

				state_ = http_version_p;
				break;
			case http_version_p:
				if (input != 'P')
					return false;

				state_ = http_version_slash;
				break;
			case http_version_slash:
				if (input != '/')
					return false;

				r.http_version_major = 0;
				r.http_version_minor = 0;

				state_ = http_version_major_start;
				break;
			case http_version_major_start:
				if (!is_digit(input))
					return false;

				r.http_version_major = r.http_version_major * 10 + input - '0';
				state_ = http_version_major;
				break;
			case http_version_major:
				if (input == '.')
					state_ = http_version_minor_start;
				else if (is_digit(input))
					r.http_version_major = r.http_version_major * 10 + input - '0';
				else
					return false;

				break;
			case http_version_minor_start:
				if (input == '\r')
					state_ = expecting_newline_1;
				else if (is_digit(input))
					r.http_version_minor = r.http_version_minor * 10 + input - '0';
				else
					return false;

				break;
			case expecting_newline_1:
				if (input != '\n')
					return false;

				state_ = header_line_start;
				break;
			case header_line_start:
				if (input == '\r')
					state_ = expecting_newline_3;
				else if (!r.headers.empty() && (input == ' ' || input == '\t'))
					state_ = header_lws;
				else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
					return false;
				else
				{
					r.headers.push_back(x0::request_header());
					//r.headers.back().name.push_back(input);
					r.headers.back().name = data.buffer().ref(cur, 1);

					state_ = header_name;
				}
				break;
			case header_lws:
				if (input == '\r')
					state_ = expecting_newline_2;
				else if (input != ' ' && input != '\t')
				{
					state_ = header_value;
					r.headers.back().value = data.buffer().ref(cur, 1);
				}
				break;
			case header_name:
				if (input == ':')
					state_ = space_before_header_value;
				else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
					return false;
				else
					r.headers.back().name.shr(1);

				break;
			case space_before_header_value:
				if (input != ' ')
					return false;

				state_ = header_value;
				break;
			case header_value:
				if (input == '\r')
					state_ = expecting_newline_2;
				else if (is_ctl(input))
					return false;
				else if (r.headers.back().value.empty())
					r.headers.back().value = data.buffer().ref(cur, 1);
				else
					r.headers.back().value.shr(1);

				break;
			case expecting_newline_2:
				if (input != '\n')
					return false;

				state_ = header_line_start;
				break;
			case expecting_newline_3:
				if (input == '\n')
				{
					buffer_ref s(r.header("Content-Length"));
					if (!s.empty())
					{
						state_ = reading_body;
						r.body.reserve(std::atoi(s.data()));
						break;
					}
					else
					{
						return true;
					}
				}
				else
				{
					return false;
				}
			case reading_body:
				r.body.push_back(input);

				if (r.body.length() < r.body.capacity())
				{
					break;
				}
				else
				{
					return true;
				}
			default:
				return false;
		}
	}

	// request header parsed partially
	return boost::indeterminate;
}
// }}}

//@}

} // namespace x0

#endif
<commit_msg>core: make use of hex2int instead of iostream to convert in url decoding<commit_after>/* <x0/request.hpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#ifndef x0_http_request_hpp
#define x0_http_request_hpp (1)

#include <x0/buffer.hpp>
#include <x0/header.hpp>
#include <x0/fileinfo.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>
#include <x0/api.hpp>
#include <string>
#include <vector>
#include <boost/tuple/tuple.hpp>
#include <boost/logic/tribool.hpp>

namespace x0 {

//! \addtogroup core
//@{

/**
 * \brief a client HTTP reuqest object, holding the parsed x0 request data.
 *
 * \see header, response, connection, server
 */
struct request
{
public:
	class reader;

public:
	explicit request(x0::connection& connection);

	/// the TCP/IP connection this request has been sent through
	x0::connection& connection;

public: // request properties
	/// HTTP request method, e.g. HEAD, GET, POST, PUT, etc.
	buffer_ref method;

	/// parsed request uri
	buffer_ref uri;

	/// decoded path-part
	buffer_ref path;

	/// the final entity to be served, for example the full path to the file on disk.
	fileinfo_ptr fileinfo;

	/// decoded query-part
	buffer_ref query;

	/// HTTP protocol version major part that this request was formed in
	int http_version_major;
	/// HTTP protocol version minor part that this request was formed in
	int http_version_minor;

	/// request headers
	std::vector<x0::request_header> headers;

	/** retrieve value of a given request header */
	buffer_ref header(const std::string& name) const;

	/// body
	std::string body;

public: // accumulated request data
	/// username this client has authenticated with.
	buffer_ref username;

	/// the document root directory for this request.
	std::string document_root;

//	std::string if_modified_since;		//!< "If-Modified-Since" request header value, if specified.
//	std::shared_ptr<range_def> range;	//!< parsed "Range" request header

public: // utility methods
	bool supports_protocol(int major, int minor) const;
	std::string hostid() const;
};

/**
 * \brief implements the HTTP request parser.
 *
 * \see request, connection
 */
class request::reader
{
public:
	enum state
	{
		method_start,
		method,
		uri_start,
		uri,
		http_version_h,
		http_version_t_1,
		http_version_t_2,
		http_version_p,
		http_version_slash,
		http_version_major_start,
		http_version_major,
		http_version_minor_start,
		http_version_minor,
		expecting_newline_1,
		header_line_start,
		header_lws,
		header_name,
		space_before_header_value,
		header_value,
		expecting_newline_2,
		expecting_newline_3,
		reading_body
	};

private:
	state state_;
	std::size_t left_;

private:
	static inline bool is_char(int ch);
	static inline bool is_ctl(int ch);
	static inline bool is_tspecial(int ch);
	static inline bool is_digit(int ch);

	static inline bool url_decode(buffer_ref& url);

public:
	reader();

	void reset();

	/** parses partial HTTP request.
	 *
	 * \param r request to fill with parsed data
	 * \param data buffer holding the (possibly partial) data of the request to be parsed.
	 *
	 * \retval true request has been fully parsed.
	 * \retval false HTTP request parser error (should result into bad_request if possible.)
	 * \retval indeterminate parsial request parsed successfully but more input is needed to complete parsing.
	 */
	inline boost::tribool parse(request& req, const buffer_ref& data);
};

// {{{ request impl
inline request::request(x0::connection& conn) :
	connection(conn)
{
}

inline bool request::supports_protocol(int major, int minor) const
{
	if (major == http_version_major && minor <= http_version_minor)
		return true;

	if (major < http_version_major)
		return true;

	return false;
}
// }}}

// {{{ request::reader impl
inline bool request::reader::is_char(int ch)
{
	return ch >= 0 && ch < 127;
}

inline bool request::reader::is_ctl(int ch)
{
	return (ch >= 0 && ch <= 31) || ch == 127;
}

inline bool request::reader::is_tspecial(int ch)
{
	switch (ch)
	{
		case '(':
		case ')':
		case '<':
		case '>':
		case '@':
		case ',':
		case ';':
		case ':':
		case '\\':
		case '"':
		case '/':
		case '[':
		case ']':
		case '?':
		case '=':
		case '{':
		case '}':
		case ' ':
		case '\t':
			return true;
		default:
			return false;
	}
}

inline bool request::reader::is_digit(int ch)
{
	return ch >= '0' && ch <= '9';
}

inline bool request::reader::url_decode(buffer_ref& url)
{
	std::size_t left = url.offset();
	std::size_t right = left + url.size();
	std::size_t i = left; // read pos
	std::size_t d = left; // write pos
	buffer& value = url.buffer();

	while (i != right)
	{
		if (value[i] == '%')
		{
			if (i + 3 <= right)
			{
				int ival;
+				if (hex2int(value.begin() + i + 1, value.begin() + i + 3, ival))
				{
					value[d++] = static_cast<char>(ival);
					i += 3;
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}
		else if (value[i] == '+')
		{
			value[d++] = ' ';
			++i;
		}
		else if (d != i)
		{
			value[d++] = value[i++];
		}
		else
		{
			++d;
			++i;
		}
	}

	url = value.ref(left, d - left);
	return true;
}

inline request::reader::reader() :
	state_(method_start), left_(0)
{
}

inline void request::reader::reset()
{
	state_ = method_start;
	left_ = 0;
}

inline boost::tribool request::reader::parse(request& r, const buffer_ref& data)
{
	std::size_t cur = data.offset();
	std::size_t count = cur + data.size();
	buffer_ref::const_iterator i = data.begin();

	for (; cur != count; ++cur)
	{
		char input = *i++;

		switch (state_)
		{
			case method_start:
				if (!is_char(input) || is_ctl(input) || is_tspecial(input))
					return false;

				state_ = method;
				break;
			case method:
				if (input == ' ')
				{
					r.method = data.buffer().ref(left_, cur - left_);
					state_ = uri;
					left_ = cur + 1;
				}
				else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
					return false;

				break;
			case uri_start:
				if (is_ctl(input))
					return false;

				state_ = uri;
				break;
			case uri:
				if (input == ' ')
				{
					r.uri = data.buffer().ref(left_, cur - left_);
					left_ = cur + 1;

					if (!url_decode(r.uri))
						return false;

					std::size_t n = r.uri.find("?");
					if (n != std::string::npos)
					{
						r.path = r.uri.ref(0, n);
						r.query = r.uri.ref(n + 1);
					}
					else
					{
						r.path = r.uri;
					}

					if (r.path.empty() || r.path[0] != '/' || r.path.find("..") != std::string::npos)
						return false;

					state_ = http_version_h;
				}
				else if (is_ctl(input))
					return false;

				break;
			case http_version_h:
				if (input != 'H')
					return false;

				state_ = http_version_t_1;
				break;
			case http_version_t_1:
				if (input != 'T')
					return false;

				state_ = http_version_t_2;
				break;
			case http_version_t_2:
				if (input != 'T')
					return false;

				state_ = http_version_p;
				break;
			case http_version_p:
				if (input != 'P')
					return false;

				state_ = http_version_slash;
				break;
			case http_version_slash:
				if (input != '/')
					return false;

				r.http_version_major = 0;
				r.http_version_minor = 0;

				state_ = http_version_major_start;
				break;
			case http_version_major_start:
				if (!is_digit(input))
					return false;

				r.http_version_major = r.http_version_major * 10 + input - '0';
				state_ = http_version_major;
				break;
			case http_version_major:
				if (input == '.')
					state_ = http_version_minor_start;
				else if (is_digit(input))
					r.http_version_major = r.http_version_major * 10 + input - '0';
				else
					return false;

				break;
			case http_version_minor_start:
				if (input == '\r')
					state_ = expecting_newline_1;
				else if (is_digit(input))
					r.http_version_minor = r.http_version_minor * 10 + input - '0';
				else
					return false;

				break;
			case expecting_newline_1:
				if (input != '\n')
					return false;

				state_ = header_line_start;
				break;
			case header_line_start:
				if (input == '\r')
					state_ = expecting_newline_3;
				else if (!r.headers.empty() && (input == ' ' || input == '\t'))
					state_ = header_lws;
				else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
					return false;
				else
				{
					r.headers.push_back(x0::request_header());
					//r.headers.back().name.push_back(input);
					r.headers.back().name = data.buffer().ref(cur, 1);

					state_ = header_name;
				}
				break;
			case header_lws:
				if (input == '\r')
					state_ = expecting_newline_2;
				else if (input != ' ' && input != '\t')
				{
					state_ = header_value;
					r.headers.back().value = data.buffer().ref(cur, 1);
				}
				break;
			case header_name:
				if (input == ':')
					state_ = space_before_header_value;
				else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
					return false;
				else
					r.headers.back().name.shr(1);

				break;
			case space_before_header_value:
				if (input != ' ')
					return false;

				state_ = header_value;
				break;
			case header_value:
				if (input == '\r')
					state_ = expecting_newline_2;
				else if (is_ctl(input))
					return false;
				else if (r.headers.back().value.empty())
					r.headers.back().value = data.buffer().ref(cur, 1);
				else
					r.headers.back().value.shr(1);

				break;
			case expecting_newline_2:
				if (input != '\n')
					return false;

				state_ = header_line_start;
				break;
			case expecting_newline_3:
				if (input == '\n')
				{
					buffer_ref s(r.header("Content-Length"));
					if (!s.empty())
					{
						state_ = reading_body;
						r.body.reserve(std::atoi(s.data()));
						break;
					}
					else
					{
						return true;
					}
				}
				else
				{
					return false;
				}
			case reading_body:
				r.body.push_back(input);

				if (r.body.length() < r.body.capacity())
				{
					break;
				}
				else
				{
					return true;
				}
			default:
				return false;
		}
	}

	// request header parsed partially
	return boost::indeterminate;
}
// }}}

//@}

} // namespace x0

#endif
<|endoftext|>


<commit_before>/*
  Copyright 2011-2020 David Robillard <http://drobilla.net>
  Copyright 2015 Rui Nuno Capela <rncbc@rncbc.org>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "suil_internal.h"

#include "lv2/core/lv2.h"
#include "lv2/ui/ui.h"
#include "suil/suil.h"

#include <QResizeEvent>
#include <QSize>
#include <QTimerEvent>
#include <QWidget>
#include <QX11Info>
#include <Qt>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include <cstdint>
#include <cstdlib>

#undef signals

extern "C" {

class SuilQX11Widget : public QWidget
{
public:
	SuilQX11Widget(QWidget* parent, Qt::WindowFlags wflags)
		: QWidget(parent, wflags)
		, _instance(NULL)
		, _idle_iface(NULL)
		, _window(0)
		, _ui_timer(0)
	{}

	SuilQX11Widget(const SuilQX11Widget&) = delete;
	SuilQX11Widget& operator=(const SuilQX11Widget&) = delete;

	~SuilQX11Widget() override;

	void start_idle(SuilInstance*               instance,
	                const LV2UI_Idle_Interface* idle_iface)
	{
		_instance   = instance;
		_idle_iface = idle_iface;
		if (_idle_iface && _ui_timer == 0) {
			_ui_timer = this->startTimer(30, Qt::CoarseTimer);
		}
	}

	void set_window(Window window)
	{
		_window = window;
	}

	QSize sizeHint() const override
	{
		if (_window) {
			XWindowAttributes attrs{};
			XGetWindowAttributes(QX11Info::display(), _window, &attrs);
			return {attrs.width, attrs.height};
		}

		return {0, 0};
	}

	QSize minimumSizeHint() const override
	{
		if (_window) {
			XSizeHints hints{};
			long       supplied{};
			XGetWMNormalHints(QX11Info::display(), _window, &hints, &supplied);
			if ((hints.flags & PMinSize)) {
				return {hints.min_width, hints.min_height};
			}
		}

		return {0, 0};
	}

protected:
	void resizeEvent(QResizeEvent* event) override
	{
		QWidget::resizeEvent(event);

		if (_window) {
			XResizeWindow(QX11Info::display(),
			              _window,
			              (unsigned)event->size().width(),
			              (unsigned)event->size().height());
		}
	}

	void timerEvent(QTimerEvent* event) override
	{
		if (event->timerId() == _ui_timer && _idle_iface) {
			_idle_iface->idle(_instance->handle);
		}
		QWidget::timerEvent(event);
	}

    void closeEvent(QCloseEvent* event) override
	{
		if (_ui_timer && _idle_iface) {
			this->killTimer(_ui_timer);
			_ui_timer = 0;
		}
		QWidget::closeEvent(event);
	}

private:
	SuilInstance*               _instance;
	const LV2UI_Idle_Interface* _idle_iface;
	Window                      _window;
	int                         _ui_timer;
};

SuilQX11Widget::~SuilQX11Widget()
{
}

typedef struct {
	QWidget*        host_widget;
	SuilQX11Widget* parent;
} SuilX11InQt5Wrapper;

static void
wrapper_free(SuilWrapper* wrapper)
{
	SuilX11InQt5Wrapper* impl = (SuilX11InQt5Wrapper*)wrapper->impl;

	delete impl->host_widget;

	free(impl);
}

static int
wrapper_wrap(SuilWrapper*  wrapper,
             SuilInstance* instance)
{
	SuilX11InQt5Wrapper* const impl    = (SuilX11InQt5Wrapper*)wrapper->impl;
	SuilQX11Widget* const      ew      = impl->parent;
	Display* const             display = QX11Info::display();
	const Window               window  = (Window)instance->ui_widget;

	XWindowAttributes attrs{};
	XSizeHints        hints{};
	long              supplied{};
	XSync(display, False);
	XGetWindowAttributes(display, window, &attrs);
	XGetWMNormalHints(display, window, &hints, &supplied);

	impl->parent->set_window(window);

	if ((hints.flags & PBaseSize)) {
		impl->parent->setBaseSize(hints.base_width, hints.base_height);
	}

	if ((hints.flags & PMinSize)) {
		impl->parent->setMinimumSize(hints.min_width, hints.min_height);
	}

	if ((hints.flags & PMaxSize)) {
		impl->parent->setMaximumSize(hints.max_width, hints.max_height);
	}

	if (instance->descriptor->extension_data) {
		const LV2UI_Idle_Interface* idle_iface
			= (const LV2UI_Idle_Interface*)
				instance->descriptor->extension_data(LV2_UI__idleInterface);
		ew->start_idle(instance, idle_iface);
	}

	impl->host_widget = ew;

	instance->host_widget = impl->host_widget;

	return 0;
}

static int
wrapper_resize(LV2UI_Feature_Handle handle, int width, int height)
{
	QWidget* const ew = (QWidget*)handle;
	ew->resize(width, height);
	return 0;
}

SUIL_LIB_EXPORT
SuilWrapper*
suil_wrapper_new(SuilHost*,
                 const char*,
                 const char*,
                 LV2_Feature*** features,
                 unsigned       n_features)
{
	SuilX11InQt5Wrapper* const impl = (SuilX11InQt5Wrapper*)
		calloc(1, sizeof(SuilX11InQt5Wrapper));

	SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper));
	wrapper->wrap = wrapper_wrap;
	wrapper->free = wrapper_free;

	SuilQX11Widget* const ew = new SuilQX11Widget(NULL, Qt::Window);

	impl->parent = ew;

	wrapper->impl             = impl;
	wrapper->resize.handle    = ew;
	wrapper->resize.ui_resize = wrapper_resize;

	void* parent_id = (void*)(intptr_t)ew->winId();
	suil_add_feature(features, &n_features, LV2_UI__parent, parent_id);
	suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize);
	suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL);

	return wrapper;
}

}  // extern "C"
<commit_msg>Clean up special member functions<commit_after>/*
  Copyright 2011-2020 David Robillard <http://drobilla.net>
  Copyright 2015 Rui Nuno Capela <rncbc@rncbc.org>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "suil_internal.h"

#include "lv2/core/lv2.h"
#include "lv2/ui/ui.h"
#include "suil/suil.h"

#include <QResizeEvent>
#include <QSize>
#include <QTimerEvent>
#include <QWidget>
#include <QX11Info>
#include <Qt>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include <cstdint>
#include <cstdlib>

#undef signals

extern "C" {

class SuilQX11Widget : public QWidget
{
public:
	SuilQX11Widget(QWidget* parent, Qt::WindowFlags wflags)
		: QWidget(parent, wflags)
		, _instance(NULL)
		, _idle_iface(NULL)
		, _window(0)
		, _ui_timer(0)
	{}

	SuilQX11Widget(const SuilQX11Widget&) = delete;
	SuilQX11Widget& operator=(const SuilQX11Widget&) = delete;

	SuilQX11Widget(SuilQX11Widget&&) = delete;
	SuilQX11Widget& operator=(SuilQX11Widget&&) = delete;

	~SuilQX11Widget() override;

	void start_idle(SuilInstance*               instance,
	                const LV2UI_Idle_Interface* idle_iface)
	{
		_instance   = instance;
		_idle_iface = idle_iface;
		if (_idle_iface && _ui_timer == 0) {
			_ui_timer = this->startTimer(30, Qt::CoarseTimer);
		}
	}

	void set_window(Window window)
	{
		_window = window;
	}

	QSize sizeHint() const override
	{
		if (_window) {
			XWindowAttributes attrs{};
			XGetWindowAttributes(QX11Info::display(), _window, &attrs);
			return {attrs.width, attrs.height};
		}

		return {0, 0};
	}

	QSize minimumSizeHint() const override
	{
		if (_window) {
			XSizeHints hints{};
			long       supplied{};
			XGetWMNormalHints(QX11Info::display(), _window, &hints, &supplied);
			if ((hints.flags & PMinSize)) {
				return {hints.min_width, hints.min_height};
			}
		}

		return {0, 0};
	}

protected:
	void resizeEvent(QResizeEvent* event) override
	{
		QWidget::resizeEvent(event);

		if (_window) {
			XResizeWindow(QX11Info::display(),
			              _window,
			              (unsigned)event->size().width(),
			              (unsigned)event->size().height());
		}
	}

	void timerEvent(QTimerEvent* event) override
	{
		if (event->timerId() == _ui_timer && _idle_iface) {
			_idle_iface->idle(_instance->handle);
		}
		QWidget::timerEvent(event);
	}

    void closeEvent(QCloseEvent* event) override
	{
		if (_ui_timer && _idle_iface) {
			this->killTimer(_ui_timer);
			_ui_timer = 0;
		}
		QWidget::closeEvent(event);
	}

private:
	SuilInstance*               _instance;
	const LV2UI_Idle_Interface* _idle_iface;
	Window                      _window;
	int                         _ui_timer;
};

SuilQX11Widget::~SuilQX11Widget()
{
}

typedef struct {
	QWidget*        host_widget;
	SuilQX11Widget* parent;
} SuilX11InQt5Wrapper;

static void
wrapper_free(SuilWrapper* wrapper)
{
	SuilX11InQt5Wrapper* impl = (SuilX11InQt5Wrapper*)wrapper->impl;

	delete impl->host_widget;

	free(impl);
}

static int
wrapper_wrap(SuilWrapper*  wrapper,
             SuilInstance* instance)
{
	SuilX11InQt5Wrapper* const impl    = (SuilX11InQt5Wrapper*)wrapper->impl;
	SuilQX11Widget* const      ew      = impl->parent;
	Display* const             display = QX11Info::display();
	const Window               window  = (Window)instance->ui_widget;

	XWindowAttributes attrs{};
	XSizeHints        hints{};
	long              supplied{};
	XSync(display, False);
	XGetWindowAttributes(display, window, &attrs);
	XGetWMNormalHints(display, window, &hints, &supplied);

	impl->parent->set_window(window);

	if ((hints.flags & PBaseSize)) {
		impl->parent->setBaseSize(hints.base_width, hints.base_height);
	}

	if ((hints.flags & PMinSize)) {
		impl->parent->setMinimumSize(hints.min_width, hints.min_height);
	}

	if ((hints.flags & PMaxSize)) {
		impl->parent->setMaximumSize(hints.max_width, hints.max_height);
	}

	if (instance->descriptor->extension_data) {
		const LV2UI_Idle_Interface* idle_iface
			= (const LV2UI_Idle_Interface*)
				instance->descriptor->extension_data(LV2_UI__idleInterface);
		ew->start_idle(instance, idle_iface);
	}

	impl->host_widget = ew;

	instance->host_widget = impl->host_widget;

	return 0;
}

static int
wrapper_resize(LV2UI_Feature_Handle handle, int width, int height)
{
	QWidget* const ew = (QWidget*)handle;
	ew->resize(width, height);
	return 0;
}

SUIL_LIB_EXPORT
SuilWrapper*
suil_wrapper_new(SuilHost*,
                 const char*,
                 const char*,
                 LV2_Feature*** features,
                 unsigned       n_features)
{
	SuilX11InQt5Wrapper* const impl = (SuilX11InQt5Wrapper*)
		calloc(1, sizeof(SuilX11InQt5Wrapper));

	SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper));
	wrapper->wrap = wrapper_wrap;
	wrapper->free = wrapper_free;

	SuilQX11Widget* const ew = new SuilQX11Widget(NULL, Qt::Window);

	impl->parent = ew;

	wrapper->impl             = impl;
	wrapper->resize.handle    = ew;
	wrapper->resize.ui_resize = wrapper_resize;

	void* parent_id = (void*)(intptr_t)ew->winId();
	suil_add_feature(features, &n_features, LV2_UI__parent, parent_id);
	suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize);
	suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL);

	return wrapper;
}

}  // extern "C"
<|endoftext|>


<commit_before>/**
 * Template C++ file.
 * Function with references to pointers: func(int *&ptr);
 */
/********************* Header Files ***********************/
/* C++ Headers */
#include <iostream> /* Input/output objects. */
//#include <fstream> /* File operations. */
//#include <sstream> /* String stream. */
#include <string> /* C++ String class. */
//#include <new> /* Defines bad_malloc exception, new functions. */
//#include <typeinfo> /* Casting header. */
//#include <exception> /* Top level exception header. */
//#include <stdexcept> /* Derived exception classes. */

/* STL Headers */
#include <vector>
//#include <list>
//#include <deque>
//#include <stack>
//#include <queue>
//#include <priority_queue>
//#include <bitset>
//#include <set> // multiset for multiple keys allowed.
//#include <map> // multimap for multiple keys allowed.
//#include <utility> // Has pair for map.
//#include <algorithm>
//#include <numeric>
//#include <functional> // Functional objects.
//#include <iterator> // Contains back_inserter function and like.

/* C Headers */
//#include <cstdlib>
//#include <cstddef>
//#include <cctype>
//#include <cstring>
//#include <cstdio>
//#include <climits>
//#include <cassert>

/* Project Headers */
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <gtest/gtest.h>

/******************* Constants/Macros *********************/

/**************** Namespace Declarations ******************/
using std::cin;
using std::cout;
using std::endl;
using std::string;
namespace fs = boost::filesystem;

/******************* Type Definitions *********************/
/* For enums: Try to namesapce the common elements.
 * typedef enum {
 *	VAL_,
 * } name_e;
 */

/* For structs:
 * typedef struct name_s {
 *	int index;
 * } name_t;
 */

/****************** Class Definitions *********************/

/****************** Global Functions **********************/
TEST(BoostFilesystem, TestFilesize) {
    string fil("./test/gtest_example_primer.cpp");
    ASSERT_EQ(3666, boost::filesystem::file_size(fil));

    ASSERT_THROW(boost::filesystem::file_size("."),
	boost::filesystem::filesystem_error);
}

TEST(BoostFilesystem, TestQueries) {
    string fil("./test/gtest_example_primer.cpp");
    string tdir("./test");
    fs::path pf(fil);
    fs::path pd(tdir);

    ASSERT_TRUE(fs::exists(pf));
    ASSERT_TRUE(fs::is_regular_file(pf));
    ASSERT_TRUE(fs::exists(pd));
    ASSERT_FALSE(fs::is_regular_file(pd));
    ASSERT_TRUE(fs::is_directory(pd));
}

TEST(BoostFilesystem, TestDirectoryIterator) {
    typedef std::vector<string> vecS;

    fs::path pd("./src");
    vecS vActual;
    vecS vExpect {"./src/CMakeLists.txt", "./src/class1.cpp", "./src/main.cpp"};

    for (fs::directory_iterator itr(pd); itr != fs::directory_iterator(); ++itr) {
	string path = itr->path().c_str();
	vActual.push_back(path);
    }

    std::sort(vActual.begin(), vActual.end());
    std::sort(vExpect.begin(), vExpect.end());

    for (vecS::const_iterator itA =  vActual.begin(), itE = vExpect.begin();
	    itA != vActual.end(); ++itA, ++itE) {
	ASSERT_STREQ(itE->c_str(), itA->c_str());
    }
}

TEST(BoostFilesystem, TestPathDecomposition) {
    typedef std::vector<string> vecS;

    fs::path pd("./src");
    vecS vActual;
    vecS vExpect {"CMakeLists.txt", "class1.cpp", "main.cpp"};

    for (fs::directory_iterator itr(pd); itr != fs::directory_iterator(); ++itr) {
	string fName = itr->path().filename().c_str();
	vActual.push_back(fName);
    }

    std::sort(vActual.begin(), vActual.end());
    std::sort(vExpect.begin(), vExpect.end());

    for (vecS::const_iterator itA =  vActual.begin(), itE = vExpect.begin();
	    itA != vActual.end(); ++itA, ++itE) {
	ASSERT_STREQ(itE->c_str(), itA->c_str());
    }
}

/* Notes:
 * Force call to use another version of virtual function: baseP->Item_base::net_price(42);
 *
 */
<commit_msg>Compose example.<commit_after>/**
 * Template C++ file.
 * Function with references to pointers: func(int *&ptr);
 */
/********************* Header Files ***********************/
/* C++ Headers */
#include <iostream> /* Input/output objects. */
//#include <fstream> /* File operations. */
//#include <sstream> /* String stream. */
#include <string> /* C++ String class. */
//#include <new> /* Defines bad_malloc exception, new functions. */
//#include <typeinfo> /* Casting header. */
//#include <exception> /* Top level exception header. */
//#include <stdexcept> /* Derived exception classes. */

/* STL Headers */
#include <vector>
//#include <list>
//#include <deque>
//#include <stack>
//#include <queue>
//#include <priority_queue>
//#include <bitset>
//#include <set> // multiset for multiple keys allowed.
//#include <map> // multimap for multiple keys allowed.
//#include <utility> // Has pair for map.
//#include <algorithm>
//#include <numeric>
//#include <functional> // Functional objects.
//#include <iterator> // Contains back_inserter function and like.

/* C Headers */
//#include <cstdlib>
//#include <cstddef>
//#include <cctype>
//#include <cstring>
//#include <cstdio>
//#include <climits>
//#include <cassert>

/* Project Headers */
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <gtest/gtest.h>

/******************* Constants/Macros *********************/

/**************** Namespace Declarations ******************/
using std::cin;
using std::cout;
using std::endl;
using std::string;
namespace fs = boost::filesystem;

/******************* Type Definitions *********************/
/* For enums: Try to namesapce the common elements.
 * typedef enum {
 *	VAL_,
 * } name_e;
 */

/* For structs:
 * typedef struct name_s {
 *	int index;
 * } name_t;
 */

/****************** Class Definitions *********************/

/****************** Global Functions **********************/
TEST(BoostFilesystem, TestFilesize) {
    string fil("./test/gtest_example_primer.cpp");
    ASSERT_EQ(3666, boost::filesystem::file_size(fil));

    ASSERT_THROW(boost::filesystem::file_size("."),
	boost::filesystem::filesystem_error);
}

TEST(BoostFilesystem, TestQueries) {
    string fil("./test/gtest_example_primer.cpp");
    string tdir("./test");
    fs::path pf(fil);
    fs::path pd(tdir);

    ASSERT_TRUE(fs::exists(pf));
    ASSERT_TRUE(fs::is_regular_file(pf));
    ASSERT_TRUE(fs::exists(pd));
    ASSERT_FALSE(fs::is_regular_file(pd));
    ASSERT_TRUE(fs::is_directory(pd));
}
TEST(BoostFilesystem, TestDirectoryIterator) {
    typedef std::vector<string> vecS;
    fs::path pd("./src");
    vecS vActual;
    vecS vExpect {"./src/CMakeLists.txt", "./src/class1.cpp", "./src/main.cpp"};

    for (fs::directory_iterator itr(pd); itr != fs::directory_iterator(); ++itr) {
	string path = itr->path().c_str();
	vActual.push_back(path);
    }

    std::sort(vActual.begin(), vActual.end());
    std::sort(vExpect.begin(), vExpect.end());

    for (vecS::const_iterator itA =  vActual.begin(), itE = vExpect.begin();
	    itA != vActual.end(); ++itA, ++itE) {
	ASSERT_STREQ(itE->c_str(), itA->c_str());
    }
}

TEST(BoostFilesystem, TestPathDecomposition) {
    typedef std::vector<string> vecS;
    fs::path pd("./src");
    vecS vActual;
    vecS vExpect {"CMakeLists.txt", "class1.cpp", "main.cpp"};

    for (fs::directory_iterator itr(pd); itr != fs::directory_iterator(); ++itr) {
	string fName = itr->path().filename().c_str();
	vActual.push_back(fName);
    }

    std::sort(vActual.begin(), vActual.end());
    std::sort(vExpect.begin(), vExpect.end());

    for (vecS::const_iterator itA =  vActual.begin(), itE = vExpect.begin();
	    itA != vActual.end(); ++itA, ++itE) {
	ASSERT_STREQ(itE->c_str(), itA->c_str());
    }
}

TEST(BoostFilesystem, TestComposePath) {
    std::string parts[] = {"/usr", "lib", "xorg", "modules", "libfb.so"};
    std::string expect = "/usr/lib/xorg/modules/libfb.so";
    fs::path p;

    for (int i = 0; i < 5; ++i) {
	p /= parts[i].c_str();
    }

    ASSERT_STREQ(expect.c_str(), p.c_str());
}

/* Notes:
 * Force call to use another version of virtual function: baseP->Item_base::net_price(42);
 *
 */
<|endoftext|>


<commit_before>#include "testsettings.hpp"
#ifdef TEST_UTIL_ERROR

#include <realm/util/basic_system_errors.hpp>

#include "test.hpp"

using namespace realm;
using namespace realm::util;

// Test independence and thread-safety
// -----------------------------------
//
// All tests must be thread safe and independent of each other. This
// is required because it allows for both shuffling of the execution
// order and for parallelized testing.
//
// In particular, avoid using std::rand() since it is not guaranteed
// to be thread safe. Instead use the API offered in
// `test/util/random.hpp`.
//
// All files created in tests must use the TEST_PATH macro (or one of
// its friends) to obtain a suitable file system path. See
// `test/util/test_path.hpp`.
//
//
// Debugging and the ONLY() macro
// ------------------------------
//
// A simple way of disabling all tests except one called `Foo`, is to
// replace TEST(Foo) with ONLY(Foo) and then recompile and rerun the
// test suite. Note that you can also use filtering by setting the
// environment varible `UNITTEST_FILTER`. See `README.md` for more on
// this.
//
// Another way to debug a particular test, is to copy that test into
// `experiments/testcase.cpp` and then run `sh build.sh
// check-testcase` (or one of its friends) from the command line.

TEST(BasicSystemErrors_Category)
{
    std::error_code err = make_error_code(error::operation_aborted);
    CHECK_EQUAL(err.category().name(), "realm.basic_system");
}

TEST(BasicSystemErrors_Messages)
{
    {
        std::error_code err = make_error_code(error::address_family_not_supported);
        CHECK_GREATER(err.message().length(), 0);
    }
    {
        std::error_code err = make_error_code(error::invalid_argument);
        CHECK_GREATER(err.message().length(), 0);
    }
    {
        std::error_code err = make_error_code(error::no_memory);
        CHECK_GREATER(err.message().length(), 0);
    }
    {
        std::error_code err = make_error_code(error::operation_aborted);
        CHECK_GREATER(err.message().length(), 0);
    }

    // Ensure that if we pass an unknown error code, we get some error reporting
    // This may potentially pass on some operating system. If this test starts failing, simply change the
    // magic number below.
    {
        std::error_code err = make_error_code(static_cast<error::basic_system_errors>(64532));
        CHECK_GREATER(err.message().length(), 0);
    }
}

#endif // TEST_BASIC_SYSTEM_ERRORS
<commit_msg>Fixed tests for Windows platforms<commit_after>#include "testsettings.hpp"
#ifdef TEST_UTIL_ERROR

#include <realm/util/basic_system_errors.hpp>

#include "test.hpp"

using namespace realm;
using namespace realm::util;

// Test independence and thread-safety
// -----------------------------------
//
// All tests must be thread safe and independent of each other. This
// is required because it allows for both shuffling of the execution
// order and for parallelized testing.
//
// In particular, avoid using std::rand() since it is not guaranteed
// to be thread safe. Instead use the API offered in
// `test/util/random.hpp`.
//
// All files created in tests must use the TEST_PATH macro (or one of
// its friends) to obtain a suitable file system path. See
// `test/util/test_path.hpp`.
//
//
// Debugging and the ONLY() macro
// ------------------------------
//
// A simple way of disabling all tests except one called `Foo`, is to
// replace TEST(Foo) with ONLY(Foo) and then recompile and rerun the
// test suite. Note that you can also use filtering by setting the
// environment varible `UNITTEST_FILTER`. See `README.md` for more on
// this.
//
// Another way to debug a particular test, is to copy that test into
// `experiments/testcase.cpp` and then run `sh build.sh
// check-testcase` (or one of its friends) from the command line.

TEST(BasicSystemErrors_Category)
{
    std::error_code err = make_error_code(error::operation_aborted);
    CHECK_EQUAL(err.category().name(), "realm.basic_system");
}

TEST(BasicSystemErrors_Messages)
{
    const std::string error_message("Unknown error");

    {
        std::error_code err = make_error_code(error::address_family_not_supported);
        CHECK_GREATER(err.message().length(), 0);
#ifdef _WIN32
        CHECK_EQUAL(err.message(), error_message);
#else
        CHECK_NOT_EQUAL(err.message(), error_message);
#endif
    }
    {
        std::error_code err = make_error_code(error::invalid_argument);
        CHECK_GREATER(err.message().length(), 0);
        CHECK_NOT_EQUAL(err.message(), error_message);
    }
    {
        std::error_code err = make_error_code(error::no_memory);
        CHECK_GREATER(err.message().length(), 0);
        CHECK_NOT_EQUAL(err.message(), error_message);
    }
    {
        std::error_code err = make_error_code(error::operation_aborted);
        CHECK_GREATER(err.message().length(), 0);
#ifdef _WIN32
        CHECK_EQUAL(err.message(), error_message);
#else
        CHECK_NOT_EQUAL(err.message(), error_message);
#endif
    }

    // Ensure that if we pass an unknown error code, we get some error reporting
    // This may potentially pass on some operating system. If this test starts
    // failing, simply change the magic number below.
    {
        std::error_code err = make_error_code(static_cast<error::basic_system_errors>(64532));
        CHECK_GREATER(err.message().length(), 0);
        // Check that `err.message()` begins with `error_message_prefix`
        // On Linux and Apple systems, the returned string is of format:
        // "Unknown error: <errcode>"
        CHECK(err.message().compare(0, error_message.length(), error_message) == 0);
    }
}

#endif // TEST_BASIC_SYSTEM_ERRORS
<|endoftext|>


<commit_before>// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s

// Also check that atomics instrumentation can be configured by either driver or
// legacy flags:

// RUN: %clangxx_tsan -O1 %s -o %t -fno-sanitize-thread-atomics && not %deflake %run %t 2>&1 \
// RUN:   | FileCheck --allow-empty --check-prefix=CHECK-NO-ATOMICS %s
// RUN: %clangxx_tsan -O1 %s -o %t -mllvm -tsan-instrument-atomics=0 && not %deflake %run %t 2>&1 \
// RUN:   | FileCheck --allow-empty --check-prefix=CHECK-NO-ATOMICS %s <%t.out

#include "test.h"

void *Thread(void *a) {
  __atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST);
  barrier_wait(&barrier);
  return 0;
}

int main() {
  barrier_init(&barrier, 2);
  int *a = new int(0);
  pthread_t t;
  pthread_create(&t, 0, Thread, a);
  barrier_wait(&barrier);
  delete a;
  pthread_join(t, 0);
}

// CHECK: WARNING: ThreadSanitizer: data race

// CHECK-NO-ATOMICS-NOT: WARNING: ThreadSanitizer: data race
<commit_msg>[tsan] Fix typo in test.<commit_after>// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s

// Also check that atomics instrumentation can be configured by either driver or
// legacy flags:

// RUN: %clangxx_tsan -O1 %s -o %t -fno-sanitize-thread-atomics && not %deflake %run %t 2>&1 \
// RUN:   | FileCheck --allow-empty --check-prefix=CHECK-NO-ATOMICS %s
// RUN: %clangxx_tsan -O1 %s -o %t -mllvm -tsan-instrument-atomics=0 && not %deflake %run %t 2>&1 \
// RUN:   | FileCheck --allow-empty --check-prefix=CHECK-NO-ATOMICS %s <%t

#include "test.h"

void *Thread(void *a) {
  __atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST);
  barrier_wait(&barrier);
  return 0;
}

int main() {
  barrier_init(&barrier, 2);
  int *a = new int(0);
  pthread_t t;
  pthread_create(&t, 0, Thread, a);
  barrier_wait(&barrier);
  delete a;
  pthread_join(t, 0);
}

// CHECK: WARNING: ThreadSanitizer: data race

// CHECK-NO-ATOMICS-NOT: WARNING: ThreadSanitizer: data race
<|endoftext|>


<commit_before>/***********************************************************************
 *    filename:   InputInjection.cpp
 *    created:    21/5/2013
 *    author:     Timotei Dolean
 *************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2013 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/

#include <boost/test/unit_test.hpp>

#include <vector>
#include <iostream>

#include "CEGUI/CEGUI.h"

using namespace CEGUI;

struct InputInjectionFixture
{
    InputInjectionFixture()
        : d_buttonHandledCount(0)
        , d_windowHandledCount(0)
    {
        System::getSingleton().notifyDisplaySizeChanged(Sizef(100, 100));
        Rectf constraint_area(0, 0, 100, 100);
        System::getSingleton().getDefaultGUIContext().getMouseCursor().setConstraintArea(&constraint_area);

        d_window = WindowManager::getSingleton().createWindow("DefaultWindow");
        d_window->setPosition(UVector2(cegui_reldim(0.0f), cegui_reldim(0.0f)));
        d_window->setSize(USize(cegui_reldim(1.0f), cegui_reldim(1.0f)));

        d_button = WindowManager::getSingleton().createWindow("CEGUI/PushButton");
        d_button->setPosition(UVector2(cegui_reldim(0.2f), cegui_reldim(0.2f)));
        d_button->setSize(USize(cegui_reldim(0.2f), cegui_reldim(0.2f)));

        d_editbox = static_cast<Editbox*>(WindowManager::getSingleton().createWindow("TaharezLook/Editbox"));
        d_editbox->setPosition(UVector2(cegui_reldim(0.9f), cegui_reldim(0.9f)));
        d_editbox->setSize(USize(cegui_reldim(0.1f), cegui_reldim(0.1f)));

        d_window->addChild(d_editbox);
        d_window->addChild(d_button);

        System::getSingleton().getDefaultGUIContext().setRootWindow(d_window);

        d_windowConnections.push_back(
            d_window->subscribeEvent(Window::EventMouseClick,
                Event::Subscriber(&InputInjectionFixture::handleWindowEvent, this))
            );
        d_buttonConnections.push_back(
            d_button->subscribeEvent(PushButton::EventClicked,
                Event::Subscriber(&InputInjectionFixture::handleButtonEvent, this))
            );
    }

    ~InputInjectionFixture()
    {
        disconnectConnections(d_windowConnections);
        disconnectConnections(d_buttonConnections);

        System::getSingleton().getDefaultGUIContext().setRootWindow(0);

        WindowManager::getSingleton().destroyWindow(d_window);
    }

    bool handleButtonEvent(const EventArgs& e)
    {
        ++d_buttonHandledCount;
        return true;
    }

    bool handleWindowEvent(const EventArgs& e)
    {
        ++d_windowHandledCount;
        return true;
    }

    void disconnectConnections(std::vector<Event::Connection>& connections)
    {
        for(std::vector<Event::Connection>::iterator itor = connections.begin();
            itor != connections.end(); ++itor)
        {
            (*itor)->disconnect();
        }
    }

    int d_buttonHandledCount;
    int d_windowHandledCount;

    Window* d_window;
    Window* d_button;
    Editbox* d_editbox;

    std::vector<Event::Connection> d_windowConnections;
    std::vector<Event::Connection> d_buttonConnections;
};

//----------------------------------------------------------------------------//
static inline GUIContext& getGUIContext()
{
    return System::getSingleton().getDefaultGUIContext();
}

static inline InputAggregator& getInputAggregator()
{
    static InputAggregator inputAggregator(&System::getSingleton().getDefaultGUIContext());
    return inputAggregator;
}

static void doClick(float position_x, float position_y)
{
    getInputAggregator().injectMousePosition(position_x, position_y);
    getGUIContext().injectMouseButtonDown(LeftButton);
    getGUIContext().injectMouseButtonUp(LeftButton);
}
//----------------------------------------------------------------------------//

BOOST_FIXTURE_TEST_SUITE(InputInjection, InputInjectionFixture)

BOOST_AUTO_TEST_CASE(OneClickOnWindow)
{
    // we check for both: a) being handled, b) have the expected final result
    BOOST_REQUIRE_EQUAL(getGUIContext().injectMouseButtonClick(LeftButton), true);

    BOOST_REQUIRE_EQUAL(d_windowHandledCount, 1);
    BOOST_REQUIRE_EQUAL(d_buttonHandledCount, 0);
}

BOOST_AUTO_TEST_CASE(MultipleClicksOnWindow)
{
    BOOST_REQUIRE_EQUAL(getGUIContext().injectMouseButtonClick(LeftButton), true);
    BOOST_REQUIRE_EQUAL(getGUIContext().injectMouseButtonClick(LeftButton), true);

    BOOST_REQUIRE_EQUAL(d_windowHandledCount, 2);
    BOOST_REQUIRE_EQUAL(d_buttonHandledCount, 0);
}

BOOST_AUTO_TEST_CASE(OneClickOnButton)
{
    doClick(30.0f, 30.0f);

    BOOST_REQUIRE_EQUAL(d_windowHandledCount, 0);
    BOOST_REQUIRE_EQUAL(d_buttonHandledCount, 1);
}

BOOST_AUTO_TEST_CASE(InsertSimpleText)
{
    // focus the editbox
    doClick(91.0f, 91.0f);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('o'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);

    BOOST_REQUIRE_EQUAL(d_editbox->getText(), "WoW");
}

BOOST_AUTO_TEST_CASE(DeleteTextWithBackspace)
{
    // focus the editbox
    doClick(91.0f, 91.0f);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('o'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('k'), true);
    BOOST_REQUIRE_EQUAL(getGUIContext().injectKeyDown(Key::Backspace), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);

    BOOST_REQUIRE_EQUAL(d_editbox->getText(), "WoW");
}

BOOST_AUTO_TEST_CASE(DeleteTextWithDelete)
{
    // focus the editbox
    doClick(91.0f, 91.0f);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('o'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('k'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);

    BOOST_REQUIRE_EQUAL(getGUIContext().injectKeyDown(Key::ArrowLeft), true);
    BOOST_REQUIRE_EQUAL(getGUIContext().injectKeyDown(Key::ArrowLeft), true);
    BOOST_REQUIRE_EQUAL(getGUIContext().injectKeyDown(Key::Delete), true);

    BOOST_REQUIRE_EQUAL(d_editbox->getText(), "WoW");
}

BOOST_AUTO_TEST_CASE(SelectAllTextCopyAndPaste)
{
    // focus the editbox
    doClick(91.0f, 91.0f);

    d_editbox->setText("WoW");

    // select all text
    BOOST_REQUIRE_EQUAL(getGUIContext().injectMouseButtonTripleClick(MouseButton::LeftButton), true);
    BOOST_REQUIRE_EQUAL(d_editbox->getSelectionLength(), 3);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectCopyRequest(), true);

    // deselect the text
    d_editbox->setSelection(0, 0);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectPasteRequest(), true);

    BOOST_REQUIRE_EQUAL(d_editbox->getText(), "WoWWoW");
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Fix an invalid enum member usage that MSVC thought it's good<commit_after>/***********************************************************************
 *    filename:   InputInjection.cpp
 *    created:    21/5/2013
 *    author:     Timotei Dolean
 *************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2013 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/

#include <boost/test/unit_test.hpp>

#include <vector>
#include <iostream>

#include "CEGUI/CEGUI.h"

using namespace CEGUI;

struct InputInjectionFixture
{
    InputInjectionFixture()
        : d_buttonHandledCount(0)
        , d_windowHandledCount(0)
    {
        System::getSingleton().notifyDisplaySizeChanged(Sizef(100, 100));
        Rectf constraint_area(0, 0, 100, 100);
        System::getSingleton().getDefaultGUIContext().getMouseCursor().setConstraintArea(&constraint_area);

        d_window = WindowManager::getSingleton().createWindow("DefaultWindow");
        d_window->setPosition(UVector2(cegui_reldim(0.0f), cegui_reldim(0.0f)));
        d_window->setSize(USize(cegui_reldim(1.0f), cegui_reldim(1.0f)));

        d_button = WindowManager::getSingleton().createWindow("CEGUI/PushButton");
        d_button->setPosition(UVector2(cegui_reldim(0.2f), cegui_reldim(0.2f)));
        d_button->setSize(USize(cegui_reldim(0.2f), cegui_reldim(0.2f)));

        d_editbox = static_cast<Editbox*>(WindowManager::getSingleton().createWindow("TaharezLook/Editbox"));
        d_editbox->setPosition(UVector2(cegui_reldim(0.9f), cegui_reldim(0.9f)));
        d_editbox->setSize(USize(cegui_reldim(0.1f), cegui_reldim(0.1f)));

        d_window->addChild(d_editbox);
        d_window->addChild(d_button);

        System::getSingleton().getDefaultGUIContext().setRootWindow(d_window);

        d_windowConnections.push_back(
            d_window->subscribeEvent(Window::EventMouseClick,
                Event::Subscriber(&InputInjectionFixture::handleWindowEvent, this))
            );
        d_buttonConnections.push_back(
            d_button->subscribeEvent(PushButton::EventClicked,
                Event::Subscriber(&InputInjectionFixture::handleButtonEvent, this))
            );
    }

    ~InputInjectionFixture()
    {
        disconnectConnections(d_windowConnections);
        disconnectConnections(d_buttonConnections);

        System::getSingleton().getDefaultGUIContext().setRootWindow(0);

        WindowManager::getSingleton().destroyWindow(d_window);
    }

    bool handleButtonEvent(const EventArgs& e)
    {
        ++d_buttonHandledCount;
        return true;
    }

    bool handleWindowEvent(const EventArgs& e)
    {
        ++d_windowHandledCount;
        return true;
    }

    void disconnectConnections(std::vector<Event::Connection>& connections)
    {
        for(std::vector<Event::Connection>::iterator itor = connections.begin();
            itor != connections.end(); ++itor)
        {
            (*itor)->disconnect();
        }
    }

    int d_buttonHandledCount;
    int d_windowHandledCount;

    Window* d_window;
    Window* d_button;
    Editbox* d_editbox;

    std::vector<Event::Connection> d_windowConnections;
    std::vector<Event::Connection> d_buttonConnections;
};

//----------------------------------------------------------------------------//
static inline GUIContext& getGUIContext()
{
    return System::getSingleton().getDefaultGUIContext();
}

static inline InputAggregator& getInputAggregator()
{
    static InputAggregator inputAggregator(&System::getSingleton().getDefaultGUIContext());
    return inputAggregator;
}

static void doClick(float position_x, float position_y)
{
    getInputAggregator().injectMousePosition(position_x, position_y);
    getGUIContext().injectMouseButtonDown(LeftButton);
    getGUIContext().injectMouseButtonUp(LeftButton);
}
//----------------------------------------------------------------------------//

BOOST_FIXTURE_TEST_SUITE(InputInjection, InputInjectionFixture)

BOOST_AUTO_TEST_CASE(OneClickOnWindow)
{
    // we check for both: a) being handled, b) have the expected final result
    BOOST_REQUIRE_EQUAL(getGUIContext().injectMouseButtonClick(LeftButton), true);

    BOOST_REQUIRE_EQUAL(d_windowHandledCount, 1);
    BOOST_REQUIRE_EQUAL(d_buttonHandledCount, 0);
}

BOOST_AUTO_TEST_CASE(MultipleClicksOnWindow)
{
    BOOST_REQUIRE_EQUAL(getGUIContext().injectMouseButtonClick(LeftButton), true);
    BOOST_REQUIRE_EQUAL(getGUIContext().injectMouseButtonClick(LeftButton), true);

    BOOST_REQUIRE_EQUAL(d_windowHandledCount, 2);
    BOOST_REQUIRE_EQUAL(d_buttonHandledCount, 0);
}

BOOST_AUTO_TEST_CASE(OneClickOnButton)
{
    doClick(30.0f, 30.0f);

    BOOST_REQUIRE_EQUAL(d_windowHandledCount, 0);
    BOOST_REQUIRE_EQUAL(d_buttonHandledCount, 1);
}

BOOST_AUTO_TEST_CASE(InsertSimpleText)
{
    // focus the editbox
    doClick(91.0f, 91.0f);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('o'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);

    BOOST_REQUIRE_EQUAL(d_editbox->getText(), "WoW");
}

BOOST_AUTO_TEST_CASE(DeleteTextWithBackspace)
{
    // focus the editbox
    doClick(91.0f, 91.0f);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('o'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('k'), true);
    BOOST_REQUIRE_EQUAL(getGUIContext().injectKeyDown(Key::Backspace), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);

    BOOST_REQUIRE_EQUAL(d_editbox->getText(), "WoW");
}

BOOST_AUTO_TEST_CASE(DeleteTextWithDelete)
{
    // focus the editbox
    doClick(91.0f, 91.0f);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('o'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('k'), true);
    BOOST_REQUIRE_EQUAL(getInputAggregator().injectChar('W'), true);

    BOOST_REQUIRE_EQUAL(getGUIContext().injectKeyDown(Key::ArrowLeft), true);
    BOOST_REQUIRE_EQUAL(getGUIContext().injectKeyDown(Key::ArrowLeft), true);
    BOOST_REQUIRE_EQUAL(getGUIContext().injectKeyDown(Key::Delete), true);

    BOOST_REQUIRE_EQUAL(d_editbox->getText(), "WoW");
}

BOOST_AUTO_TEST_CASE(SelectAllTextCopyAndPaste)
{
    // focus the editbox
    doClick(91.0f, 91.0f);

    d_editbox->setText("WoW");

    // select all text
    BOOST_REQUIRE_EQUAL(getGUIContext().injectMouseButtonTripleClick(LeftButton), true);
    BOOST_REQUIRE_EQUAL(d_editbox->getSelectionLength(), 3);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectCopyRequest(), true);

    // deselect the text
    d_editbox->setSelection(0, 0);

    BOOST_REQUIRE_EQUAL(getInputAggregator().injectPasteRequest(), true);

    BOOST_REQUIRE_EQUAL(d_editbox->getText(), "WoWWoW");
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>
#include "qv4isel_masm_p.h"
#include "qmljs_runtime.h"
#include "qmljs_objects.h"

#include <assembler/LinkBuffer.h>

#include <sys/mman.h>
#include <iostream>
#include <cassert>

#ifndef NO_UDIS86
#  include <udis86.h>
#endif

using namespace QQmlJS;
using namespace QQmlJS::MASM;
using namespace QQmlJS::VM;

namespace {
QTextStream qout(stdout, QIODevice::WriteOnly);
}

InstructionSelection::InstructionSelection(VM::ExecutionEngine *engine, IR::Module *module, uchar *buffer)
    : _engine(engine)
    , _module(module)
    , _function(0)
    , _block(0)
    , _buffer(buffer)
    , _code(buffer)
    , _codePtr(buffer)
{
}

InstructionSelection::~InstructionSelection()
{
}

void InstructionSelection::operator()(IR::Function *function)
{
    qSwap(_function, function);

    enterStandardStackFrame();

    int locals = (_function->tempCount - _function->locals.size() + _function->maxNumberOfArguments) * sizeof(Value);
    locals = (locals + 15) & ~15;
    sub32(TrustedImm32(locals), StackPointerRegister);

    push(ContextRegister);
    loadPtr(addressForArgument(0), ContextRegister);

    foreach (IR::BasicBlock *block, _function->basicBlocks) {
        _block = block;
    //    _addrs[block] = _codePtr;
        foreach (IR::Stmt *s, block->statements) {
            s->accept(this);
        }
    }

    pop(ContextRegister);

    add32(TrustedImm32(locals), StackPointerRegister);

    leaveStandardStackFrame();
    ret();

    JSC::JSGlobalData dummy;
    JSC::LinkBuffer linkBuffer(dummy, this, 0);
    foreach (CallToLink ctl, _callsToLink)
        linkBuffer.link(ctl.call, ctl.externalFunction);
    _function->codeRef = linkBuffer.finalizeCodeWithDisassembly("operator()(IR::Function*)");
    _function->code = (void (*)(VM::Context *, const uchar *)) _function->codeRef.code().executableAddress();

    qSwap(_function, function);
}

String *InstructionSelection::identifier(const QString &s)
{
    return _engine->identifier(s);
}

JSC::MacroAssembler::Address InstructionSelection::loadTempAddress(RegisterID reg, IR::Temp *t)
{
    int32_t offset = 0;
    if (t->index < 0) {
        const int arg = -t->index - 1;
        loadPtr(Address(ContextRegister, offsetof(Context, arguments)), reg);
        offset = arg * sizeof(Value);
    } else if (t->index < _function->locals.size()) {
        loadPtr(Address(ContextRegister, offsetof(Context, locals)), reg);
        offset = t->index * sizeof(Value);
    } else {
        const int arg = _function->maxNumberOfArguments + t->index - _function->locals.size();
        offset = sizeof(Value) * (-arg)
                 - sizeof(void*); // size of ebp
        reg = StackFrameRegister;
    }
    return Address(reg, offset);
}

void InstructionSelection::callActivationProperty(IR::Call *call, IR::Temp *result)
{
}

void InstructionSelection::callValue(IR::Call *call, IR::Temp *result)
{
}

void InstructionSelection::callProperty(IR::Call *call, IR::Temp *result)
{
}

void InstructionSelection::constructActivationProperty(IR::New *call, IR::Temp *result)
{
}

void InstructionSelection::constructProperty(IR::New *call, IR::Temp *result)
{
}

void InstructionSelection::constructValue(IR::New *call, IR::Temp *result)
{
}

void InstructionSelection::checkExceptions()
{
}

void InstructionSelection::visitExp(IR::Exp *s)
{
    Q_UNIMPLEMENTED();
    assert(!"TODO");
}

void InstructionSelection::visitEnter(IR::Enter *)
{
    Q_UNIMPLEMENTED();
    assert(!"TODO");
}

void InstructionSelection::visitLeave(IR::Leave *)
{
    Q_UNIMPLEMENTED();
    assert(!"TODO");
}

void InstructionSelection::visitMove(IR::Move *s)
{
    if (s->op == IR::OpInvalid) {
        if (IR::Temp *t = s->target->asTemp()) {
            if (IR::Const *c = s->source->asConst()) {
                Address dest = loadTempAddress(Gpr0, t);
                switch (c->type) {
                case IR::NumberType:
                    // ### Taking address of pointer inside IR.
                    loadDouble(&c->value, FPGpr0);
                    storeDouble(FPGpr0, dest);
                    break;
                }
            }
        }
    }
    Q_UNIMPLEMENTED();
    s->dump(qout, IR::Stmt::MIR);
    qout << endl;
    assert(!"TODO");
}

void InstructionSelection::visitJump(IR::Jump *s)
{
}

void InstructionSelection::visitCJump(IR::CJump *s)
{
    Q_UNIMPLEMENTED();
    assert(!"TODO");
}

void InstructionSelection::visitRet(IR::Ret *s)
{
    if (IR::Temp *t = s->expr->asTemp()) {
        Address addr = loadTempAddress(Gpr1, t);
        add32(TrustedImm32(addr.offset), addr.base, Gpr1);
        add32(TrustedImm32(offsetof(Context, result)), ContextRegister, Gpr0);
        callHelper(__qmljs_copy, Gpr1, Gpr0);
        return;
    }
    Q_UNIMPLEMENTED();
    Q_UNUSED(s);
}

<commit_msg>Fix ret argumet passing<commit_after>
#include "qv4isel_masm_p.h"
#include "qmljs_runtime.h"
#include "qmljs_objects.h"

#include <assembler/LinkBuffer.h>

#include <sys/mman.h>
#include <iostream>
#include <cassert>

#ifndef NO_UDIS86
#  include <udis86.h>
#endif

using namespace QQmlJS;
using namespace QQmlJS::MASM;
using namespace QQmlJS::VM;

namespace {
QTextStream qout(stdout, QIODevice::WriteOnly);
}

InstructionSelection::InstructionSelection(VM::ExecutionEngine *engine, IR::Module *module, uchar *buffer)
    : _engine(engine)
    , _module(module)
    , _function(0)
    , _block(0)
    , _buffer(buffer)
    , _code(buffer)
    , _codePtr(buffer)
{
}

InstructionSelection::~InstructionSelection()
{
}

void InstructionSelection::operator()(IR::Function *function)
{
    qSwap(_function, function);

    enterStandardStackFrame();

    int locals = (_function->tempCount - _function->locals.size() + _function->maxNumberOfArguments) * sizeof(Value);
    locals = (locals + 15) & ~15;
    sub32(TrustedImm32(locals), StackPointerRegister);

    push(ContextRegister);
    loadPtr(addressForArgument(0), ContextRegister);

    foreach (IR::BasicBlock *block, _function->basicBlocks) {
        _block = block;
    //    _addrs[block] = _codePtr;
        foreach (IR::Stmt *s, block->statements) {
            s->accept(this);
        }
    }

    pop(ContextRegister);

    add32(TrustedImm32(locals), StackPointerRegister);

    leaveStandardStackFrame();
    ret();

    JSC::JSGlobalData dummy;
    JSC::LinkBuffer linkBuffer(dummy, this, 0);
    foreach (CallToLink ctl, _callsToLink)
        linkBuffer.link(ctl.call, ctl.externalFunction);
    _function->codeRef = linkBuffer.finalizeCodeWithDisassembly("operator()(IR::Function*)");
    _function->code = (void (*)(VM::Context *, const uchar *)) _function->codeRef.code().executableAddress();

    qSwap(_function, function);
}

String *InstructionSelection::identifier(const QString &s)
{
    return _engine->identifier(s);
}

JSC::MacroAssembler::Address InstructionSelection::loadTempAddress(RegisterID reg, IR::Temp *t)
{
    int32_t offset = 0;
    if (t->index < 0) {
        const int arg = -t->index - 1;
        loadPtr(Address(ContextRegister, offsetof(Context, arguments)), reg);
        offset = arg * sizeof(Value);
    } else if (t->index < _function->locals.size()) {
        loadPtr(Address(ContextRegister, offsetof(Context, locals)), reg);
        offset = t->index * sizeof(Value);
    } else {
        const int arg = _function->maxNumberOfArguments + t->index - _function->locals.size();
        offset = sizeof(Value) * (-arg)
                 - sizeof(void*); // size of ebp
        reg = StackFrameRegister;
    }
    return Address(reg, offset);
}

void InstructionSelection::callActivationProperty(IR::Call *call, IR::Temp *result)
{
}

void InstructionSelection::callValue(IR::Call *call, IR::Temp *result)
{
}

void InstructionSelection::callProperty(IR::Call *call, IR::Temp *result)
{
}

void InstructionSelection::constructActivationProperty(IR::New *call, IR::Temp *result)
{
}

void InstructionSelection::constructProperty(IR::New *call, IR::Temp *result)
{
}

void InstructionSelection::constructValue(IR::New *call, IR::Temp *result)
{
}

void InstructionSelection::checkExceptions()
{
}

void InstructionSelection::visitExp(IR::Exp *s)
{
    Q_UNIMPLEMENTED();
    assert(!"TODO");
}

void InstructionSelection::visitEnter(IR::Enter *)
{
    Q_UNIMPLEMENTED();
    assert(!"TODO");
}

void InstructionSelection::visitLeave(IR::Leave *)
{
    Q_UNIMPLEMENTED();
    assert(!"TODO");
}

void InstructionSelection::visitMove(IR::Move *s)
{
    if (s->op == IR::OpInvalid) {
        if (IR::Temp *t = s->target->asTemp()) {
            if (IR::Const *c = s->source->asConst()) {
                Address dest = loadTempAddress(Gpr0, t);
                switch (c->type) {
                case IR::NumberType:
                    // ### Taking address of pointer inside IR.
                    loadDouble(&c->value, FPGpr0);
                    storeDouble(FPGpr0, dest);
                    break;
                }
            }
        }
    }
    Q_UNIMPLEMENTED();
    s->dump(qout, IR::Stmt::MIR);
    qout << endl;
    assert(!"TODO");
}

void InstructionSelection::visitJump(IR::Jump *s)
{
}

void InstructionSelection::visitCJump(IR::CJump *s)
{
    Q_UNIMPLEMENTED();
    assert(!"TODO");
}

void InstructionSelection::visitRet(IR::Ret *s)
{
    if (IR::Temp *t = s->expr->asTemp()) {
        Address addr = loadTempAddress(Gpr0, t);
        add32(TrustedImm32(addr.offset), addr.base, Gpr0);
        add32(TrustedImm32(offsetof(Context, result)), ContextRegister, Gpr1);
        callHelper(__qmljs_copy, Gpr1, Gpr0);
        return;
    }
    Q_UNIMPLEMENTED();
    Q_UNUSED(s);
}

<|endoftext|>


<commit_before>#ifndef __RANK_FILTER__
#define __RANK_FILTER__

#include <deque>
#include <set>
#include <cmath>
#include <cassert>
#include <iostream>
#include <iterator>
#include <type_traits>
#include <utility>

#include <vigra/multi_array.hxx>
#include <vigra/linear_algebra.hxx>

namespace vigra
{

template<unsigned int N,
        class T1, class S1,
        class T2, class S2,
        typename std::enable_if<(N == 1), int>::type = 0>
inline void lineRankOrderFilterND(const vigra::MultiArrayView <N, T1, S1> &src,
        vigra::MultiArrayView <N, T2, S2> dest,
        unsigned int half_length, float rank, unsigned int axis = 0)
{
    // Will ignore boundaries initially.
    // Then will try adding reflection.

    // Rank must be in the range 0 to 1
    assert((0 <= rank) && (rank <= 1));

    const int rank_pos = round(rank * (2 * half_length));

    // The position of the
    typename vigra::MultiArrayView<N, T1, S1>::difference_type_1 window_begin(0);
    std::multiset<T1> sorted_window;
    std::deque< typename std::multiset<T1>::iterator > window_iters;

    // Get the initial sorted window.
    // Include the reflection.
    for (typename vigra::MultiArrayView<N, T1, S1>::difference_type_1 j(half_length); j > 0; j--)
    {
        window_iters.push_back(sorted_window.insert(src[window_begin + j]));
    }
    for (typename vigra::MultiArrayView<N, T1, S1>::difference_type_1 j(0); j <= half_length; j++)
    {
        window_iters.push_back(sorted_window.insert(src[window_begin + j]));
    }

    typename std::multiset<T1>::iterator rank_point = sorted_window.begin();

    for (int i = 0; i < rank_pos; i++)
    {
        rank_point++;
    }

    typename std::multiset<T1>::iterator prev_iter;
    T1 prev_value;
    T1 next_value;
    while ( window_begin < src.size() )
    {
        dest[window_begin] = *rank_point;

        prev_iter = window_iters.front();
        prev_value = *prev_iter;
        window_iters.pop_front();

        window_begin++;

        if ( window_begin < (src.size() - half_length) )
        {
            next_value = src[window_begin + half_length];
        }
        else
        {
            next_value = src[2 * src.size() - (window_begin + half_length + 2)];
        }

        if ( ( *rank_point < prev_value ) && ( *rank_point <= next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point > next_value ) )
        {
            if ( rank_point == prev_iter )
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point--;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));
            }
        }
        else if ( ( *rank_point < prev_value ) && ( *rank_point > next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));

            rank_point--;
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point <= next_value ) )
        {
            if (rank_point == prev_iter)
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point++;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));

                rank_point++;
            }
        }
    }
}

template<unsigned int N,
        class T1, class S1,
        class T2, class S2,
        typename std::enable_if<(N > 1), int>::type = 0>
inline void lineRankOrderFilterND(const vigra::MultiArrayView <N, T1, S1> &src,
        vigra::MultiArrayView <N, T2, S2> dest,
        unsigned int half_length, float rank, unsigned int axis = 0)
{
    typename vigra::MultiArrayView<N, T1, S1>::difference_type transposed_axes;

    for (unsigned int i = 0; i < N; i++)
    {
        transposed_axes[i] = i;
    }

    std::swap(transposed_axes[0], transposed_axes[axis]);

    vigra::MultiArray<N, T1> src_transposed(src.transpose(transposed_axes));

    vigra::MultiArrayView<N, T1, S1> dest_transposed(dest.transpose(transposed_axes));

    typename vigra::MultiArrayView<N - 1, T1, S1>::difference_type pos;
    pos = 0;

    bool done = false;
    bool carry = true;
    while (!done)
    {
        lineRankOrderFilterND(src_transposed.bindOuter(pos), dest_transposed.bindOuter(pos), half_length, rank, 0);

        carry = true;
        for (unsigned int i = 0; ( carry && (i < (N - 1)) ); i++)
        {
            if ( (++pos[i]) < src_transposed.shape(i + 1) )
            {
                carry = false;
            }
            else
            {
                pos[i] = 0;
                carry = true;
            }
        }

        done = carry;
    }
}

template<unsigned int N,
        class T1, class S1,
        class T2, class S2>
inline void lineRankOrderFilter(const vigra::MultiArrayView <N, T1, S1> &src,
        vigra::MultiArrayView <N, T2, S2> dest,
        unsigned int half_length, float rank, unsigned int axis = 0)
{
    lineRankOrderFilterND(src, dest, half_length, rank, axis);
}

}

#endif //__RANK_FILTER__
<commit_msg>rank_filter.hxx: Fixed dest_transposed tags and strides.<commit_after>#ifndef __RANK_FILTER__
#define __RANK_FILTER__

#include <deque>
#include <set>
#include <cmath>
#include <cassert>
#include <iostream>
#include <iterator>
#include <type_traits>
#include <utility>

#include <vigra/multi_array.hxx>
#include <vigra/linear_algebra.hxx>

namespace vigra
{

template<unsigned int N,
        class T1, class S1,
        class T2, class S2,
        typename std::enable_if<(N == 1), int>::type = 0>
inline void lineRankOrderFilterND(const vigra::MultiArrayView <N, T1, S1> &src,
        vigra::MultiArrayView <N, T2, S2> dest,
        unsigned int half_length, float rank, unsigned int axis = 0)
{
    // Will ignore boundaries initially.
    // Then will try adding reflection.

    // Rank must be in the range 0 to 1
    assert((0 <= rank) && (rank <= 1));

    const int rank_pos = round(rank * (2 * half_length));

    // The position of the
    typename vigra::MultiArrayView<N, T1, S1>::difference_type_1 window_begin(0);
    std::multiset<T1> sorted_window;
    std::deque< typename std::multiset<T1>::iterator > window_iters;

    // Get the initial sorted window.
    // Include the reflection.
    for (typename vigra::MultiArrayView<N, T1, S1>::difference_type_1 j(half_length); j > 0; j--)
    {
        window_iters.push_back(sorted_window.insert(src[window_begin + j]));
    }
    for (typename vigra::MultiArrayView<N, T1, S1>::difference_type_1 j(0); j <= half_length; j++)
    {
        window_iters.push_back(sorted_window.insert(src[window_begin + j]));
    }

    typename std::multiset<T1>::iterator rank_point = sorted_window.begin();

    for (int i = 0; i < rank_pos; i++)
    {
        rank_point++;
    }

    typename std::multiset<T1>::iterator prev_iter;
    T1 prev_value;
    T1 next_value;
    while ( window_begin < src.size() )
    {
        dest[window_begin] = *rank_point;

        prev_iter = window_iters.front();
        prev_value = *prev_iter;
        window_iters.pop_front();

        window_begin++;

        if ( window_begin < (src.size() - half_length) )
        {
            next_value = src[window_begin + half_length];
        }
        else
        {
            next_value = src[2 * src.size() - (window_begin + half_length + 2)];
        }

        if ( ( *rank_point < prev_value ) && ( *rank_point <= next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point > next_value ) )
        {
            if ( rank_point == prev_iter )
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point--;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));
            }
        }
        else if ( ( *rank_point < prev_value ) && ( *rank_point > next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));

            rank_point--;
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point <= next_value ) )
        {
            if (rank_point == prev_iter)
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point++;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));

                rank_point++;
            }
        }
    }
}

template<unsigned int N,
        class T1, class S1,
        class T2, class S2,
        typename std::enable_if<(N > 1), int>::type = 0>
inline void lineRankOrderFilterND(const vigra::MultiArrayView <N, T1, S1> &src,
        vigra::MultiArrayView <N, T2, S2> dest,
        unsigned int half_length, float rank, unsigned int axis = 0)
{
    typename vigra::MultiArrayView<N, T1, S1>::difference_type transposed_axes;

    for (unsigned int i = 0; i < N; i++)
    {
        transposed_axes[i] = i;
    }

    std::swap(transposed_axes[0], transposed_axes[axis]);

    vigra::MultiArray<N, T1> src_transposed(src.transpose(transposed_axes));

    vigra::MultiArrayView<N, T2, S2> dest_transposed(dest.transpose(transposed_axes));

    typename vigra::MultiArrayView<N - 1, T1, S1>::difference_type pos;
    pos = 0;

    bool done = false;
    bool carry = true;
    while (!done)
    {
        lineRankOrderFilterND(src_transposed.bindOuter(pos), dest_transposed.bindOuter(pos), half_length, rank, 0);

        carry = true;
        for (unsigned int i = 0; ( carry && (i < (N - 1)) ); i++)
        {
            if ( (++pos[i]) < src_transposed.shape(i + 1) )
            {
                carry = false;
            }
            else
            {
                pos[i] = 0;
                carry = true;
            }
        }

        done = carry;
    }
}

template<unsigned int N,
        class T1, class S1,
        class T2, class S2>
inline void lineRankOrderFilter(const vigra::MultiArrayView <N, T1, S1> &src,
        vigra::MultiArrayView <N, T2, S2> dest,
        unsigned int half_length, float rank, unsigned int axis = 0)
{
    lineRankOrderFilterND(src, dest, half_length, rank, axis);
}

}

#endif //__RANK_FILTER__
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

int main(int argc, char** argv) {

	double y = 0;
	double x;
	double n = 0;
	ifstream inFile;

	inFile.open("test.txt");

	if (!inFile) {
    	cerr << "Unable to open file";
    	return 0;   // call system to stop
	}

	while (inFile >> x) {
  		y = y + x;
  		n = n + 1;
	}
	inFile.close();

 	ofstream myfile;
 	myfile.open ("testWrite.txt");
 	if (!myfile) {
    	cerr << "Unable to open file";
    	return 0;   // call system to stop
	}
  	myfile << "Average: " << y/n << "\nTotal sum: " << y << "\nNumber of Values: " << n;
    myfile.close();

	cout << "Average is " << y/n << endl;

	return 0;
}
<commit_msg>Delete readingPrac.cpp<commit_after><|endoftext|>


<commit_before>#include "SgInit.h"
#include "GoInit.h"

#include "BackendThread.hpp"
#include "GUI.hpp"

int main(int argc, char** argv) {
    QApplication qt_app(argc, argv);
    // changes the current working directory and makes all texture and model paths relative to the executable
    QDir::setCurrent(QCoreApplication::applicationDirPath());

    // init fuego
    SgInit();
    GoInit();

    {
        using Go_AR::BackendThread;
        using Go_GUI::GUI;

        BackendThread backend;
        GUI gui;

        // connect signal from backend to gui
        QObject::connect(&backend, &BackendThread::backend_new_image, &gui, &GUI::new_image, Qt::QueuedConnection);
        QObject::connect(&backend, &BackendThread::game_data_changed, &gui, &GUI::new_game_data, Qt::QueuedConnection);

        // connect signal from gui to backend
        QObject::connect(&gui, &GUI::stop_backend_thread, &backend, &BackendThread::stop, Qt::QueuedConnection);

        backend.start(); // start backend thread

        gui.show();
        qt_app.exec();   // start gui thread (and it's event loop)

        backend.quit();  // failsafe: explicitly tell the backend thread to stop (if the gui hasn't done this)
        backend.wait();  // gui was exited, wait for the backend thread (gui should have sent a signal to the backend thread to quit)
    }

    // "clean up" fuego
    GoFini();
    SgFini();

    return 0;
}<commit_msg>Refs #39 - connected save game signal from gui to backend<commit_after>#include "SgInit.h"
#include "GoInit.h"

#include "BackendThread.hpp"
#include "GUI.hpp"

int main(int argc, char** argv) {
    QApplication qt_app(argc, argv);
    // changes the current working directory and makes all texture and model paths relative to the executable
    QDir::setCurrent(QCoreApplication::applicationDirPath());

    // init fuego
    SgInit();
    GoInit();

    {
        using Go_AR::BackendThread;
        using Go_GUI::GUI;

        BackendThread backend;
        GUI gui;

        // connect signal from backend to gui
        QObject::connect(&backend, &BackendThread::backend_new_image, &gui, &GUI::new_image, Qt::QueuedConnection);
        QObject::connect(&backend, &BackendThread::game_data_changed, &gui, &GUI::new_game_data, Qt::QueuedConnection);

        // connect signal from gui to backend
        QObject::connect(&gui, &GUI::stop_backend_thread, &backend, &BackendThread::stop, Qt::QueuedConnection);
        QObject::connect(&gui, &GUI::signal_saveGame, &backend, &BackendThread::save_sgf, Qt::QueuedConnection);

        backend.start(); // start backend thread

        gui.show();
        qt_app.exec();   // start gui thread (and it's event loop)

        backend.quit();  // failsafe: explicitly tell the backend thread to stop (if the gui hasn't done this)
        backend.wait();  // gui was exited, wait for the backend thread (gui should have sent a signal to the backend thread to quit)
    }

    // "clean up" fuego
    GoFini();
    SgFini();

    return 0;
}<|endoftext|>