<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	I2C EEPROM ドライバー
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>
#include "common/iica_io.hpp"
#include "common/delay.hpp"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  EEPROM テンプレートクラス
		@param[in]	I2C_IO	i2c I/O クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class I2C_IO>
	class EEPROM {

		static const uint8_t	EEPROM_ADR_ = 0x50;

		I2C_IO&	i2c_;

		uint8_t	ds_;
		bool	exp_;
		bool	ad_mix_;
		uint8_t	pagen_;

		uint8_t i2c_adr_(uint32_t adr) const {
			uint8_t a = EEPROM_ADR_ | ds_;
			if(ad_mix_) {
				if(adr >> 16) a |= 4;
			}
			return a;
		}

	public:
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief 256 バイトまでの EEPROM の ID (0 to 7) @n
				   アドレス指定が１バイトのデバイス
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class M256B : uint8_t {
			ID0,	///< A0=L(0), A1=L(0), A2=L(0)
			ID1,	///< A0=H(1), A1=L(0), A2=L(0)
			ID2,	///< A0=L(0), A1=H(1), A2=L(0)
			ID3,	///< A0=H(1), A1=H(1), A2=L(0)
			ID4,	///< A0=L(0), A1=L(0), A2=H(1)
			ID5,	///< A0=H(1), A1=L(0), A2=H(1)
			ID6,	///< A0=L(0), A1=H(1), A2=H(1)
			ID7,	///< A0=H(1), A1=H(1), A2=H(1)
		};

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief 64K バイトまでの EEPROM の ID (0 to 7) @n
				   アドレス指定が２バイトのデバイス
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class M64KB : uint8_t {
			ID0,	///< A0=L(0), A1=L(0), A2=L(0)
			ID1,	///< A0=H(1), A1=L(0), A2=L(0)
			ID2,	///< A0=L(0), A1=H(1), A2=L(0)
			ID3,	///< A0=H(1), A1=H(1), A2=L(0)
			ID4,	///< A0=L(0), A1=L(0), A2=H(1)
			ID5,	///< A0=H(1), A1=L(0), A2=H(1)
			ID6,	///< A0=L(0), A1=H(1), A2=H(1)
			ID7,	///< A0=H(1), A1=H(1), A2=H(1)
		};

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief 128K バイトの EEPROM の ID (0 to 3) @n
				   アドレス指定が２バイトのデバイス @n
				   A2 端子が、バンクセレクトに使われるデバイス
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class M128KB : uint8_t {
			ID0,	///< A0=L(0), A1=L(0)
			ID1,	///< A0=H(1), A1=L(0)
			ID2,	///< A0=L(0), A1=H(1)
			ID3,	///< A0=H(1), A1=H(1)
		};

		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	i2c	i2c_io クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		EEPROM(I2C_IO& i2c) : i2c_(i2c), ds_(0),
			exp_(false), ad_mix_(false), pagen_(1) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	アドレス指定１バイトの EEPROM を開始
			@param[in]	type	デバイスのタイプとID
			@param[in]	pagen	ページサイズ（書き込み一時バッファのサイズ）
		 */
		//-----------------------------------------------------------------//
		void start(M256B type_id, uint8_t pagen) {
			ds_ = static_cast<uint8_t>(type_id);
			exp_ = false;
			ad_mix_ = false;
			pagen_ = pagen;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アドレス指定２バイトの EEPROM を開始
			@param[in]	type	デバイスのタイプとID
			@param[in]	pagen	ページサイズ（書き込み一時バッファのサイズ）
		 */
		//-----------------------------------------------------------------//
		void start(M64KB type_id, uint8_t pagen) {
			ds_ = static_cast<uint8_t>(type_id);
			exp_ = true;
			ad_mix_ = false;
			pagen_ = pagen;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アドレス指定２バイトで、「A2」がバンクの EEPROM を開始
			@param[in]	type	デバイスのタイプとID
			@param[in]	pagen	ページサイズ（書き込み一時バッファのサイズ）
		 */
		//-----------------------------------------------------------------//
		void start(M128KB type_id, uint8_t pagen) {
			ds_ = static_cast<uint8_t>(type_id);
			exp_ = true;
			ad_mix_ = true;
			pagen_ = pagen;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	書き込み状態の検査
			@param[in]	adr	検査アドレス
			@return 「false」なら、書き込み中
		 */
		//-----------------------------------------------------------------//
		bool get_write_state(uint32_t adr) const {
			uint8_t tmp[1];
			return read(adr, tmp, 1);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	書き込み同期
			@param[in]	adr	検査アドレス
			@param[in]	delay 待ち時間（10us単位）
			@return デバイスエラーなら「false」
		 */
		//-----------------------------------------------------------------//
		bool sync_write(uint32_t adr, uint16_t delay = 600) const {
			bool ok = false;
			for(uint16_t i = 0; i < delay; ++i) {
				utils::delay::micro_second(10);
				uint8_t tmp[1];
				if(read(adr, tmp, 1)) {
					ok = true;
					break;
				}
			}
			return ok;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	EEPROM 読み出し
			@param[in]	adr	読み出しアドレス
			@param[out]	dst	先
			@param[in]	len	長さ
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool read(uint32_t adr, uint8_t* dst, uint16_t len) const {
			uint8_t tmp[2];
			if(exp_) {
				tmp[0] = (adr >> 8) & 255;
				tmp[1] =  adr & 255;
				if(!i2c_.send(i2c_adr_(adr), tmp, 2)) {
					return false;
				}
			} else {
				tmp[0] = adr & 255;
				if(!i2c_.send(i2c_adr_(adr), tmp, 1)) {
					return false;
				}
			}
			if(!i2c_.recv(i2c_adr_(adr), dst, len)) {
				return false;
			}
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	EEPROM 書き込み
			@param[in]	adr	書き込みアドレス
			@param[out]	src	元
			@param[in]	len	長さ
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool write(uint32_t adr, const uint8_t* src, uint16_t len) const {
			while(len > 0) {
				uint16_t l = pagen_ - (adr & (pagen_ - 1));
				if(len < l) l = len;
				if(exp_) {
					if(!i2c_.send(i2c_adr_(adr), adr >> 8, adr & 255, src, l)) {
						return false;
					}
				} else {
					if(!i2c_.send(i2c_adr_(adr), adr & 255, src, l)) {
						return false;
					}
				}
				src += l;
				len -= l;
				if(len) {  // 書き込み終了を待つポーリング
					if(!sync_write(adr)) {
						return false;
					}
				}
				adr += l;
			}
			return true;
		}
	};
}
<commit_msg>update: cleanup<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	I2C EEPROM ドライバー
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>
#include "common/delay.hpp"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  EEPROM テンプレートクラス
		@param[in]	I2C	i2c I/O クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class I2C>
	class EEPROM {

		static const uint8_t	EEPROM_ADR_ = 0x50;

		I2C&	i2c_;

		uint8_t	ds_;
		bool	exp_;
		bool	ad_mix_;
		uint8_t	pagen_;

		uint8_t i2c_adr_(uint32_t adr) const {
			uint8_t a = EEPROM_ADR_ | ds_;
			if(ad_mix_) {
				if(adr >> 16) a |= 4;
			}
			return a;
		}

	public:
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief 256 バイトまでの EEPROM の ID (0 to 7) @n
				   アドレス指定が１バイトのデバイス
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class M256B : uint8_t {
			ID0,	///< A0=L(0), A1=L(0), A2=L(0)
			ID1,	///< A0=H(1), A1=L(0), A2=L(0)
			ID2,	///< A0=L(0), A1=H(1), A2=L(0)
			ID3,	///< A0=H(1), A1=H(1), A2=L(0)
			ID4,	///< A0=L(0), A1=L(0), A2=H(1)
			ID5,	///< A0=H(1), A1=L(0), A2=H(1)
			ID6,	///< A0=L(0), A1=H(1), A2=H(1)
			ID7,	///< A0=H(1), A1=H(1), A2=H(1)
		};

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief 64K バイトまでの EEPROM の ID (0 to 7) @n
				   アドレス指定が２バイトのデバイス
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class M64KB : uint8_t {
			ID0,	///< A0=L(0), A1=L(0), A2=L(0)
			ID1,	///< A0=H(1), A1=L(0), A2=L(0)
			ID2,	///< A0=L(0), A1=H(1), A2=L(0)
			ID3,	///< A0=H(1), A1=H(1), A2=L(0)
			ID4,	///< A0=L(0), A1=L(0), A2=H(1)
			ID5,	///< A0=H(1), A1=L(0), A2=H(1)
			ID6,	///< A0=L(0), A1=H(1), A2=H(1)
			ID7,	///< A0=H(1), A1=H(1), A2=H(1)
		};

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief 128K バイトの EEPROM の ID (0 to 3) @n
				   アドレス指定が２バイトのデバイス @n
				   A2 端子が、バンクセレクトに使われるデバイス
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class M128KB : uint8_t {
			ID0,	///< A0=L(0), A1=L(0)
			ID1,	///< A0=H(1), A1=L(0)
			ID2,	///< A0=L(0), A1=H(1)
			ID3,	///< A0=H(1), A1=H(1)
		};

		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	i2c	i2c_io クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		EEPROM(I2C& i2c) : i2c_(i2c), ds_(0),
			exp_(false), ad_mix_(false), pagen_(1) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	アドレス指定１バイトの EEPROM を開始
			@param[in]	type	デバイスのタイプとID
			@param[in]	pagen	ページサイズ（書き込み一時バッファのサイズ）
		 */
		//-----------------------------------------------------------------//
		void start(M256B type_id, uint8_t pagen) {
			ds_ = static_cast<uint8_t>(type_id);
			exp_ = false;
			ad_mix_ = false;
			pagen_ = pagen;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アドレス指定２バイトの EEPROM を開始
			@param[in]	type	デバイスのタイプとID
			@param[in]	pagen	ページサイズ（書き込み一時バッファのサイズ）
		 */
		//-----------------------------------------------------------------//
		void start(M64KB type_id, uint8_t pagen) {
			ds_ = static_cast<uint8_t>(type_id);
			exp_ = true;
			ad_mix_ = false;
			pagen_ = pagen;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アドレス指定２バイトで、「A2」がバンクの EEPROM を開始
			@param[in]	type	デバイスのタイプとID
			@param[in]	pagen	ページサイズ（書き込み一時バッファのサイズ）
		 */
		//-----------------------------------------------------------------//
		void start(M128KB type_id, uint8_t pagen) {
			ds_ = static_cast<uint8_t>(type_id);
			exp_ = true;
			ad_mix_ = true;
			pagen_ = pagen;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	書き込み状態の検査
			@param[in]	adr	検査アドレス
			@return 「false」なら、書き込み中
		 */
		//-----------------------------------------------------------------//
		bool get_write_state(uint32_t adr) const {
			uint8_t tmp[1];
			return read(adr, tmp, 1);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	書き込み同期
			@param[in]	adr	検査アドレス
			@param[in]	delay 待ち時間（10us単位）
			@return デバイスエラーなら「false」
		 */
		//-----------------------------------------------------------------//
		bool sync_write(uint32_t adr, uint16_t delay = 600) const {
			bool ok = false;
			for(uint16_t i = 0; i < delay; ++i) {
				utils::delay::micro_second(10);
				uint8_t tmp[1];
				if(read(adr, tmp, 1)) {
					ok = true;
					break;
				}
			}
			return ok;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	EEPROM 読み出し
			@param[in]	adr	読み出しアドレス
			@param[out]	dst	先
			@param[in]	len	長さ
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool read(uint32_t adr, void* dst, uint16_t len) const
		{
			if(exp_) {
				uint8_t tmp[2];
				tmp[0] = (adr >> 8) & 255;
				tmp[1] =  adr & 255;
				if(!i2c_.send(i2c_adr_(adr), tmp, 2)) {
					return false;
				}
			} else {
				uint8_t tmp[1];
				tmp[0] = adr & 255;
				if(!i2c_.send(i2c_adr_(adr), tmp, 1)) {
					return false;
				}
			}
			if(!i2c_.recv(i2c_adr_(adr), dst, len)) {
				return false;
			}
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	EEPROM 書き込み
			@param[in]	adr	書き込みアドレス
			@param[in]	src	元
			@param[in]	len	長さ
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool write(uint32_t adr, const void* src, uint16_t len) const
		{
			const uint8_t* p = static_cast<const uint8_t*>(src);
			while(len > 0) {
				uint16_t l = pagen_ - (adr & (pagen_ - 1));
				if(len < l) l = len;
				if(exp_) {
					if(!i2c_.send(i2c_adr_(adr), adr >> 8, adr & 255, p, l)) {
						return false;
					}
				} else {
					if(!i2c_.send(i2c_adr_(adr), adr & 255, p, l)) {
						return false;
					}
				}
				p += l;
				len -= l;
				if(len) {  // 書き込み終了を待つポーリング
					if(!sync_write(adr)) {
						return false;
					}
				}
				adr += l;
			}
			return true;
		}
	};
}
<|endoftext|>


<commit_before>#include "robotsBlockParser.h"

using namespace qReal;
using namespace utils;

RobotsBlockParser::RobotsBlockParser(ErrorReporterInterface *errorReporter)
	: ExpressionsParser(errorReporter)
{
	setReservedVariables();
}

Number RobotsBlockParser::standartBlockParseProcess(const QString &stream, int &pos, const Id &curId)
{
	mCurrentId = curId;

	if (isEmpty(stream, pos)) {
		error(emptyProcess);
		return Number(0, Number::intType);
	}
	QStringList exprs = stream.split(";", QString::SkipEmptyParts);
	for (int i = 0; i < (exprs.length() - 1); ++i) {
		if (mHasParseErrors)
			return Number(0, Number::intType);
		int position = 0;
		QString expr = exprs[i];
		skip(expr, position);
		parseCommand(expr + ";", position);
	}
	int position = 0;
	QString valueExpression = exprs.last();
	if (!valueExpression.contains("="))
		return parseExpression(valueExpression, position);
	else {
		error(noExpression);
		return Number(0, Number::intType);
	}
}

void RobotsBlockParser::functionBlockParseProcess(const QString &stream, int &pos, const Id &curId)
{
	mCurrentId = curId;

	if (isEmpty(stream, pos))
		error(emptyProcess);

	bool hasParseErrorsFlag = false;

	QStringList exprs = stream.split(";", QString::SkipEmptyParts);
	for (int i = 0; i < exprs.length(); ++i) {
		if (mHasParseErrors) {
			mHasParseErrors = false; /*С‡С‚РѕР±С‹ РЅРµ РїРѕР»СѓС‡РёС‚СЊ Р»РёС€РЅРёС… РѕС€РёР±РѕРє, Р±СѓРґРµРј РЅРµР·Р°РІРёСЃРёРјРѕ РѕР±СЂР°Р±Р°С‚С‹РІР°С‚СЊ РїРµСЂРµРјРµРЅРЅС‹Рµ*/
			hasParseErrorsFlag = true;
		}
		int position = 0;
		QString expr = exprs[i];
		skip(expr, position);
		parseCommand(expr + ";", position);
	}
	mHasParseErrors = hasParseErrorsFlag;
}

void RobotsBlockParser::deselect()
{
	mHasParseErrors = false;
}

void RobotsBlockParser::robotsClearVariables()
{
	mVariables.clear();
	setReservedVariables();
}

bool RobotsBlockParser::checkForUsingReservedVariables(const QString &nameOfVariable)
{
	if ((mReservedVariables.contains(nameOfVariable)) || (isFunction(nameOfVariable))) {
		mHasParseErrors = true;
		error(usingReservedVariable, "", "", nameOfVariable);
	}
	return mHasParseErrors;
}

bool RobotsBlockParser::isLetter(const QChar &symbol)
{
	QString rus = QString::fromUtf8("РђР°Р‘Р±Р’РІР“РіР”РґР•РµРЃС‘Р–Р¶Р—Р·РРёР™Р№РљРєР›Р»РњРјРќРЅРћРѕРџРїР СЂРЎСЃРўС‚РЈСѓР¤С„РҐС…Р¦С†Р§С‡РЁС€Р©С‰Р¬СЊР«С‹Р™Р№РСЌР®СЋРЇСЏ");
	char symbolChar = symbol.toAscii();
	return (('A'<=symbolChar && symbolChar<='Z') || ('a'<=symbolChar && symbolChar<='z') || (rus.contains(symbol)));
}

void RobotsBlockParser::setReservedVariables()
{
	QString const pi = "pi";
	Number value = Number(3.14, Number::doubleType);
	mVariables.insert(pi, value);
	for (int i = 1; i <= 4; ++i) {
		QString variable = QObject::tr("Sensor") + QString::number(i);
		mVariables.insert(variable, Number(0, Number::intType));
		mReservedVariables.append(variable);
	}
}
<commit_msg>Fixed russian variale duplicates in watch window<commit_after>#include "robotsBlockParser.h"

using namespace qReal;
using namespace utils;

RobotsBlockParser::RobotsBlockParser(ErrorReporterInterface *errorReporter)
	: ExpressionsParser(errorReporter)
{
	setReservedVariables();
}

Number RobotsBlockParser::standartBlockParseProcess(const QString &stream, int &pos, const Id &curId)
{
	mCurrentId = curId;

	if (isEmpty(stream, pos)) {
		error(emptyProcess);
		return Number(0, Number::intType);
	}
	QStringList exprs = stream.split(";", QString::SkipEmptyParts);
	for (int i = 0; i < (exprs.length() - 1); ++i) {
		if (mHasParseErrors)
			return Number(0, Number::intType);
		int position = 0;
		QString expr = exprs[i];
		skip(expr, position);
		parseCommand(expr + ";", position);
	}
	int position = 0;
	QString valueExpression = exprs.last();
	if (!valueExpression.contains("="))
		return parseExpression(valueExpression, position);
	else {
		error(noExpression);
		return Number(0, Number::intType);
	}
}

void RobotsBlockParser::functionBlockParseProcess(const QString &stream, int &pos, const Id &curId)
{
	mCurrentId = curId;

	if (isEmpty(stream, pos))
		error(emptyProcess);

	bool hasParseErrorsFlag = false;

	QStringList exprs = stream.split(";", QString::SkipEmptyParts);
	for (int i = 0; i < exprs.length(); ++i) {
		if (mHasParseErrors) {
			mHasParseErrors = false; /*С‡С‚РѕР±С‹ РЅРµ РїРѕР»СѓС‡РёС‚СЊ Р»РёС€РЅРёС… РѕС€РёР±РѕРє, Р±СѓРґРµРј РЅРµР·Р°РІРёСЃРёРјРѕ РѕР±СЂР°Р±Р°С‚С‹РІР°С‚СЊ РїРµСЂРµРјРµРЅРЅС‹Рµ*/
			hasParseErrorsFlag = true;
		}
		int position = 0;
		QString expr = exprs[i];
		skip(expr, position);
		parseCommand(expr + ";", position);
	}
	mHasParseErrors = hasParseErrorsFlag;
}

void RobotsBlockParser::deselect()
{
	mHasParseErrors = false;
}

void RobotsBlockParser::robotsClearVariables()
{
	mVariables.clear();
	setReservedVariables();
}

bool RobotsBlockParser::checkForUsingReservedVariables(const QString &nameOfVariable)
{
	if ((mReservedVariables.contains(nameOfVariable)) || (isFunction(nameOfVariable))) {
		mHasParseErrors = true;
		error(usingReservedVariable, "", "", nameOfVariable);
	}
	return mHasParseErrors;
}

bool RobotsBlockParser::isLetter(const QChar &symbol)
{
	QString rus = QString::fromUtf8("РђР°Р‘Р±Р’РІР“РіР”РґР•РµРЃС‘Р–Р¶Р—Р·РРёР™Р№РљРєР›Р»РњРјРќРЅРћРѕРџРїР СЂРЎСЃРўС‚РЈСѓР¤С„РҐС…Р¦С†Р§С‡РЁС€Р©С‰Р¬СЊР«С‹Р™Р№РСЌР®СЋРЇСЏ");
	char symbolChar = symbol.toAscii();
	return (('A'<=symbolChar && symbolChar<='Z') || ('a'<=symbolChar && symbolChar<='z') || (rus.contains(symbol)));
}

void RobotsBlockParser::setReservedVariables()
{
	QString const pi = "pi";
	Number value = Number(3.14, Number::doubleType);
	mVariables.insert(pi, value);
	for (int i = 1; i <= 4; ++i) {
		// TODO: restore QObject::tr("Sensor") when russian variable names would be supported
		QString variable = "Sensor" + QString::number(i);
		mVariables.insert(variable, Number(0, Number::intType));
		mReservedVariables.append(variable);
	}
}
<|endoftext|>


<commit_before><commit_msg>Fix problem with ETW timer variable scope<commit_after><|endoftext|>


<commit_before>//--------------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2005, 2006 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//--------------------------------------------------------------------

// Tests all aspects of LAPACKFullMatrix

#include "../tests.h"
#include <base/logstream.h>
#include <lac/lapack_full_matrix.h>
#include <lac/full_matrix.h>
#include <lac/vector.h>

#include <fstream>
#include <iostream>

/*
 * Eigenvalues and -vectors of this system are
 * lambda = 1     v = (1, 1, 1, 1)
 * lambda = 5     v = (1,-1, 0, 0)
 * lambda = 5     v = (0, 1,-1, 0)
 * lambda = 5     v = (0, 0, 1,-1)
 */
const double symm[] =
{
      4., -1., -1., -1.,
      -1., 4., -1., -1.,
      -1., -1., 4., -1.,
      -1., -1., -1., 4.
};

const double rect[] =
{
      4., 3., 2., 1.,
      5., 8., 1., -2.,
      11., 13., -4., -5
};

int main()
{
  std::ofstream logfile("full_matrix/output");
  logfile.precision(3);
  deallog.attach(logfile);
  deallog.depth_console(0);
  deallog.threshold_double(1.e-10);

  FullMatrix<double> A(3,4,rect);
  LAPACKFullMatrix<double> LA(3,4);
  LA = A;

  Vector<double> u(4);
  Vector<double> v1(3);
  Vector<double> v2(3);

  for (unsigned int i=0;i<u.size();++i)
    u(i) = i*i;

				   // Test rectangular vmult. All
				   // results compare with same
				   // operation for FullMatrix.
  deallog.push("Rect");

  deallog << "operator= (const FullMatrix<number>&) ok" << std::endl;

  A.vmult(v1,u);
  LA.vmult(v2,u);
  v1 -= v2;
  if (v1.l2_norm() < 1.e-14)
    deallog << "vmult ok" << std::endl;
  v1 = v2;

  A.vmult_add(v1,u);
  LA.vmult_add(v2,u);
  v1 -= v2;
  if (v1.l2_norm() < 1.e-14)
    deallog << "vmult_add ok" << std::endl;

  LA.Tvmult(u, v2);
  u *= -1;
  A.Tvmult_add(u, v2);
  if (u.l2_norm() < 1.e-14)
    deallog << "Tvmult ok" << std::endl;

  A.Tvmult(u, v2);
  u *= -1;
  LA.Tvmult_add(u, v2);
  if (u.l2_norm() < 1.e-14)
    deallog << "Tvmult_add ok" << std::endl;

  deallog.pop();

				   // Test symmetric system
  A.reinit(4,4);
  LA.reinit(4,4);
  A.fill(symm);
  LA = A;
  LA.compute_eigenvalues();
  for (unsigned int i=0;i<A.m();++i)
    {
      std::complex<double> lambda = LA.eigenvalue(i);
      deallog << "Eigenvalues "
	      << (int) (lambda.real()+.0001) << '\t'
	      << (int) (lambda.imag()+.0001) << std::endl;
    }

  v1.reinit(4);
  v2.reinit(4);
}
<commit_msg>change description<commit_after>//--------------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2005, 2006 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//--------------------------------------------------------------------

// Tests all aspects of LAPACKFullMatrix except eigenvectors

#include "../tests.h"
#include <base/logstream.h>
#include <lac/lapack_full_matrix.h>
#include <lac/full_matrix.h>
#include <lac/vector.h>

#include <fstream>
#include <iostream>

/*
 * Eigenvalues and -vectors of this system are
 * lambda = 1     v = (1, 1, 1, 1)
 * lambda = 5     v = (1,-1, 0, 0)
 * lambda = 5     v = (0, 1,-1, 0)
 * lambda = 5     v = (0, 0, 1,-1)
 */
const double symm[] =
{
      4., -1., -1., -1.,
      -1., 4., -1., -1.,
      -1., -1., 4., -1.,
      -1., -1., -1., 4.
};

const double rect[] =
{
      4., 3., 2., 1.,
      5., 8., 1., -2.,
      11., 13., -4., -5
};

int main()
{
  std::ofstream logfile("full_matrix/output");
  logfile.precision(3);
  deallog.attach(logfile);
  deallog.depth_console(0);
  deallog.threshold_double(1.e-10);

  FullMatrix<double> A(3,4,rect);
  LAPACKFullMatrix<double> LA(3,4);
  LA = A;

  Vector<double> u(4);
  Vector<double> v1(3);
  Vector<double> v2(3);

  for (unsigned int i=0;i<u.size();++i)
    u(i) = i*i;

				   // Test rectangular vmult. All
				   // results compare with same
				   // operation for FullMatrix.
  deallog.push("Rect");

  deallog << "operator= (const FullMatrix<number>&) ok" << std::endl;

  A.vmult(v1,u);
  LA.vmult(v2,u);
  v1 -= v2;
  if (v1.l2_norm() < 1.e-14)
    deallog << "vmult ok" << std::endl;
  v1 = v2;

  A.vmult_add(v1,u);
  LA.vmult_add(v2,u);
  v1 -= v2;
  if (v1.l2_norm() < 1.e-14)
    deallog << "vmult_add ok" << std::endl;

  LA.Tvmult(u, v2);
  u *= -1;
  A.Tvmult_add(u, v2);
  if (u.l2_norm() < 1.e-14)
    deallog << "Tvmult ok" << std::endl;

  A.Tvmult(u, v2);
  u *= -1;
  LA.Tvmult_add(u, v2);
  if (u.l2_norm() < 1.e-14)
    deallog << "Tvmult_add ok" << std::endl;

  deallog.pop();

				   // Test symmetric system
  A.reinit(4,4);
  LA.reinit(4,4);
  A.fill(symm);
  LA = A;
  LA.compute_eigenvalues();
  for (unsigned int i=0;i<A.m();++i)
    {
      std::complex<double> lambda = LA.eigenvalue(i);
      deallog << "Eigenvalues "
	      << (int) (lambda.real()+.0001) << '\t'
	      << (int) (lambda.imag()+.0001) << std::endl;
    }

  v1.reinit(4);
  v2.reinit(4);
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/views/menu_bar.h"

#if defined(USE_X11)
#include "gtk/gtk.h"
#endif

#include "atom/browser/ui/views/menu_delegate.h"
#include "atom/browser/ui/views/submenu_button.h"
#include "ui/base/models/menu_model.h"
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"

#if defined(OS_WIN)
#include "ui/gfx/color_utils.h"
#elif defined(USE_X11)
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
#endif

namespace atom {

namespace {

const char kViewClassName[] = "ElectronMenuBar";

// Default color of the menu bar.
const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233);

#if defined(USE_X11)
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
                     SkColor* hover, SkColor* background) {
  GtkWidget* menu_bar = gtk_menu_bar_new();

  GtkStyle* style = gtk_rc_get_style(menu_bar);
  *enabled = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]);
  *disabled = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]);
  *highlight = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]);
  *hover = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]);
  *background = libgtkui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]);

  gtk_widget_destroy(menu_bar);
}
#endif

}  // namespace

MenuBar::MenuBar(NativeWindow* window)
    : background_color_(kDefaultColor),
      menu_model_(NULL),
      window_(window) {
  UpdateMenuBarColor();
  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal));
}

MenuBar::~MenuBar() {
}

void MenuBar::SetMenu(AtomMenuModel* model) {
  menu_model_ = model;
  RemoveAllChildViews(true);

  for (int i = 0; i < model->GetItemCount(); ++i) {
    SubmenuButton* button = new SubmenuButton(model->GetLabelAt(i),
                                              this,
                                              background_color_);
    button->set_tag(i);

#if defined(USE_X11)
    button->SetTextColor(views::Button::STATE_NORMAL, enabled_color_);
    button->SetTextColor(views::Button::STATE_DISABLED, disabled_color_);
    button->SetTextColor(views::Button::STATE_PRESSED, highlight_color_);
    button->SetTextColor(views::Button::STATE_HOVERED, hover_color_);
    button->SetUnderlineColor(enabled_color_);
#elif defined(OS_WIN)
    button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_GRAYTEXT));
#endif

    AddChildView(button);
  }
}

void MenuBar::SetAcceleratorVisibility(bool visible) {
  for (int i = 0; i < child_count(); ++i)
    static_cast<SubmenuButton*>(child_at(i))->SetAcceleratorVisibility(visible);
}

int MenuBar::GetAcceleratorIndex(base::char16 key) {
  for (int i = 0; i < child_count(); ++i) {
    SubmenuButton* button = static_cast<SubmenuButton*>(child_at(i));
    if (button->accelerator() == key)
      return i;
  }
  return -1;
}

void MenuBar::ActivateAccelerator(base::char16 key) {
  int i = GetAcceleratorIndex(key);
  if (i != -1)
    static_cast<SubmenuButton*>(child_at(i))->Activate(nullptr);
}

int MenuBar::GetItemCount() const {
  return menu_model_->GetItemCount();
}

bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point,
                                           AtomMenuModel** menu_model,
                                           views::MenuButton** button) {
  gfx::Point location(point);
  views::View::ConvertPointFromScreen(this, &location);

  if (location.x() < 0 || location.x() >= width() || location.y() < 0 ||
      location.y() >= height())
    return false;

  for (int i = 0; i < child_count(); ++i) {
    views::View* view = child_at(i);
    if (view->GetMirroredBounds().Contains(location) &&
        (menu_model_->GetTypeAt(i) == AtomMenuModel::TYPE_SUBMENU)) {
      *menu_model = menu_model_->GetSubmenuModelAt(i);
      *button = static_cast<views::MenuButton*>(view);
      return true;
    }
  }

  return false;
}

const char* MenuBar::GetClassName() const {
  return kViewClassName;
}

void MenuBar::OnMenuButtonClicked(views::MenuButton* source,
                                  const gfx::Point& point,
                                  const ui::Event* event) {
  // Hide the accelerator when a submenu is activated.
  SetAcceleratorVisibility(false);

  if (!menu_model_)
    return;

  if (!window_->IsFocused())
    window_->Focus(true);

  int id = source->tag();
  AtomMenuModel::ItemType type = menu_model_->GetTypeAt(id);
  if (type != AtomMenuModel::TYPE_SUBMENU) {
    menu_model_->ActivatedAt(id, 0);
    return;
  }

  // Deleted in MenuDelegate::OnMenuClosed
  MenuDelegate* menu_delegate = new MenuDelegate(this);
  menu_delegate->RunMenu(menu_model_->GetSubmenuModelAt(id), source);
}

void MenuBar::OnNativeThemeChanged(const ui::NativeTheme* theme) {
  UpdateMenuBarColor();
}

void MenuBar::UpdateMenuBarColor() {
#if defined(OS_WIN)
  background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
#elif defined(USE_X11)
  GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_,
                  &hover_color_, &background_color_);
#endif
  SetBackground(views::CreateSolidBackground(background_color_));
}

}  // namespace atom
<commit_msg>fix gtk3 deprecation warnings setting menubar colors<commit_after>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/views/menu_bar.h"

#if defined(USE_X11)
#include "gtk/gtk.h"
#endif

#include "atom/browser/ui/views/menu_delegate.h"
#include "atom/browser/ui/views/submenu_button.h"
#include "ui/base/models/menu_model.h"
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"

#if defined(OS_WIN)
#include "ui/gfx/color_utils.h"
#elif defined(USE_X11)
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
#endif

namespace atom {

namespace {

#if defined(USE_X11)
#if GTK_CHECK_VERSION(3,0,0)

SkColor GdkRgbaToSkColor(const GdkRGBA& rgba) {
  return SkColorSetARGB(rgba.alpha*255, rgba.red*255,
                        rgba.green*255, rgba.blue*255);
}

SkColor GetStyleContextFgColor(GtkStyleContext* style_context,
                               GtkStateFlags state) {
  GdkRGBA rgba;
  gtk_style_context_get_color(style_context, state, &rgba);
  return GdkRgbaToSkColor(rgba);
}

SkColor GetStyleContextBgColor(GtkStyleContext* style_context,
                               GtkStateFlags state) {
  GdkRGBA rgba;
  gtk_style_context_get_background_color(style_context, state, &rgba);
  return GdkRgbaToSkColor(rgba);
}

// GTK+ 3 impl
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
                     SkColor* hover, SkColor* background) {
  GtkWidget* menu_bar = gtk_menu_bar_new();
  GtkStyleContext* style_context = gtk_widget_get_style_context(menu_bar);
  *enabled    = GetStyleContextFgColor(style_context, GTK_STATE_FLAG_NORMAL);
  *disabled   = GetStyleContextFgColor(style_context, GTK_STATE_FLAG_INSENSITIVE);
  *highlight  = GetStyleContextFgColor(style_context, GTK_STATE_FLAG_SELECTED);
  *hover      = GetStyleContextFgColor(style_context, GTK_STATE_FLAG_PRELIGHT);
  *background = GetStyleContextBgColor(style_context, GTK_STATE_FLAG_NORMAL);
  g_object_unref(G_OBJECT(menu_bar));
}

#else  // GTK_CHECK_VERSION(3,0,0)

// GTK+ 2 impl
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
                     SkColor* hover, SkColor* background) {
  GtkWidget* menu_bar = gtk_menu_bar_new();
  GtkStyle* style = gtk_rc_get_style(menu_bar);
  *enabled    = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]);
  *disabled   = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]);
  *highlight  = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]);
  *hover      = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]);
  *background = libgtkui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]);
  g_object_unref(G_OBJECT(menu_bar));
}
#endif  // GTK_CHECK_VERSION(3,0,0)
#endif  // USE_X11

const char kViewClassName[] = "ElectronMenuBar";

// Default color of the menu bar.
const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233);

}  // namespace

MenuBar::MenuBar(NativeWindow* window)
    : background_color_(kDefaultColor),
      menu_model_(NULL),
      window_(window) {
  UpdateMenuBarColor();
  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal));
}

MenuBar::~MenuBar() {
}

void MenuBar::SetMenu(AtomMenuModel* model) {
  menu_model_ = model;
  RemoveAllChildViews(true);

  for (int i = 0; i < model->GetItemCount(); ++i) {
    SubmenuButton* button = new SubmenuButton(model->GetLabelAt(i),
                                              this,
                                              background_color_);
    button->set_tag(i);

#if defined(USE_X11)
    button->SetTextColor(views::Button::STATE_NORMAL, enabled_color_);
    button->SetTextColor(views::Button::STATE_DISABLED, disabled_color_);
    button->SetTextColor(views::Button::STATE_PRESSED, highlight_color_);
    button->SetTextColor(views::Button::STATE_HOVERED, hover_color_);
    button->SetUnderlineColor(enabled_color_);
#elif defined(OS_WIN)
    button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_GRAYTEXT));
#endif

    AddChildView(button);
  }
}

void MenuBar::SetAcceleratorVisibility(bool visible) {
  for (int i = 0; i < child_count(); ++i)
    static_cast<SubmenuButton*>(child_at(i))->SetAcceleratorVisibility(visible);
}

int MenuBar::GetAcceleratorIndex(base::char16 key) {
  for (int i = 0; i < child_count(); ++i) {
    SubmenuButton* button = static_cast<SubmenuButton*>(child_at(i));
    if (button->accelerator() == key)
      return i;
  }
  return -1;
}

void MenuBar::ActivateAccelerator(base::char16 key) {
  int i = GetAcceleratorIndex(key);
  if (i != -1)
    static_cast<SubmenuButton*>(child_at(i))->Activate(nullptr);
}

int MenuBar::GetItemCount() const {
  return menu_model_->GetItemCount();
}

bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point,
                                           AtomMenuModel** menu_model,
                                           views::MenuButton** button) {
  gfx::Point location(point);
  views::View::ConvertPointFromScreen(this, &location);

  if (location.x() < 0 || location.x() >= width() || location.y() < 0 ||
      location.y() >= height())
    return false;

  for (int i = 0; i < child_count(); ++i) {
    views::View* view = child_at(i);
    if (view->GetMirroredBounds().Contains(location) &&
        (menu_model_->GetTypeAt(i) == AtomMenuModel::TYPE_SUBMENU)) {
      *menu_model = menu_model_->GetSubmenuModelAt(i);
      *button = static_cast<views::MenuButton*>(view);
      return true;
    }
  }

  return false;
}

const char* MenuBar::GetClassName() const {
  return kViewClassName;
}

void MenuBar::OnMenuButtonClicked(views::MenuButton* source,
                                  const gfx::Point& point,
                                  const ui::Event* event) {
  // Hide the accelerator when a submenu is activated.
  SetAcceleratorVisibility(false);

  if (!menu_model_)
    return;

  if (!window_->IsFocused())
    window_->Focus(true);

  int id = source->tag();
  AtomMenuModel::ItemType type = menu_model_->GetTypeAt(id);
  if (type != AtomMenuModel::TYPE_SUBMENU) {
    menu_model_->ActivatedAt(id, 0);
    return;
  }

  // Deleted in MenuDelegate::OnMenuClosed
  MenuDelegate* menu_delegate = new MenuDelegate(this);
  menu_delegate->RunMenu(menu_model_->GetSubmenuModelAt(id), source);
}

void MenuBar::OnNativeThemeChanged(const ui::NativeTheme* theme) {
  UpdateMenuBarColor();
}

void MenuBar::UpdateMenuBarColor() {
#if defined(OS_WIN)
  background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
#elif defined(USE_X11)
  GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_,
                  &hover_color_, &background_color_);
#endif
  SetBackground(views::CreateSolidBackground(background_color_));
}

}  // namespace atom
<|endoftext|>


<commit_before><commit_msg>findbar01: Local merge with remote repo<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/web_dialog_helper.h"

#include <string>
#include <vector>

#include "atom/browser/atom_browser_context.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h"
#include "base/bind.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/file_chooser_file_info.h"
#include "content/public/common/file_chooser_params.h"
#include "net/base/mime_util.h"
#include "ui/shell_dialogs/selected_file_info.h"

namespace {

class FileSelectHelper : public base::RefCountedThreadSafe<
                             FileSelectHelper,
                             content::BrowserThread::DeleteOnUIThread>,
                         public content::WebContentsObserver {
 public:
  FileSelectHelper(content::RenderFrameHost* render_frame_host,
                   const content::FileChooserParams::Mode& mode)
      : render_frame_host_(render_frame_host), mode_(mode) {
    auto web_contents = content::WebContents::FromRenderFrameHost(
        render_frame_host);
    content::WebContentsObserver::Observe(web_contents);
    // Add ref that will be released when the dialog is completed
    AddRef();
  }

  void ShowOpenDialog(const file_dialog::DialogSettings& settings) {
    auto callback = base::Bind(&FileSelectHelper::OnOpenDialogDone,
                               base::Unretained(this));
    file_dialog::ShowOpenDialog(settings, callback);
  }

  void ShowSaveDialog(const file_dialog::DialogSettings& settings) {
    auto callback = base::Bind(&FileSelectHelper::OnSaveDialogDone,
                               base::Unretained(this));
    file_dialog::ShowSaveDialog(settings, callback);
  }

 private:
  void OnOpenDialogDone(bool result, const std::vector<base::FilePath>& paths) {
    std::vector<content::FileChooserFileInfo> file_info;
    if (result) {
      for (auto& path : paths) {
        content::FileChooserFileInfo info;
        info.file_path = path;
        info.display_name = path.BaseName().value();
        file_info.push_back(info);
      }

      if (!paths.empty()) {
        auto browser_context = static_cast<atom::AtomBrowserContext*>(
            render_frame_host_->GetProcess()->GetBrowserContext());
        browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory,
                                              paths[0].DirName());
      }
    }
    OnFilesSelected(file_info);
  }

  void OnSaveDialogDone(bool result, const base::FilePath& path) {
    std::vector<content::FileChooserFileInfo> file_info;
    if (result) {
      content::FileChooserFileInfo info;
      info.file_path = path;
      info.display_name = path.BaseName().value();
      file_info.push_back(info);
    }
    OnFilesSelected(file_info);
  }

  void OnFilesSelected(
      const std::vector<content::FileChooserFileInfo>& file_info) {
    if (render_frame_host_)
      render_frame_host_->FilesSelectedInChooser(file_info, mode_);
    Release();
  }

  // content::WebContentsObserver:
  void RenderFrameHostChanged(content::RenderFrameHost* old_host,
                              content::RenderFrameHost* new_host) override {
    if (old_host == render_frame_host_)
      render_frame_host_ = nullptr;
  }

  // content::WebContentsObserver:
  void RenderFrameDeleted(content::RenderFrameHost* deleted_host) override {
    if (deleted_host == render_frame_host_)
      render_frame_host_ = nullptr;
  }

  // content::WebContentsObserver:
  void WebContentsDestroyed() override {
    render_frame_host_ = nullptr;
  }

  content::RenderFrameHost* render_frame_host_;
  content::FileChooserParams::Mode mode_;
};

file_dialog::Filters GetFileTypesFromAcceptType(
    const std::vector<base::string16>& accept_types) {
  file_dialog::Filters filters;
  if (accept_types.empty())
    return filters;

  std::vector<base::FilePath::StringType> extensions;

  for (const auto& accept_type : accept_types) {
    std::string ascii_type = base::UTF16ToASCII(accept_type);
    if (ascii_type[0] == '.') {
      // If the type starts with a period it is assumed to be a file extension,
      // like `.txt`, // so we just have to add it to the list.
      base::FilePath::StringType extension(
          ascii_type.begin(), ascii_type.end());
      // Skip the first character.
      extensions.push_back(extension.substr(1));
    } else {
      // For MIME Type, `audio/*, vidio/*, image/*
      net::GetExtensionsForMimeType(ascii_type, &extensions);
    }
  }

  // If no valid exntesion is added, return empty filters.
  if (extensions.empty())
    return filters;

  filters.push_back(file_dialog::Filter());
  for (const auto& extension : extensions) {
#if defined(OS_WIN)
    filters[0].second.push_back(base::UTF16ToASCII(extension));
#else
    filters[0].second.push_back(extension);
#endif
  }
  return filters;
}

}  // namespace

namespace atom {

WebDialogHelper::WebDialogHelper(NativeWindow* window)
    : window_(window),
      weak_factory_(this) {
}

WebDialogHelper::~WebDialogHelper() {
}

void WebDialogHelper::RunFileChooser(
    content::RenderFrameHost* render_frame_host,
    const content::FileChooserParams& params) {
  std::vector<content::FileChooserFileInfo> result;

  file_dialog::DialogSettings settings;
  settings.filters = GetFileTypesFromAcceptType(params.accept_types);
  settings.parent_window = window_;
  settings.title = base::UTF16ToUTF8(params.title);

  scoped_refptr<FileSelectHelper> file_select_helper(
      new FileSelectHelper(render_frame_host, params.mode));
  if (params.mode == content::FileChooserParams::Save) {
    settings.default_path = params.default_file_name;
    file_select_helper->ShowSaveDialog(settings);
  } else {
    int flags = file_dialog::FILE_DIALOG_CREATE_DIRECTORY;
    switch (params.mode) {
      case content::FileChooserParams::OpenMultiple:
        flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS;
      case content::FileChooserParams::Open:
        flags |= file_dialog::FILE_DIALOG_OPEN_FILE;
        break;
      case content::FileChooserParams::UploadFolder:
        flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
        break;
      default:
        NOTREACHED();
    }

    AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
        window_->web_contents()->GetBrowserContext());
    settings.default_path = browser_context->prefs()->GetFilePath(
        prefs::kSelectFileLastDirectory).Append(params.default_file_name);
    settings.properties = flags;
    file_select_helper->ShowOpenDialog(settings);
  }
}

void WebDialogHelper::EnumerateDirectory(content::WebContents* web_contents,
                                         int request_id,
                                         const base::FilePath& dir) {
  int types = base::FileEnumerator::FILES |
              base::FileEnumerator::DIRECTORIES |
              base::FileEnumerator::INCLUDE_DOT_DOT;
  base::FileEnumerator file_enum(dir, false, types);

  base::FilePath path;
  std::vector<base::FilePath> paths;
  while (!(path = file_enum.Next()).empty())
    paths.push_back(path);

  web_contents->GetRenderViewHost()->DirectoryEnumerationFinished(
      request_id, paths);
}

}  // namespace atom
<commit_msg> Extend RefCounted and add private destructor<commit_after>// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/web_dialog_helper.h"

#include <string>
#include <vector>

#include "atom/browser/atom_browser_context.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h"
#include "base/bind.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/file_chooser_file_info.h"
#include "content/public/common/file_chooser_params.h"
#include "net/base/mime_util.h"
#include "ui/shell_dialogs/selected_file_info.h"

namespace {

class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
                         public content::WebContentsObserver {
 public:
  FileSelectHelper(content::RenderFrameHost* render_frame_host,
                   const content::FileChooserParams::Mode& mode)
      : render_frame_host_(render_frame_host), mode_(mode) {
    auto web_contents = content::WebContents::FromRenderFrameHost(
        render_frame_host);
    content::WebContentsObserver::Observe(web_contents);
    // Add ref that will be released when the dialog is completed
    AddRef();
  }

  void ShowOpenDialog(const file_dialog::DialogSettings& settings) {
    auto callback = base::Bind(&FileSelectHelper::OnOpenDialogDone, this);
    file_dialog::ShowOpenDialog(settings, callback);
  }

  void ShowSaveDialog(const file_dialog::DialogSettings& settings) {
    auto callback = base::Bind(&FileSelectHelper::OnSaveDialogDone, this);
    file_dialog::ShowSaveDialog(settings, callback);
  }

 private:
  friend class base::RefCounted<FileSelectHelper>;

  ~FileSelectHelper() {}

  void OnOpenDialogDone(bool result, const std::vector<base::FilePath>& paths) {
    std::vector<content::FileChooserFileInfo> file_info;
    if (result) {
      for (auto& path : paths) {
        content::FileChooserFileInfo info;
        info.file_path = path;
        info.display_name = path.BaseName().value();
        file_info.push_back(info);
      }

      if (!paths.empty()) {
        auto browser_context = static_cast<atom::AtomBrowserContext*>(
            render_frame_host_->GetProcess()->GetBrowserContext());
        browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory,
                                              paths[0].DirName());
      }
    }
    OnFilesSelected(file_info);
  }

  void OnSaveDialogDone(bool result, const base::FilePath& path) {
    std::vector<content::FileChooserFileInfo> file_info;
    if (result) {
      content::FileChooserFileInfo info;
      info.file_path = path;
      info.display_name = path.BaseName().value();
      file_info.push_back(info);
    }
    OnFilesSelected(file_info);
  }

  void OnFilesSelected(
      const std::vector<content::FileChooserFileInfo>& file_info) {
    if (render_frame_host_)
      render_frame_host_->FilesSelectedInChooser(file_info, mode_);
    Release();
  }

  // content::WebContentsObserver:
  void RenderFrameHostChanged(content::RenderFrameHost* old_host,
                              content::RenderFrameHost* new_host) override {
    if (old_host == render_frame_host_)
      render_frame_host_ = nullptr;
  }

  // content::WebContentsObserver:
  void RenderFrameDeleted(content::RenderFrameHost* deleted_host) override {
    if (deleted_host == render_frame_host_)
      render_frame_host_ = nullptr;
  }

  // content::WebContentsObserver:
  void WebContentsDestroyed() override {
    render_frame_host_ = nullptr;
  }

  content::RenderFrameHost* render_frame_host_;
  content::FileChooserParams::Mode mode_;
};

file_dialog::Filters GetFileTypesFromAcceptType(
    const std::vector<base::string16>& accept_types) {
  file_dialog::Filters filters;
  if (accept_types.empty())
    return filters;

  std::vector<base::FilePath::StringType> extensions;

  for (const auto& accept_type : accept_types) {
    std::string ascii_type = base::UTF16ToASCII(accept_type);
    if (ascii_type[0] == '.') {
      // If the type starts with a period it is assumed to be a file extension,
      // like `.txt`, // so we just have to add it to the list.
      base::FilePath::StringType extension(
          ascii_type.begin(), ascii_type.end());
      // Skip the first character.
      extensions.push_back(extension.substr(1));
    } else {
      // For MIME Type, `audio/*, vidio/*, image/*
      net::GetExtensionsForMimeType(ascii_type, &extensions);
    }
  }

  // If no valid exntesion is added, return empty filters.
  if (extensions.empty())
    return filters;

  filters.push_back(file_dialog::Filter());
  for (const auto& extension : extensions) {
#if defined(OS_WIN)
    filters[0].second.push_back(base::UTF16ToASCII(extension));
#else
    filters[0].second.push_back(extension);
#endif
  }
  return filters;
}

}  // namespace

namespace atom {

WebDialogHelper::WebDialogHelper(NativeWindow* window)
    : window_(window),
      weak_factory_(this) {
}

WebDialogHelper::~WebDialogHelper() {
}

void WebDialogHelper::RunFileChooser(
    content::RenderFrameHost* render_frame_host,
    const content::FileChooserParams& params) {
  std::vector<content::FileChooserFileInfo> result;

  file_dialog::DialogSettings settings;
  settings.filters = GetFileTypesFromAcceptType(params.accept_types);
  settings.parent_window = window_;
  settings.title = base::UTF16ToUTF8(params.title);

  scoped_refptr<FileSelectHelper> file_select_helper(
      new FileSelectHelper(render_frame_host, params.mode));
  if (params.mode == content::FileChooserParams::Save) {
    settings.default_path = params.default_file_name;
    file_select_helper->ShowSaveDialog(settings);
  } else {
    int flags = file_dialog::FILE_DIALOG_CREATE_DIRECTORY;
    switch (params.mode) {
      case content::FileChooserParams::OpenMultiple:
        flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS;
      case content::FileChooserParams::Open:
        flags |= file_dialog::FILE_DIALOG_OPEN_FILE;
        break;
      case content::FileChooserParams::UploadFolder:
        flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
        break;
      default:
        NOTREACHED();
    }

    AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
        window_->web_contents()->GetBrowserContext());
    settings.default_path = browser_context->prefs()->GetFilePath(
        prefs::kSelectFileLastDirectory).Append(params.default_file_name);
    settings.properties = flags;
    file_select_helper->ShowOpenDialog(settings);
  }
}

void WebDialogHelper::EnumerateDirectory(content::WebContents* web_contents,
                                         int request_id,
                                         const base::FilePath& dir) {
  int types = base::FileEnumerator::FILES |
              base::FileEnumerator::DIRECTORIES |
              base::FileEnumerator::INCLUDE_DOT_DOT;
  base::FileEnumerator file_enum(dir, false, types);

  base::FilePath path;
  std::vector<base::FilePath> paths;
  while (!(path = file_enum.Next()).empty())
    paths.push_back(path);

  web_contents->GetRenderViewHost()->DirectoryEnumerationFinished(
      request_id, paths);
}

}  // namespace atom
<|endoftext|>


<commit_before><commit_msg>fix: #81757# SvxCrossedOutItem putted correctly<commit_after><|endoftext|>


<commit_before>// Ignore unused parameter warnings coming from cppunit headers
#include <libmesh/ignore_warnings.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <libmesh/restore_warnings.h>

#include <libmesh/libmesh.h>
#include <libmesh/mesh.h>
#include <libmesh/elem.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/mesh_refinement.h>

#include "test_comm.h"

// THE CPPUNIT_TEST_SUITE_END macro expands to code that involves
// std::auto_ptr, which in turn produces -Wdeprecated-declarations
// warnings.  These can be ignored in GCC as long as we wrap the
// offending code in appropriate pragmas.  We can't get away with a
// single ignore_warnings.h inclusion at the beginning of this file,
// since the libmesh headers pull in a restore_warnings.h at some
// point.  We also don't bother restoring warnings at the end of this
// file since it's not a header.
#include <libmesh/ignore_warnings.h>

using namespace libMesh;

class ExtraIntegersTest : public CppUnit::TestCase
{
  /**
   * The goal of this test is to verify the ability to add extra
   * integer storage to a Mesh object, then set and query those extra
   * integers in the objects within the mesh.
   */
public:
  CPPUNIT_TEST_SUITE( ExtraIntegersTest );

  CPPUNIT_TEST( testExtraIntegersEdge2 );

  CPPUNIT_TEST_SUITE_END();

protected:
  // Helper function called by the test implementations, saves a few lines of code.
  void test_helper_1D(ElemType elem_type)
  {
    Mesh mesh(*TestCommWorld, /*dim=*/2);

    // Request some extra integers before building
    unsigned int i1 = mesh.add_elem_integer("i1");
    unsigned int ni1 = mesh.add_node_integer("ni1");
    unsigned int ni2 = mesh.add_node_integer("ni2");

    MeshTools::Generation::build_line(mesh,
                                      /*nx=*/10,
                                      /*xmin=*/0., /*xmax=*/1.,
                                      elem_type);

    for (const auto & elem : mesh.element_ptr_range())
      {
        CPPUNIT_ASSERT_EQUAL(elem->n_extra_integers(), 1u);
        CPPUNIT_ASSERT_EQUAL(elem->get_extra_integer(i1), DofObject::invalid_id);
        elem->set_extra_integer(i1, dof_id_type(elem->point(0)(0)*100));
        CPPUNIT_ASSERT_EQUAL(elem->get_extra_integer(i1), dof_id_type(elem->point(0)(0)*100));
      }

    for (const auto & node : mesh.node_ptr_range())
      {
        CPPUNIT_ASSERT_EQUAL(node->n_extra_integers(), 2u);
        CPPUNIT_ASSERT_EQUAL(node->get_extra_integer(ni1), DofObject::invalid_id);
        CPPUNIT_ASSERT_EQUAL(node->get_extra_integer(ni2), DofObject::invalid_id);
      }

    // Force (in parallel) a different partitioning - we'll simply put
    // everything on rank 0, which hopefully is not what our default
    // partitioner did!
    mesh.partition(1);

    CPPUNIT_ASSERT_EQUAL(i1, mesh.add_elem_integer("i1"));
    CPPUNIT_ASSERT_EQUAL(ni1, mesh.add_node_integer("ni1"));
    CPPUNIT_ASSERT_EQUAL(ni2, mesh.add_node_integer("ni2"));

    // Make sure we didn't screw up any extra integers thereby.
    for (const auto & elem : mesh.element_ptr_range())
      {
        CPPUNIT_ASSERT_EQUAL(elem->n_extra_integers(), 1u);
        CPPUNIT_ASSERT_EQUAL(elem->get_extra_integer(i1), dof_id_type(elem->point(0)(0)*100));
      }

    for (const auto & node : mesh.node_ptr_range())
      {
        CPPUNIT_ASSERT_EQUAL(node->n_extra_integers(), 2u);
        CPPUNIT_ASSERT_EQUAL(node->get_extra_integer(ni1), DofObject::invalid_id);
        CPPUNIT_ASSERT_EQUAL(node->get_extra_integer(ni2), DofObject::invalid_id);
      }

#ifdef LIBMESH_ENABLE_AMR
    MeshRefinement mr(mesh);
    mr.uniformly_refine(1);

    // Make sure the old elements have the same integers and the new
    // elements have be initialized as undefined.
    for (const auto & elem : mesh.element_ptr_range())
      {
        CPPUNIT_ASSERT_EQUAL(elem->n_extra_integers(), 1u);
        CPPUNIT_ASSERT_EQUAL(elem->get_extra_integer(i1), dof_id_type(elem->top_parent()->point(0)(0)*100));
        if (!elem->level())
          for (auto & node : elem->node_ref_range())
            CPPUNIT_ASSERT_EQUAL(node.n_extra_integers(), 2u);
      }
#endif
  }

public:
  void setUp() {}

  void tearDown() {}

  void testExtraIntegersEdge2() { test_helper_1D(EDGE2); }
};

CPPUNIT_TEST_SUITE_REGISTRATION( ExtraIntegersTest );
<commit_msg>Refactor extra_integer tests, add checkpointing<commit_after>// Ignore unused parameter warnings coming from cppunit headers
#include <libmesh/ignore_warnings.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <libmesh/restore_warnings.h>

#include <libmesh/libmesh.h>
#include <libmesh/mesh.h>
#include <libmesh/elem.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/mesh_refinement.h>

#include "test_comm.h"

// THE CPPUNIT_TEST_SUITE_END macro expands to code that involves
// std::auto_ptr, which in turn produces -Wdeprecated-declarations
// warnings.  These can be ignored in GCC as long as we wrap the
// offending code in appropriate pragmas.  We can't get away with a
// single ignore_warnings.h inclusion at the beginning of this file,
// since the libmesh headers pull in a restore_warnings.h at some
// point.  We also don't bother restoring warnings at the end of this
// file since it's not a header.
#include <libmesh/ignore_warnings.h>

using namespace libMesh;

class ExtraIntegersTest : public CppUnit::TestCase
{
  /**
   * The goal of this test is to verify the ability to add extra
   * integer storage to a Mesh object, then set and query those extra
   * integers in the objects within the mesh.
   */
public:
  CPPUNIT_TEST_SUITE( ExtraIntegersTest );

  CPPUNIT_TEST( testExtraIntegersEdge2 );

  CPPUNIT_TEST( testExtraIntegersTri6 );

  CPPUNIT_TEST( testExtraIntegersCheckpointEdge3 );

  CPPUNIT_TEST( testExtraIntegersCheckpointHex8 );

  CPPUNIT_TEST_SUITE_END();

protected:
  // Helper functions called by the test implementations, saves a few lines of code.
  std::array<unsigned int, 3>
    build_mesh(Mesh & mesh, ElemType elem_type, unsigned int n_elem_per_side)
  {
    // Request some extra integers before building
    unsigned int i1 = mesh.add_elem_integer("i1");
    unsigned int ni1 = mesh.add_node_integer("ni1");
    unsigned int ni2 = mesh.add_node_integer("ni2");

    const std::unique_ptr<Elem> test_elem = Elem::build(elem_type);
    const unsigned int ymax = test_elem->dim() > 1;
    const unsigned int zmax = test_elem->dim() > 2;
    const unsigned int ny = ymax * n_elem_per_side;
    const unsigned int nz = zmax * n_elem_per_side;

    MeshTools::Generation::build_cube (mesh,
                                       n_elem_per_side,
                                       ny,
                                       nz,
                                       0., 1.,
                                       0., ymax,
                                       0., zmax,
                                       elem_type);
    return {i1, ni1, ni2};
  }

  void test_and_set_initial_integers
    (Mesh & mesh, unsigned int i1, unsigned int ni1, unsigned int ni2)
  {
    for (const auto & elem : mesh.element_ptr_range())
      {
        CPPUNIT_ASSERT_EQUAL(elem->n_extra_integers(), 1u);
        CPPUNIT_ASSERT_EQUAL(elem->get_extra_integer(i1), DofObject::invalid_id);
        elem->set_extra_integer(i1, dof_id_type(elem->point(0)(0)*100));
        CPPUNIT_ASSERT_EQUAL(elem->get_extra_integer(i1), dof_id_type(elem->point(0)(0)*100));
      }

    for (const auto & node : mesh.node_ptr_range())
      {
        CPPUNIT_ASSERT_EQUAL(node->n_extra_integers(), 2u);
        CPPUNIT_ASSERT_EQUAL(node->get_extra_integer(ni1), DofObject::invalid_id);
        CPPUNIT_ASSERT_EQUAL(node->get_extra_integer(ni2), DofObject::invalid_id);
      }

  }

  void test_final_integers(Mesh & mesh, unsigned int i1)
  {
    // Make sure old (level 0) elements have the same integers and any new
    // elements have inherited their ancestors' settings
    for (const auto & elem : mesh.element_ptr_range())
      {
        const Elem * top_parent = elem;
#ifdef LIBMESH_ENABLE_AMR
        top_parent = elem->top_parent();

        if (!elem->level())
#endif
          for (auto & node : elem->node_ref_range())
            CPPUNIT_ASSERT_EQUAL(node.n_extra_integers(), 2u);

        CPPUNIT_ASSERT_EQUAL(elem->n_extra_integers(), 1u);
        CPPUNIT_ASSERT_EQUAL(elem->get_extra_integer(i1), dof_id_type(top_parent->point(0)(0)*100));
      }
  }

  void test_helper(ElemType elem_type, unsigned int n_elem_per_side)
  {
    Mesh mesh(*TestCommWorld);

    std::array<unsigned int, 3> ini = build_mesh(mesh, elem_type, n_elem_per_side);
    const unsigned int i1 = ini[0], ni1 = ini[1], ni2 = ini[2];

    test_and_set_initial_integers(mesh, i1, ni1, ni2);

    // Force (in parallel) a different partitioning - we'll simply put
    // everything on rank 0, which hopefully is not what our default
    // partitioner did!
    mesh.partition(1);

    CPPUNIT_ASSERT_EQUAL(i1, mesh.add_elem_integer("i1"));
    CPPUNIT_ASSERT_EQUAL(ni1, mesh.add_node_integer("ni1"));
    CPPUNIT_ASSERT_EQUAL(ni2, mesh.add_node_integer("ni2"));

    // Make sure we didn't screw up any extra integers thereby.
    test_final_integers(mesh, i1);

#ifdef LIBMESH_ENABLE_AMR
    MeshRefinement mr(mesh);
    mr.uniformly_refine(1);

    test_final_integers(mesh, i1);
#endif
  }

  void checkpoint_helper(ElemType elem_type, unsigned int n_elem_per_side, bool binary)
  {
    Mesh mesh(*TestCommWorld);

    std::array<unsigned int, 3> ini = build_mesh(mesh, elem_type, n_elem_per_side);
    const unsigned int i1 = ini[0], ni1 = ini[1], ni2 = ini[2];

    test_and_set_initial_integers(mesh, i1, ni1, ni2);

    const std::string filename =
      std::string("extra_integers.cp") + (binary ? "r" : "a");

    mesh.write(filename);

    TestCommWorld->barrier();

    Mesh mesh2(*TestCommWorld);

    mesh2.read(filename);

    // Make sure everything got transferred to the second mesh
    CPPUNIT_ASSERT_EQUAL(i1, mesh2.add_elem_integer("i1"));
    CPPUNIT_ASSERT_EQUAL(ni1, mesh2.add_node_integer("ni1"));
    CPPUNIT_ASSERT_EQUAL(ni2, mesh2.add_node_integer("ni2"));

    // Make sure we didn't screw up any extra integers thereby.
    test_final_integers(mesh2, i1);
  }

public:
  void setUp() {}

  void tearDown() {}

  void testExtraIntegersEdge2() { test_helper(EDGE2, 5); }

  void testExtraIntegersTri6() { test_helper(TRI6, 4); }

  void testExtraIntegersCheckpointEdge3() { checkpoint_helper(EDGE3, 5, false); }

  void testExtraIntegersCheckpointHex8() { checkpoint_helper(HEX8, 2, true); }

};

CPPUNIT_TEST_SUITE_REGISTRATION( ExtraIntegersTest );
<|endoftext|>


<commit_before><commit_msg>#i101242# release options helper on last page<commit_after><|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <algorithm>
using std::max;

#include "test_common.h"

/* Purpose: to figure out how to proxy a TCP connection
 *          using raw sockets.
 */

const short LISTEN_PORT = 4210;

typedef void * (*thread_func)(void*);

//static pthread_mutex_t proxy_lock = PTHREAD_MUTEX_INITIALIZER;
//static pthread_cond_t proxy_cv = PTHREAD_COND_INITIALIZER;
static bool running = true;

/* from_sock and to_sock are both raw sockets. */
static int proxy_data(int from_sock, int to_sock, void (*line_proc)(char *))
{
    char buf[4096];
    int rc = read(from_sock, buf, sizeof(buf) - 1);
    if (rc > 0) {
        buf[rc] = '\0';
        if (line_proc) {
            line_proc(buf);
        }
        int bytes_written = write(to_sock, buf, rc);
        if (bytes_written != rc) {
            perror("proxy_data: write");
        }
        rc = bytes_written;
    } else if (rc == 0) {
        fprintf(stderr, "proxy_data: socket closed\n");
    } else {
        perror("proxy_data: read");
    }
    return rc;
}

// only proxy a given number of lines before simulating disconnection.
static void proxy_lines_until_closed(int client_fd, int server_fd,
                                     void (*line_proc)(char *),
                                     int num_lines_before_break)
{
    fd_set readable;
    FD_ZERO(&readable);
    FD_SET(client_fd, &readable);
    FD_SET(server_fd, &readable);
    int nfds = max(client_fd, server_fd) + 1;

    int num_lines = 0;

    while (running) {
        int rc = select(nfds, &readable, NULL, NULL, NULL);
        if (num_lines >= num_lines_before_break) {
            // silently drop it
            continue;
        }
        if (rc > 0) {
            if (FD_ISSET(client_fd, &readable)) {
                rc = proxy_data(client_fd, server_fd, line_proc);
                num_lines++;
                if (rc > 0) {
                    FD_SET(client_fd, &readable);
                }
            }
            if (FD_ISSET(server_fd, &readable)) {
                rc = proxy_data(server_fd, client_fd, line_proc);
                num_lines++;
                if (rc > 0) {
                    FD_SET(client_fd, &readable);
                }
            }
            if (!FD_ISSET(client_fd, &readable) &&
                !FD_ISSET(server_fd, &readable)) {
                fprintf(stderr, "client and server proxy sockets closed; proxy thread exiting.\n");
                break;
            }
        } else {
            perror("select");
            break;
        }
    }
}

void ProxyThread(void *unused)
{
    int client_proxy_listen_sock = make_listening_socket(LISTEN_PORT);
    assert(client_proxy_listen_sock >= 0);

    int client_proxy_sock =  accept(client_proxy_listen_sock, NULL, NULL);
    handle_error(client_proxy_sock < 0, "accepting proxy socket");

    int server_proxy_sock = socket(PF_INET, SOCK_STREAM, 0);
    handle_error(server_proxy_sock < 0, "creating client proxy socket");

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(LISTEN_PORT + 1);
    socklen_t addrlen = sizeof(addr);
    int rc = connect(server_proxy_sock, (struct sockaddr *) &addr, addrlen);
    handle_error(rc < 0, "connecting server proxy socket");

    proxy_lines_until_closed(client_proxy_sock, server_proxy_sock, NULL, 5);

    close(server_proxy_sock);
    close(client_proxy_sock);
    close(client_proxy_listen_sock);
}

void ServerThread(int listen_sock)
{
    int sock = accept(listen_sock, NULL, NULL);
    handle_error(sock < 0, "accepting socket at server");

    char buf[4096];
    int rc;
    while ((rc = read(sock, buf, sizeof(buf) - 1)) > 0) {
        int bytes = rc;
        for (int i = 0; i < rc; ++i) {
            buf[i] = toupper(buf[i]);
        }
        rc = write(sock, buf, bytes);
        if (bytes != rc) {
            break;
        }
    }
    close(sock);
}

int main()
{
    int listen_sock = make_listening_socket(LISTEN_PORT + 1);
    assert(listen_sock >= 0);

    pthread_t server_thread, proxy_thread;
    pthread_create(&server_thread, NULL, (thread_func) ServerThread, (void *) listen_sock);
    pthread_create(&proxy_thread, NULL, (thread_func) ProxyThread, NULL);

    int client_sock = socket(PF_INET, SOCK_STREAM, 0);
    handle_error(client_sock < 0, "socket");

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(LISTEN_PORT);
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    int rc = connect(client_sock, (struct sockaddr *) &addr, (socklen_t) sizeof(addr));
    handle_error(rc < 0, "connecting client socket");

    proxy_lines_until_closed(STDIN_FILENO, client_sock, NULL, -1);
    close(client_sock);

    pthread_join(proxy_thread, NULL);
    pthread_join(server_thread, NULL);

    return 0;
}
<commit_msg>Got proxy code working.<commit_after>#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <algorithm>
using std::max;

#include "test_common.h"

/* Purpose: to figure out how to proxy a TCP connection
 *          using raw sockets.
 */

const short LISTEN_PORT = 4210;

typedef void * (*thread_func)(void*);

static pthread_mutex_t proxy_started_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t proxy_started_cv = PTHREAD_COND_INITIALIZER;
static bool running = true;

/* from_sock and to_sock are both raw sockets. */
static int proxy_data(int from_sock, int to_sock, void (*line_proc)(char *))
{
    char buf[4096];
    int rc = read(from_sock, buf, sizeof(buf) - 1);
    if (rc > 0) {
        buf[rc] = '\0';
        if (line_proc) {
            line_proc(buf);
        }
        int bytes_written = write(to_sock, buf, rc);
        if (bytes_written != rc) {
            perror("proxy_data: write");
        }
        rc = bytes_written;
    } else if (rc == 0) {
        fprintf(stderr, "proxy_data: socket closed\n");
    } else {
        perror("proxy_data: read");
    }
    return rc;
}

// only proxy a given number of lines before simulating disconnection.
static void proxy_lines_until_closed(int client_fd, int server_fd,
                                     void (*line_proc)(char *),
                                     int num_lines_before_break)
{
    fd_set readable;
    FD_ZERO(&readable);
    FD_SET(client_fd, &readable);
    FD_SET(server_fd, &readable);
    int nfds = max(client_fd, server_fd) + 1;

    int num_lines = 0;

    while (running) {
        int rc = select(nfds, &readable, NULL, NULL, NULL);
        if (num_lines_before_break >= 0 &&
            num_lines >= num_lines_before_break) {
            // silently drop it
            continue;
        }
        if (rc > 0) {
            if (FD_ISSET(client_fd, &readable)) {
                rc = proxy_data(client_fd, server_fd, line_proc);
                num_lines++;
                if (rc > 0) {
                    FD_SET(client_fd, &readable);
                }
            }
            if (FD_ISSET(server_fd, &readable)) {
                rc = proxy_data(server_fd, client_fd, line_proc);
                num_lines++;
                if (rc > 0) {
                    FD_SET(client_fd, &readable);
                }
            }
            if (!FD_ISSET(client_fd, &readable) &&
                !FD_ISSET(server_fd, &readable)) {
                fprintf(stderr, "client and server proxy sockets closed; proxy thread exiting.\n");
                break;
            }
        } else {
            perror("select");
            break;
        }
    }
}

static void print_line(char *line)
{
    fprintf(stderr, "proxy'd line: %s", line);
}

void ProxyThread(void *unused)
{
    int client_proxy_listen_sock = make_listening_socket(LISTEN_PORT);
    assert(client_proxy_listen_sock >= 0);

    pthread_mutex_lock(&proxy_started_lock);
    pthread_cond_signal(&proxy_started_cv);
    pthread_mutex_unlock(&proxy_started_lock);

    int client_proxy_sock =  accept(client_proxy_listen_sock, NULL, NULL);
    handle_error(client_proxy_sock < 0, "accepting proxy socket");

    int server_proxy_sock = socket(PF_INET, SOCK_STREAM, 0);
    handle_error(server_proxy_sock < 0, "creating client proxy socket");

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(LISTEN_PORT + 1);
    socklen_t addrlen = sizeof(addr);
    int rc = connect(server_proxy_sock, (struct sockaddr *) &addr, addrlen);
    handle_error(rc < 0, "connecting server proxy socket");

    proxy_lines_until_closed(client_proxy_sock, server_proxy_sock, print_line, 5);

    close(server_proxy_sock);
    close(client_proxy_sock);
    close(client_proxy_listen_sock);
}

void ServerThread(int listen_sock)
{
    int sock = accept(listen_sock, NULL, NULL);
    handle_error(sock < 0, "accepting socket at server");

    char buf[4096];
    int rc;
    while ((rc = read(sock, buf, sizeof(buf) - 1)) > 0) {
        int bytes = rc;
        for (int i = 0; i < rc; ++i) {
            buf[i] = toupper(buf[i]);
        }
        rc = write(sock, buf, bytes);
        if (bytes != rc) {
            break;
        }
    }
    close(sock);
}

int main()
{
    int listen_sock = make_listening_socket(LISTEN_PORT + 1);
    assert(listen_sock >= 0);

    pthread_t server_thread, proxy_thread;
    pthread_create(&server_thread, NULL, (thread_func) ServerThread, (void *) listen_sock);

    pthread_mutex_lock(&proxy_started_lock);
    pthread_create(&proxy_thread, NULL, (thread_func) ProxyThread, NULL);
    pthread_cond_wait(&proxy_started_cv, &proxy_started_lock);
    pthread_mutex_unlock(&proxy_started_lock);

    int client_sock = socket(PF_INET, SOCK_STREAM, 0);
    handle_error(client_sock < 0, "socket");

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(LISTEN_PORT);
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    int rc = connect(client_sock, (struct sockaddr *) &addr, (socklen_t) sizeof(addr));
    handle_error(rc < 0, "connecting client socket");

    proxy_lines_until_closed(STDIN_FILENO, client_sock, NULL, -1);
    close(client_sock);

    pthread_join(proxy_thread, NULL);
    pthread_join(server_thread, NULL);

    return 0;
}
<|endoftext|>


<commit_before>/*
  HardwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

  Modified 23 November 2006 by David A. Mellis
  Modified 28 September 2010 by Mark Sproul
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "core_build_options.h"
#include "wiring.h"
#include "wiring_private.h"

// this next line disables the entire HardwareSerial.cpp,
// this is so I can support Attiny series and any other chip without a uart
#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)

#include "HardwareSerial.h"

// Define constants and variables for buffering incoming serial data.  We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read.
#if (RAMEND < 1000)
  #define RX_BUFFER_SIZE 32
#else
  #define RX_BUFFER_SIZE 128
#endif

struct ring_buffer
{
  unsigned char buffer[RX_BUFFER_SIZE];
  int head;
  int tail;
};

#if defined(UBRRH) || defined(UBRR0H)
  ring_buffer rx_buffer  =  { { 0 }, 0, 0 };
#endif
#if defined(UBRR1H)
  ring_buffer rx_buffer1  =  { { 0 }, 0, 0 };
#endif
#if defined(UBRR2H)
  ring_buffer rx_buffer2  =  { { 0 }, 0, 0 };
#endif
#if defined(UBRR3H)
  ring_buffer rx_buffer3  =  { { 0 }, 0, 0 };
#endif

inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
  int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE;

  // if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != rx_buffer->tail) {
    rx_buffer->buffer[rx_buffer->head] = c;
    rx_buffer->head = i;
  }
}

#if defined(USART_RX_vect)
  ISR(USART_RX_vect)
  {
  #if defined(UDR0)
    unsigned char c  =  UDR0;
  #elif defined(UDR)
    unsigned char c  =  UDR;  //  atmega8535
  #else
    #error UDR not defined
  #endif
    store_char(c, &rx_buffer);
  }
#elif defined(USART0_RECV_vect) && defined(UDR0)
  ISR(USART0_RECV_vect)
  {
    unsigned char c  =  UDR0;
    store_char(c, &rx_buffer);
  }
#elif defined(UART0_RECV_vect) && defined(UDR0)
  ISR(UART0_RECV_vect)
  {
    unsigned char c  =  UDR0;
    store_char(c, &rx_buffer);
  }
//#elif defined(SIG_USART_RECV)
#elif defined(USART0_RX_vect)
  // fixed by Mark Sproul this is on the 644/644p
  //ISR(SIG_USART_RECV)
  ISR(USART0_RX_vect)
  {
  #if defined(UDR0)
    unsigned char c  =  UDR0;
  #elif defined(UDR)
    unsigned char c  =  UDR;  //  atmega8, atmega32
  #else
    #error UDR not defined
  #endif
    store_char(c, &rx_buffer);
  }
#elif defined(UART_RECV_vect)
  // this is for atmega8
  ISR(UART_RECV_vect)
  {
  #if defined(UDR0)
    unsigned char c  =  UDR0;  //  atmega645
  #elif defined(UDR)
    unsigned char c  =  UDR;  //  atmega8
  #endif
    store_char(c, &rx_buffer);
  }
#elif defined(USBCON)
  #warning No interrupt handler for usart 0
  #warning Serial(0) is on USB interface
#else
  #error No interrupt handler for usart 0
#endif

//#if defined(SIG_USART1_RECV)
#if defined(USART1_RX_vect)
  //ISR(SIG_USART1_RECV)
  ISR(USART1_RX_vect)
  {
    unsigned char c = UDR1;
    store_char(c, &rx_buffer1);
  }
#endif

#if defined(USART2_RX_vect) && defined(UDR2)
  ISR(USART2_RX_vect)
  {
    unsigned char c = UDR2;
    store_char(c, &rx_buffer2);
  }
#endif

#if defined(USART3_RX_vect) && defined(UDR3)
  ISR(USART3_RX_vect)
  {
    unsigned char c = UDR3;
    store_char(c, &rx_buffer3);
  }
#endif

// Constructors ////////////////////////////////////////////////////////////////

HardwareSerial::HardwareSerial(ring_buffer *rx_buffer,
  volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
  volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
  volatile uint8_t *udr,
  uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre, uint8_t u2x)
{
  _rx_buffer = rx_buffer;
  _ubrrh = ubrrh;
  _ubrrl = ubrrl;
  _ucsra = ucsra;
  _ucsrb = ucsrb;
  _udr = udr;
  _rxen = rxen;
  _txen = txen;
  _rxcie = rxcie;
  _udre = udre;
  _u2x = u2x;
}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(long baud)
{
  uint16_t baud_setting;
  bool use_u2x = true;

#if F_CPU == 16000000UL
  // hardcoded exception for compatibility with the bootloader shipped
  // with the Duemilanove and previous boards and the firmware on the 8U2
  // on the Uno and Mega 2560.
  if (baud == 57600) {
    use_u2x = false;
  }
#endif

  if (use_u2x) {
    *_ucsra = 1 << _u2x;
    baud_setting = (F_CPU / 4 / baud - 1) / 2;
  } else {
    *_ucsra = 0;
    baud_setting = (F_CPU / 8 / baud - 1) / 2;
  }

  // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
  *_ubrrh = baud_setting >> 8;
  *_ubrrl = baud_setting;

  sbi(*_ucsrb, _rxen);
  sbi(*_ucsrb, _txen);
  sbi(*_ucsrb, _rxcie);
}

void HardwareSerial::end()
{
  cbi(*_ucsrb, _rxen);
  cbi(*_ucsrb, _txen);
  cbi(*_ucsrb, _rxcie);
}

int HardwareSerial::available(void)
{
  return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
}

int HardwareSerial::peek(void)
{
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    return _rx_buffer->buffer[_rx_buffer->tail];
  }
}

int HardwareSerial::read(void)
{
  // if the head isn't ahead of the tail, we don't have any characters
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
    _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % RX_BUFFER_SIZE;
    return c;
  }
}

void HardwareSerial::flush()
{
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // were full, not empty.
  _rx_buffer->head = _rx_buffer->tail;
}

size_t HardwareSerial::write(uint8_t c)
{
  while (!((*_ucsra) & (1 << _udre)))
    ;

  *_udr = c;

  return( 1 );
}

// Preinstantiate Objects //////////////////////////////////////////////////////

#if ! DEFAULT_TO_TINY_DEBUG_SERIAL
  #if defined(UBRRH) && defined(UBRRL)
    HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE, U2X);
  #elif defined(UBRR0H) && defined(UBRR0L)
    HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0, U2X0);
  #elif defined(USBCON)
    #warning no serial port defined  (port 0)
  #else
    #error no serial port defined  (port 0)
  #endif
#endif

#if defined(UBRR1H)
  HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1);
#endif
#if defined(UBRR2H)
  HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2, U2X2);
#endif
#if defined(UBRR3H)
  HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3, U2X3);
#endif

#endif // whole file
<commit_msg>Reduce size of 1634's serial buffer<commit_after>/*
  HardwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

  Modified 23 November 2006 by David A. Mellis
  Modified 28 September 2010 by Mark Sproul
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "core_build_options.h"
#include "wiring.h"
#include "wiring_private.h"

// this next line disables the entire HardwareSerial.cpp,
// this is so I can support Attiny series and any other chip without a uart
#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)

#include "HardwareSerial.h"

// Define constants and variables for buffering incoming serial data.  We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read.
#if (RAMEND < 1000)
  #define RX_BUFFER_SIZE 32
#else
  #define RX_BUFFER_SIZE 64
#endif

struct ring_buffer
{
  unsigned char buffer[RX_BUFFER_SIZE];
  int head;
  int tail;
};

#if defined(UBRRH) || defined(UBRR0H)
  ring_buffer rx_buffer  =  { { 0 }, 0, 0 };
#endif
#if defined(UBRR1H)
  ring_buffer rx_buffer1  =  { { 0 }, 0, 0 };
#endif
#if defined(UBRR2H)
  ring_buffer rx_buffer2  =  { { 0 }, 0, 0 };
#endif
#if defined(UBRR3H)
  ring_buffer rx_buffer3  =  { { 0 }, 0, 0 };
#endif

inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
  int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE;

  // if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != rx_buffer->tail) {
    rx_buffer->buffer[rx_buffer->head] = c;
    rx_buffer->head = i;
  }
}

#if defined(USART_RX_vect)
  ISR(USART_RX_vect)
  {
  #if defined(UDR0)
    unsigned char c  =  UDR0;
  #elif defined(UDR)
    unsigned char c  =  UDR;  //  atmega8535
  #else
    #error UDR not defined
  #endif
    store_char(c, &rx_buffer);
  }
#elif defined(USART0_RECV_vect) && defined(UDR0)
  ISR(USART0_RECV_vect)
  {
    unsigned char c  =  UDR0;
    store_char(c, &rx_buffer);
  }
#elif defined(UART0_RECV_vect) && defined(UDR0)
  ISR(UART0_RECV_vect)
  {
    unsigned char c  =  UDR0;
    store_char(c, &rx_buffer);
  }
//#elif defined(SIG_USART_RECV)
#elif defined(USART0_RX_vect)
  // fixed by Mark Sproul this is on the 644/644p
  //ISR(SIG_USART_RECV)
  ISR(USART0_RX_vect)
  {
  #if defined(UDR0)
    unsigned char c  =  UDR0;
  #elif defined(UDR)
    unsigned char c  =  UDR;  //  atmega8, atmega32
  #else
    #error UDR not defined
  #endif
    store_char(c, &rx_buffer);
  }
#elif defined(UART_RECV_vect)
  // this is for atmega8
  ISR(UART_RECV_vect)
  {
  #if defined(UDR0)
    unsigned char c  =  UDR0;  //  atmega645
  #elif defined(UDR)
    unsigned char c  =  UDR;  //  atmega8
  #endif
    store_char(c, &rx_buffer);
  }
#elif defined(USBCON)
  #warning No interrupt handler for usart 0
  #warning Serial(0) is on USB interface
#else
  #error No interrupt handler for usart 0
#endif

//#if defined(SIG_USART1_RECV)
#if defined(USART1_RX_vect)
  //ISR(SIG_USART1_RECV)
  ISR(USART1_RX_vect)
  {
    unsigned char c = UDR1;
    store_char(c, &rx_buffer1);
  }
#endif

#if defined(USART2_RX_vect) && defined(UDR2)
  ISR(USART2_RX_vect)
  {
    unsigned char c = UDR2;
    store_char(c, &rx_buffer2);
  }
#endif

#if defined(USART3_RX_vect) && defined(UDR3)
  ISR(USART3_RX_vect)
  {
    unsigned char c = UDR3;
    store_char(c, &rx_buffer3);
  }
#endif

// Constructors ////////////////////////////////////////////////////////////////

HardwareSerial::HardwareSerial(ring_buffer *rx_buffer,
  volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
  volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
  volatile uint8_t *udr,
  uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre, uint8_t u2x)
{
  _rx_buffer = rx_buffer;
  _ubrrh = ubrrh;
  _ubrrl = ubrrl;
  _ucsra = ucsra;
  _ucsrb = ucsrb;
  _udr = udr;
  _rxen = rxen;
  _txen = txen;
  _rxcie = rxcie;
  _udre = udre;
  _u2x = u2x;
}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(long baud)
{
  uint16_t baud_setting;
  bool use_u2x = true;

#if F_CPU == 16000000UL
  // hardcoded exception for compatibility with the bootloader shipped
  // with the Duemilanove and previous boards and the firmware on the 8U2
  // on the Uno and Mega 2560.
  if (baud == 57600) {
    use_u2x = false;
  }
#endif

  if (use_u2x) {
    *_ucsra = 1 << _u2x;
    baud_setting = (F_CPU / 4 / baud - 1) / 2;
  } else {
    *_ucsra = 0;
    baud_setting = (F_CPU / 8 / baud - 1) / 2;
  }

  // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
  *_ubrrh = baud_setting >> 8;
  *_ubrrl = baud_setting;

  sbi(*_ucsrb, _rxen);
  sbi(*_ucsrb, _txen);
  sbi(*_ucsrb, _rxcie);
}

void HardwareSerial::end()
{
  cbi(*_ucsrb, _rxen);
  cbi(*_ucsrb, _txen);
  cbi(*_ucsrb, _rxcie);
}

int HardwareSerial::available(void)
{
  return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
}

int HardwareSerial::peek(void)
{
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    return _rx_buffer->buffer[_rx_buffer->tail];
  }
}

int HardwareSerial::read(void)
{
  // if the head isn't ahead of the tail, we don't have any characters
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
    _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % RX_BUFFER_SIZE;
    return c;
  }
}

void HardwareSerial::flush()
{
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // were full, not empty.
  _rx_buffer->head = _rx_buffer->tail;
}

size_t HardwareSerial::write(uint8_t c)
{
  while (!((*_ucsra) & (1 << _udre)))
    ;

  *_udr = c;

  return( 1 );
}

// Preinstantiate Objects //////////////////////////////////////////////////////

#if ! DEFAULT_TO_TINY_DEBUG_SERIAL
  #if defined(UBRRH) && defined(UBRRL)
    HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE, U2X);
  #elif defined(UBRR0H) && defined(UBRR0L)
    HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0, U2X0);
  #elif defined(USBCON)
    #warning no serial port defined  (port 0)
  #else
    #error no serial port defined  (port 0)
  #endif
#endif

#if defined(UBRR1H)
  HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1);
#endif
#if defined(UBRR2H)
  HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2, U2X2);
#endif
#if defined(UBRR3H)
  HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3, U2X3);
#endif

#endif // whole file
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: b3dtuple.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: aw $ $Date: 2003-11-28 11:18:14 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _BGFX_TUPLE_B3DTUPLE_HXX
#include <basegfx/tuple/b3dtuple.hxx>
#endif

namespace basegfx
{
    // initialize static member
    ::basegfx::B3DTuple B3DTuple::maEmptyTuple(0.0, 0.0, 0.0);
} // end of namespace basegfx

// eof
<commit_msg>INTEGRATION: CWS tune04 (1.4.26); FILE MERGED 2004/06/15 07:23:36 cmc 1.4.26.1: #i29636# turn global objects into local static data protected with swishy double-locked templated template<commit_after>/*************************************************************************
 *
 *  $RCSfile: b3dtuple.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hjs $ $Date: 2004-06-25 17:19:14 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _BGFX_TUPLE_B3DTUPLE_HXX
#include <basegfx/tuple/b3dtuple.hxx>
#endif
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif

namespace { struct EmptyTuple : public rtl::Static<basegfx::B3DTuple, EmptyTuple> {}; }

namespace basegfx
{
    static const B3DTuple& getEmptyTuple()
    {
        return EmptyTuple::get();
    }
} // end of namespace basegfx

// eof
<|endoftext|>