<commit_before>//=====================================================================//
/*! @file
    @brief  ファースト・サンプル（LED 点滅） @n
			RX64M, RX71M: @n
					12MHz のベースクロックを使用する @n
			　　　　P07 ピンにLEDを接続する @n
			RX65N (Renesas Envision kit RX65N): @n
					12MHz のベースクロックを使用する @n
			　　　　P70 に接続された LED を利用する @n
			RX63T @n
					12MHz のベースクロックを使用する @n
					PB7 に接続された LED を利用する @n
			RX24T: @n
					10MHz のベースクロックを使用する @n
			　　　　P00 ピンにLEDを接続する @n
			RX66T: @n
					10MHz のベースクロックを使用する @n
			　　　　P00 ピンにLEDを接続する
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"
#include "common/fixed_fifo.hpp"
#include "common/sci_io.hpp"
#include "common/format.hpp"
#include "common/cmt_mgr.hpp"
#include "common/vtx.hpp"

// #ifdef TFU
// #define OUT_TPU
#define OUT_MTU

#ifdef OUT_TPU
#include "common/tpu_io.hpp"
#endif

#ifdef OUT_MTU
#include "common/mtu_io.hpp"
#endif

#if 0
extern "C" {
	void __init_tfu(void);
	void __builtin_rx_sincosf(float, float*, float*);
	void __builtin_rx_atan2hypotf(float, float, float*, float*);
	float __builtin_rx_sinf(float);
	float __builtin_rx_cosf(float);
	float __builtin_rx_atan2f(float, float);
	float __builtin_rx_hypotf(float, float);
};
#endif

namespace {

#if defined(SIG_RX71M)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B7> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX71M" };
#elif defined(SIG_RX64M)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B7> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX64M" };
#elif defined(SIG_RX65N)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT7, device::bitpos::B0> LED;
	typedef device::SCI9 SCI_CH;
	static const char* system_str_ = { "RX65N" };
#elif defined(SIG_RX24T)
	typedef device::system_io<10000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B0> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX24T" };
#elif defined(SIG_RX66T)
	typedef device::system_io<10000000, 160000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B0> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX66T" };
#elif defined(SIG_RX72N)
	typedef device::system_io<16'000'000> SYSTEM_IO;
	typedef device::PORT<device::PORT4, device::bitpos::B0> LED;
	typedef device::SCI2 SCI_CH;
	static const char* system_str_ = { "RX72N" };
#endif

	typedef utils::fixed_fifo<char, 512> RXB;  // RX (RECV) バッファの定義
	typedef utils::fixed_fifo<char, 256> TXB;  // TX (SEND) バッファの定義

	typedef device::sci_io<SCI_CH, RXB, TXB> SCI;
// SCI ポートの第二候補を選択する場合
//	typedef device::sci_io<SCI_CH, RXB, TXB, device::port_map::option::SECOND> SCI;
	SCI		sci_;

	typedef device::cmt_mgr<device::CMT0> CMT;
	CMT		cmt_;

#ifdef OUT_TPU
	typedef device::tpu_io<device::TPU4> TPU;
	TPU		tpu_;
#endif

#ifdef OUT_MTU
	typedef device::MTU4 MTU;
	typedef device::mtu_io<MTU> MTU_IO;
	MTU_IO	mtu_io_;
#endif

//	typedef device::PORT<device::PORTD, device::bitpos::B1> PD1;
}

extern "C" {

	// syscalls.c から呼ばれる、標準出力（stdout, stderr）
	void sci_putch(char ch)
	{
		sci_.putch(ch);
	}

	void sci_puts(const char* str)
	{
		sci_.puts(str);
	}

	// syscalls.c から呼ばれる、標準入力（stdin）
	char sci_getch(void)
	{
		return sci_.getch();
	}

	uint16_t sci_length()
	{
		return sci_.recv_length();
	}

}

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

int main(int argc, char** argv)
{
	SYSTEM_IO::setup_system_clock();

	{  // タイマー設定
		uint8_t intr = 4;
		cmt_.start(100, intr);
	}

	{  // SCI の開始
		uint8_t intr = 2;        // 割り込みレベル
		uint32_t baud = 115200;  // ボーレート
		sci_.start(baud, intr);
	}

	auto iclk = F_ICLK / 1000000;
	utils::format("Start test for '%s' %d[MHz]\n") % system_str_ % iclk;

	{
		utils::format("SCI Baud rate (set):  %d\n") % sci_.get_baud_rate();
		float rate = 1.0f - static_cast<float>(sci_.get_baud_rate()) / sci_.get_baud_rate(true);
		rate *= 100.0f;
		utils::format("SCI Baud rate (real): %d (%3.2f [%%])\n") % sci_.get_baud_rate(true) % rate;
		utils::format("CMT rate (set):  %d [Hz]\n") % cmt_.get_rate();
		rate = 1.0f - static_cast<float>(cmt_.get_rate()) / cmt_.get_rate(true);
		rate *= 100.0f;
		utils::format("CMT rate (real): %d [Hz] (%3.2f [%%])\n") % cmt_.get_rate(true) % rate;
	}

	LED::OUTPUT();  // LED ポートを出力に設定

#ifdef TFU
	__init_tfu();
#endif

#ifdef OUT_TPU
	{
		// RX72N Envision Kit Pmod2.8(PD1)
		// MTIOC4B(TPU4,B)
		uint8_t intr = 0;
//		uint32_t freq = 10'000 * 2;  // トグル出力なので２倍
		uint32_t freq = 100;  // トグル出力なので２倍
		if(!tpu_.start(TPU::TYPE::MATCH_B, freq, intr, TPU::OUTPUT::IH_MT)) {
			utils::format("TPU4 not start...\n");
		} else {
			utils::format("TPU rate (set):  %d [Hz]\n") % tpu_.get_rate();
			auto rate = 1.0f - static_cast<float>(tpu_.get_rate()) / tpu_.get_rate(true);
			rate *= 100.0f;
			utils::format("TPU rate (real): %d [Hz] (%3.2f [%%])\n") % tpu_.get_rate(true) % rate;
		}
	}
//	PD1::OUTPUT();
#endif

#ifdef OUT_MTU
	{
		uint32_t freq = 10'000;
		if(!mtu_io_.start_normal(MTU::channel::B, MTU_IO::OUTPUT_TYPE::TOGGLE, freq)) {
			utils::format("MTU4 not start...\n");
		} else {
			utils::format("MTU rate (set):  %d [Hz]\n") % mtu_io_.get_rate();
			auto rate = 1.0f - static_cast<float>(mtu_io_.get_rate()) / mtu_io_.get_rate(true);
			rate *= 100.0f;
			utils::format("MTU rate (real): %d [Hz] (%3.2f [%%])\n")
				% mtu_io_.get_rate(true) % rate;
		}
	}
#endif

	uint8_t cnt = 0;
	while(1) {
		cmt_.sync();

		if(sci_.recv_length() > 0) {
#ifdef TFU
			if(sci_.getch() == ' ') {
				float a = vtx::get_pi<float>() * 0.25f;
				float si, co;
				__builtin_rx_sincosf(a, &si, &co);
				utils::format("%8.7f: %8.7f, %8.7f\n") % a % si % co;
				a = vtx::get_pi<float>() * 1.75f;
				si = __builtin_rx_sinf(a);
				co = __builtin_rx_cosf(a);
				utils::format("%8.7f: %8.7f, %8.7f\n") % a % si % co;
			}
#endif
		}

//		PD1::P = cnt & 1;

		++cnt;
		if(cnt >= 50) {
			cnt = 0;
		}
		if(cnt < 25) {
			LED::P = 0;
		} else {
			LED::P = 1;
		}
	}
}
<commit_msg>Update: MTU4 test<commit_after>//=====================================================================//
/*! @file
    @brief  ファースト・サンプル（LED 点滅） @n
			RX64M, RX71M: @n
					12MHz のベースクロックを使用する @n
			　　　　P07 ピンにLEDを接続する @n
			RX65N (Renesas Envision kit RX65N): @n
					12MHz のベースクロックを使用する @n
			　　　　P70 に接続された LED を利用する @n
			RX63T @n
					12MHz のベースクロックを使用する @n
					PB7 に接続された LED を利用する @n
			RX24T: @n
					10MHz のベースクロックを使用する @n
			　　　　P00 ピンにLEDを接続する @n
			RX66T: @n
					10MHz のベースクロックを使用する @n
			　　　　P00 ピンにLEDを接続する
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"
#include "common/fixed_fifo.hpp"
#include "common/sci_io.hpp"
#include "common/format.hpp"
#include "common/cmt_mgr.hpp"
#include "common/vtx.hpp"
#include "common/command.hpp"
#include "common/input.hpp"

// #ifdef TFU
// #define OUT_TPU
#define OUT_MTU

#ifdef OUT_TPU
#include "common/tpu_io.hpp"
#endif

#ifdef OUT_MTU
#include "common/mtu_io.hpp"
#endif

#if 0
extern "C" {
	void __init_tfu(void);
	void __builtin_rx_sincosf(float, float*, float*);
	void __builtin_rx_atan2hypotf(float, float, float*, float*);
	float __builtin_rx_sinf(float);
	float __builtin_rx_cosf(float);
	float __builtin_rx_atan2f(float, float);
	float __builtin_rx_hypotf(float, float);
};
#endif

namespace {

#if defined(SIG_RX71M)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B7> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX71M" };
#elif defined(SIG_RX64M)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B7> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX64M" };
#elif defined(SIG_RX65N)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT7, device::bitpos::B0> LED;
	typedef device::SCI9 SCI_CH;
	static const char* system_str_ = { "RX65N" };
#elif defined(SIG_RX24T)
	typedef device::system_io<10000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B0> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX24T" };
#elif defined(SIG_RX66T)
	typedef device::system_io<10000000, 160000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B0> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX66T" };
#elif defined(SIG_RX72N)
	typedef device::system_io<16'000'000> SYSTEM_IO;
	typedef device::PORT<device::PORT4, device::bitpos::B0> LED;
	typedef device::SCI2 SCI_CH;
	static const char* system_str_ = { "RX72N" };
#endif

	typedef utils::fixed_fifo<char, 512> RXB;  // RX (RECV) バッファの定義
	typedef utils::fixed_fifo<char, 256> TXB;  // TX (SEND) バッファの定義

	typedef device::sci_io<SCI_CH, RXB, TXB> SCI;
	SCI		sci_;

	typedef device::cmt_mgr<device::CMT0> CMT;
	CMT		cmt_;

#ifdef OUT_TPU
	typedef device::tpu_io<device::TPU4> TPU;
	TPU		tpu_;
#endif

#ifdef OUT_MTU
	typedef device::MTU4 MTU;
	static const auto PSEL = device::port_map_mtu::option::FIFTH;
	typedef device::mtu_io<MTU, utils::null_task, utils::null_task, PSEL> MTU_IO;
	MTU_IO	mtu_io_;
//	typedef device::PORT<device::PORTD, device::bitpos::B1> PD1;
#endif

	typedef utils::command<256> CMD;
	CMD		cmd_;

#ifdef OUT_MTU
	void list_mtu_freq_()
	{
		utils::format("MTU rate (set):  %d [Hz]\n") % mtu_io_.get_rate();
		auto rate = 1.0f - static_cast<float>(mtu_io_.get_rate()) / mtu_io_.get_rate(true);
		rate *= 100.0f;
		utils::format("MTU rate (real): %d [Hz] (%3.2f [%%])\n")
			% mtu_io_.get_rate(true) % rate;
	}
#endif
}

extern "C" {

	// syscalls.c から呼ばれる、標準出力（stdout, stderr）
	void sci_putch(char ch)
	{
		sci_.putch(ch);
	}

	void sci_puts(const char* str)
	{
		sci_.puts(str);
	}

	// syscalls.c から呼ばれる、標準入力（stdin）
	char sci_getch(void)
	{
		return sci_.getch();
	}

	uint16_t sci_length()
	{
		return sci_.recv_length();
	}

}

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

int main(int argc, char** argv)
{
	SYSTEM_IO::setup_system_clock();

	{  // タイマー設定
		uint8_t intr = 4;
		cmt_.start(100, intr);
	}

	{  // SCI の開始
		uint8_t intr = 2;        // 割り込みレベル
		uint32_t baud = 115200;  // ボーレート
		sci_.start(baud, intr);
	}

	auto iclk = F_ICLK / 1000000;
	utils::format("Start test for '%s' %d[MHz]\n") % system_str_ % iclk;

	{
		utils::format("SCI Baud rate (set):  %d\n") % sci_.get_baud_rate();
		float rate = 1.0f - static_cast<float>(sci_.get_baud_rate()) / sci_.get_baud_rate(true);
		rate *= 100.0f;
		utils::format("SCI Baud rate (real): %d (%3.2f [%%])\n") % sci_.get_baud_rate(true) % rate;
		utils::format("CMT rate (set):  %d [Hz]\n") % cmt_.get_rate();
		rate = 1.0f - static_cast<float>(cmt_.get_rate()) / cmt_.get_rate(true);
		rate *= 100.0f;
		utils::format("CMT rate (real): %d [Hz] (%3.2f [%%])\n") % cmt_.get_rate(true) % rate;
	}

	LED::OUTPUT();  // LED ポートを出力に設定

#ifdef TFU
	__init_tfu();
#endif

#ifdef OUT_TPU
	{
		// RX72N Envision Kit Pmod2.8(PD1)
		// MTIOC4B(TPU4,B)
		uint8_t intr = 0;
//		uint32_t freq = 10'000 * 2;  // トグル出力なので２倍
		uint32_t freq = 100;  // トグル出力なので２倍
		if(!tpu_.start(TPU::TYPE::MATCH_B, freq, intr, TPU::OUTPUT::IH_MT)) {
			utils::format("TPU4 not start...\n");
		} else {
			utils::format("TPU rate (set):  %d [Hz]\n") % tpu_.get_rate();
			auto rate = 1.0f - static_cast<float>(tpu_.get_rate()) / tpu_.get_rate(true);
			rate *= 100.0f;
			utils::format("TPU rate (real): %d [Hz] (%3.2f [%%])\n") % tpu_.get_rate(true) % rate;
		}
	}
//	PD1::OUTPUT();
#endif

#ifdef OUT_MTU
	{
		uint32_t freq = 10'000;
		if(!mtu_io_.start_normal(MTU::channel::B, MTU_IO::OUTPUT::TOGGLE, freq)) {
			utils::format("MTU4 not start...\n");
		} else {
			list_mtu_freq_();
		}
	}
#endif

	cmd_.set_prompt("# ");

	uint8_t cnt = 0;
	while(1) {
		cmt_.sync();

#ifdef TFU
		if(sci_.recv_length() > 0) {
			if(sci_.getch() == ' ') {
				float a = vtx::get_pi<float>() * 0.25f;
				float si, co;
				__builtin_rx_sincosf(a, &si, &co);
				utils::format("%8.7f: %8.7f, %8.7f\n") % a % si % co;
				a = vtx::get_pi<float>() * 1.75f;
				si = __builtin_rx_sinf(a);
				co = __builtin_rx_cosf(a);
				utils::format("%8.7f: %8.7f, %8.7f\n") % a % si % co;
			}
		}
#endif

#ifdef OUT_MTU
		if(cmd_.service()) {
			auto cmdn = cmd_.get_words();
			if(cmdn >= 2 && cmd_.cmp_word(0, "freq")) {
				char tmp[32];
				cmd_.get_word(1, tmp, sizeof(tmp));
				int freq = 100;
				if((utils::input("%d", tmp) % freq).status()) {
					if(freq < 100) {
						utils::format("Error Limit under 100[Hz]\n");
					} else {
						mtu_io_.set_freq(freq);
						list_mtu_freq_();
					}
				} else {
					utils::format("input error: '%s'\n") % tmp;
				}
			} else if(cmdn >= 1 && cmd_.cmp_word(0, "help")) {
				utils::format("freq FREQ[Hz]\n");
			} else if(cmdn >= 1) {
				char tmp[32];
				cmd_.get_word(0, tmp, sizeof(tmp));
				utils::format("Command error: '%s'") % tmp;
			}
		}
#endif

//		PD1::P = cnt & 1;

		++cnt;
		if(cnt >= 50) {
			cnt = 0;
		}
		if(cnt < 25) {
			LED::P = 0;
		} else {
			LED::P = 1;
		}
	}
}
<|endoftext|>


<commit_before>//=====================================================================//
/*! @file
    @brief  ファースト・サンプル（LED 点滅） @n
			RX64M, RX71M: @n
					12MHz のベースクロックを使用する @n
			　　　　P07 ピンにLEDを接続する @n
			RX65N (Renesas Envision kit RX65N): @n
					12MHz のベースクロックを使用する @n
			　　　　P70 に接続された LED を利用する @n
			RX63T @n
					12MHz のベースクロックを使用する @n
					PB7 に接続された LED を利用する @n
			RX24T: @n
					10MHz のベースクロックを使用する @n
			　　　　P00 ピンにLEDを接続する @n
			RX66T: @n
					10MHz のベースクロックを使用する @n
			　　　　P00 ピンにLEDを接続する
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"
#include "common/fixed_fifo.hpp"
#include "common/sci_io.hpp"
#include "common/format.hpp"
#include "common/cmt_io.hpp"

#include "common/fixed_string.hpp"

/// #include <iostream>

namespace {

#if defined(SIG_RX71M)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B7> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX71M" };
#elif defined(SIG_RX64M)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B7> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX64M" };
#elif defined(SIG_RX65N)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT7, device::bitpos::B0> LED;
	typedef device::SCI9 SCI_CH;
	static const char* system_str_ = { "RX65N" };
#elif defined(SIG_RX24T)
	typedef device::system_io<10000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B0> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX24T" };
#elif defined(SIG_RX66T)
	typedef device::system_io<10000000, 160000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B0> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX66T" };
#endif

	typedef utils::fixed_fifo<char, 512> RXB;  // RX (RECV) バッファの定義
	typedef utils::fixed_fifo<char, 256> TXB;  // TX (SEND) バッファの定義

	typedef device::sci_io<SCI_CH, RXB, TXB> SCI;
// SCI ポートの第二候補を選択する場合
//	typedef device::sci_io<SCI_CH, RXB, TXB, device::port_map::option::SECOND> SCI;
	SCI		sci_;

	device::cmt_io<device::CMT0, utils::null_task>  cmt_;
}

extern "C" {

	// syscalls.c から呼ばれる、標準出力（stdout, stderr）
	void sci_putch(char ch)
	{
		sci_.putch(ch);
	}

	void sci_puts(const char* str)
	{
		sci_.puts(str);
	}

	// syscalls.c から呼ばれる、標準入力（stdin）
	char sci_getch(void)
	{
		return sci_.getch();
	}

	uint16_t sci_length()
	{
		return sci_.recv_length();
	}

}

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

int main(int argc, char** argv)
{
	SYSTEM_IO::setup_system_clock();

	{  // タイマー設定
		uint8_t intr = 4;
		cmt_.start(850, intr);
	}

	{  // SCI の開始
		uint8_t intr = 2;        // 割り込みレベル
		uint32_t baud = 115200;  // ボーレート
		sci_.start(baud, intr);
	}

	auto iclk = F_ICLK / 1000000;
	utils::format("Start test for '%s' %d[MHz]\n") % system_str_ % iclk;

#if 0
	utils::STR16 str;

	str = "asdfg";

	for(const auto ch : str) {
		utils::format("%c") % ch;
	}
	utils::format("\n");

	utils::STR16 a("012");
	utils::STR16 b("013");

	utils::format("a: '%s'\n") % a.c_str();
	utils::format("b: '%s'\n") % b.c_str();
	{
		int a_eq_b = a == b;
		utils::format("a.EQ.b: %d\n") % a_eq_b;
	}
	{
		int a_eq_b = a == "013";
		utils::format("a.EQ.\"013\": %d\n") % a_eq_b;
	}

	int a_lt_b = a < b;
	utils::format("a.LT.b: %d\n") % a_lt_b;

	int a_gt_b = a > b;
	utils::format("a.GT.b: %d\n") % a_gt_b;

//	if(a > b) utils::format("a < b: %d\n") % (a > b);
#endif

///	std::cout << "Hello!" << std::endl;
///	utils::format("Hello!\n");
///	printf("Hello!\n");

	LED::OUTPUT();  // LED ポートを出力に設定
	uint8_t cnt = 0;
	while(1) {
		cmt_.sync();

		if(sci_.recv_length() > 0) {
			if(sci_.getch() == ' ') {
				utils::format("Freq  (set): %u Hz\n") % cmt_.get_rate();
				utils::format("Freq (real): %u Hz\n") % cmt_.get_rate(true);
			}
		}

		++cnt;
		if(cnt >= 50) {
			cnt = 0;
		}
		if(cnt < 25) {
			LED::P = 0;
		} else {
			LED::P = 1;
		}
	}
}
<commit_msg>Rename: cmt_io to cmt_mgr<commit_after>//=====================================================================//
/*! @file
    @brief  ファースト・サンプル（LED 点滅） @n
			RX64M, RX71M: @n
					12MHz のベースクロックを使用する @n
			　　　　P07 ピンにLEDを接続する @n
			RX65N (Renesas Envision kit RX65N): @n
					12MHz のベースクロックを使用する @n
			　　　　P70 に接続された LED を利用する @n
			RX63T @n
					12MHz のベースクロックを使用する @n
					PB7 に接続された LED を利用する @n
			RX24T: @n
					10MHz のベースクロックを使用する @n
			　　　　P00 ピンにLEDを接続する @n
			RX66T: @n
					10MHz のベースクロックを使用する @n
			　　　　P00 ピンにLEDを接続する
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"
#include "common/fixed_fifo.hpp"
#include "common/sci_io.hpp"
#include "common/format.hpp"
#include "common/cmt_mgr.hpp"

#include "common/fixed_string.hpp"

/// #include <iostream>

namespace {

#if defined(SIG_RX71M)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B7> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX71M" };
#elif defined(SIG_RX64M)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B7> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX64M" };
#elif defined(SIG_RX65N)
	typedef device::system_io<12000000> SYSTEM_IO;
	typedef device::PORT<device::PORT7, device::bitpos::B0> LED;
	typedef device::SCI9 SCI_CH;
	static const char* system_str_ = { "RX65N" };
#elif defined(SIG_RX24T)
	typedef device::system_io<10000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B0> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX24T" };
#elif defined(SIG_RX66T)
	typedef device::system_io<10000000, 160000000> SYSTEM_IO;
	typedef device::PORT<device::PORT0, device::bitpos::B0> LED;
	typedef device::SCI1 SCI_CH;
	static const char* system_str_ = { "RX66T" };
#endif

	typedef utils::fixed_fifo<char, 512> RXB;  // RX (RECV) バッファの定義
	typedef utils::fixed_fifo<char, 256> TXB;  // TX (SEND) バッファの定義

	typedef device::sci_io<SCI_CH, RXB, TXB> SCI;
// SCI ポートの第二候補を選択する場合
//	typedef device::sci_io<SCI_CH, RXB, TXB, device::port_map::option::SECOND> SCI;
	SCI		sci_;

	device::cmt_mgr<device::CMT0, utils::null_task>  cmt_;
}

extern "C" {

	// syscalls.c から呼ばれる、標準出力（stdout, stderr）
	void sci_putch(char ch)
	{
		sci_.putch(ch);
	}

	void sci_puts(const char* str)
	{
		sci_.puts(str);
	}

	// syscalls.c から呼ばれる、標準入力（stdin）
	char sci_getch(void)
	{
		return sci_.getch();
	}

	uint16_t sci_length()
	{
		return sci_.recv_length();
	}

}

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

int main(int argc, char** argv)
{
	SYSTEM_IO::setup_system_clock();

	{  // タイマー設定
		uint8_t intr = 4;
		cmt_.start(850, intr);
	}

	{  // SCI の開始
		uint8_t intr = 2;        // 割り込みレベル
		uint32_t baud = 115200;  // ボーレート
		sci_.start(baud, intr);
	}

	auto iclk = F_ICLK / 1000000;
	utils::format("Start test for '%s' %d[MHz]\n") % system_str_ % iclk;

#if 0
	utils::STR16 str;

	str = "asdfg";

	for(const auto ch : str) {
		utils::format("%c") % ch;
	}
	utils::format("\n");

	utils::STR16 a("012");
	utils::STR16 b("013");

	utils::format("a: '%s'\n") % a.c_str();
	utils::format("b: '%s'\n") % b.c_str();
	{
		int a_eq_b = a == b;
		utils::format("a.EQ.b: %d\n") % a_eq_b;
	}
	{
		int a_eq_b = a == "013";
		utils::format("a.EQ.\"013\": %d\n") % a_eq_b;
	}

	int a_lt_b = a < b;
	utils::format("a.LT.b: %d\n") % a_lt_b;

	int a_gt_b = a > b;
	utils::format("a.GT.b: %d\n") % a_gt_b;

//	if(a > b) utils::format("a < b: %d\n") % (a > b);
#endif

///	std::cout << "Hello!" << std::endl;
///	utils::format("Hello!\n");
///	printf("Hello!\n");

	LED::OUTPUT();  // LED ポートを出力に設定
	uint8_t cnt = 0;
	while(1) {
		cmt_.sync();

		if(sci_.recv_length() > 0) {
			if(sci_.getch() == ' ') {
				utils::format("Freq  (set): %u Hz\n") % cmt_.get_rate();
				utils::format("Freq (real): %u Hz\n") % cmt_.get_rate(true);
			}
		}

		++cnt;
		if(cnt >= 50) {
			cnt = 0;
		}
		if(cnt < 25) {
			LED::P = 0;
		} else {
			LED::P = 1;
		}
	}
}
<|endoftext|>


<commit_before>/*
 * main.cxx:
 *
 * Copyright (c) 2015 Masashi Fujita
 *
 */

#include "common.h"
#include "md5.h"
#include "salsa20.h"
#include <array>

#define CATCH_CONFIG_MAIN
#include <catch/catch.hpp>
#include <fmt/format.h>
#include <fmt/ostream.h>

static uint32_t to_uint (int a, int b, int c, int d) {
    return (  (static_cast<unsigned int> (a & 0xFF) <<  0)
            | (static_cast<unsigned int> (b & 0xFF) <<  8)
            | (static_cast<unsigned int> (c & 0xFF) << 16)
            | (static_cast<unsigned int> (d & 0xFF) << 24)) ;
}

static uint64_t to_uint (int a, int b, int c, int d, int e, int f, int g, int h) {
    return (  (static_cast<uint64_t> (a & 0xFF) <<  0)
            | (static_cast<uint64_t> (b & 0xFF) <<  8)
            | (static_cast<uint64_t> (c & 0xFF) << 16)
            | (static_cast<uint64_t> (d & 0xFF) << 24)
            | (static_cast<uint64_t> (e & 0xFF) << 32)
            | (static_cast<uint64_t> (f & 0xFF) << 40)
            | (static_cast<uint64_t> (g & 0xFF) << 48)
            | (static_cast<uint64_t> (h & 0xFF) << 56)) ;
}

namespace {
    bool operator == (const Salsa20::hash_value_t &a, const Salsa20::hash_value_t &b) {
        for (int_fast32_t i = 0 ; i < a.size () ; ++i) {
            if (a [i] != b [i]) {
                return false ;
            }
        }
        return true ;
    }

}

std::ostream &  operator << (std::ostream &out, const Salsa20::hash_value_t &value) {
    for (size_t i = 0 ; i < value.size () ; ++i) {
        fmt::print (out, " {0:3d}", value [i]) ;
    }
    return out ;
}

namespace Catch {
    template <> struct StringMaker<Salsa20::hash_value_t> {
        static std::string convert (Salsa20::hash_value_t const& value ) {
            std::stringstream s ;
            for (size_t i = 0 ; i < value.size () ; ++i) {
                fmt::print (s, " {0:3d}", value [i]) ;
            }
            return s.str () ;
        }
    };
}

TEST_CASE ("Simple salsa20 test", "[simple]") {
    auto const  key = std::array<uint8_t, 32> {
          1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,
        201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216
    } ;
    auto const  IV = to_uint (101, 102, 103, 104, 105, 106, 107, 108) ;
    SECTION ("Long key") {
        const Salsa20::hash_value_t expected {  69,  37,  68,  39,  41,  15, 107, 193, 255, 139, 122,   6, 170, 233, 217,  98
                                             ,  89, 144, 182, 106,  21,  51, 200,  65, 239,  49, 222,  34, 215, 114,  40, 126
                                             , 104, 197,   7, 225, 197, 153,  31,   2, 102,  78,  76, 176,  84, 245, 246, 184
                                             , 177, 160, 133, 130,   6,  72, 149, 119, 192, 195, 132, 236, 234, 103, 246,  74 } ;
        Salsa20::State  state (&key [0], key.size (), IV) ;
        state.SetSequenceNumber (to_uint (109, 110, 111, 112, 113, 114, 115, 116)) ;
        auto const result = state.ComputeHashValue () ;

        REQUIRE (result == expected) ;
    }
    SECTION ("Truncated key") {
        const Salsa20::hash_value_t expected {  39, 173,  46, 248,  30, 200,  82,  17,  48, 67, 254, 239,  37,  18,  13, 247
                                             , 241, 200,  61, 144,  10,  55,  50, 185,   6, 47, 246, 253, 143,  86, 187, 225
                                             , 134,  85, 110, 246, 161, 163,  43, 235, 231, 94, 171,  51, 145, 214, 112,  29
                                             ,  14, 232,   5,  16, 151, 140, 183, 141, 171,  9, 122, 181, 104, 182, 177, 193 } ;

        Salsa20::State  state (&key [0], 16, IV) ;
        state.SetSequenceNumber (to_uint (109, 110, 111, 112, 113, 114, 115, 116)) ;

        auto const result = state.ComputeHashValue () ;

        REQUIRE (result == expected) ;
    }
}

TEST_CASE ("Big salsa20 test", "[bigtest][hide]") {
    auto message = std::array<uint8_t, 4096> {} ;
    auto cipher_text = std::array<uint8_t, 4096> {} ;
    auto deciphered = std::array<uint8_t, 4096> {} ;
    auto key = std::array<uint8_t, 32> {} ;
    auto IV = std::array<uint8_t, 8> {} ;

    message.fill (0) ;
    cipher_text.fill (0) ;
    deciphered.fill (0) ;
    key.fill (0) ;
    IV.fill (0) ;

    Salsa20::State  state ;

    SECTION ("Construct state") {
        auto const testvector = std::array<std::string, 10>
                { std::string { "e2d22467015c0ffb0adc5fac0ee88ccf8d467a7f07ab53d4efeac8da47fd833e" }
                , std::string { "42ace6ef6e8dbfa909114e7b3ba45ba8fb8a1ee1215a5cf7099c3d7d54ea7dd2" }
                , std::string { "1db38ebb933ef1969b1f28d9f897fce505d7dc51f5480a37692c3af33f5af678" }
                , std::string { "96858517a69b888de857855809e12779b1d664b624a833b5557c6f2c5d86c890" }
                , std::string { "b6dde6c97a15a8d97440e39d191288ff51adbc7e97b8d2ccb128a47df0800202" }
                , std::string { "7b057f22ee78a6496310686ddc7417824eedd94d4be1ebe8d1166cc23fe6123a" }
                , std::string { "4eea51772404b0fb77ce3f37f19a19f2e758f3aa672f4850c936a7b8cd4a5230" }
                , std::string { "13cdd99b631fdc5c6355985eed37507b015d07236b41a3ab1d04d1721e243b48" }
                , std::string { "247b71ca788aea9c0aae22cc7988d42f5efe3f24782b9481a61620719c7a3c9b" }
                , std::string { "1c47c12a40457949d723b86e97a9f2989344ea7bbad6be8a24b0d3486aa954e1" } } ;

        for (int loop = 0 ; loop < 10 ; ++loop) {
            MD5Generator    md5 ;

            for (int bytes = 0 ; bytes <= message.size () ; ++bytes) {
                state.SetKey (key.data (), ((loop & 1) != 0) ? 32 : 16) ;

                state.SetInitialVector (to_uint (IV[0], IV[1],  IV[2],  IV[3], IV[4], IV[5], IV[6], IV[7])) ;
                Salsa20::Encrypt (state, cipher_text.data (), message.data (), bytes) ;
                md5.update (cipher_text.data (), bytes) ;
                state.SetInitialVector (to_uint (IV[0], IV[1],  IV[2],  IV[3], IV[4], IV[5], IV[6], IV[7])) ;
                Salsa20::Decrypt (state, deciphered.data (), cipher_text.data (), bytes) ;

                for (int i = 0 ; i < bytes ; ++i) {
                    if (deciphered[i] != message[i]) {
                        fmt::print (std::cerr, "Mismatched at position {0:4d}/{1:4d}\n", i, bytes) ;
                    }
                }
                switch (bytes % 3) {
                case 0:
                    for (int i = 0 ; i < std::min<int> (bytes, key.size ()) ; ++i) {
                        key[i] ^= cipher_text[i] ;
                    }
                    break ;
                case 1:
                    for (int i = 0 ; i < std::min<int> (bytes, IV.size ()) ; ++i) {
                        IV[i] ^= cipher_text[i] ;
                    }
                    break ;
                case 2:
                    for (int i = 0 ; i < bytes ; ++i) {
                        message[i] = cipher_text[i] ;
                    }
                    break ;
                }
            }
            MD5Generator::Digest    digest { md5.finalize () } ;

            std::stringstream   sout ;
            for (int i = 0 ; i < 16 ; ++i) {
                fmt::print (sout, "{0:02x}", digest [i]) ;
            }
            for (int i = 0 ; i < 16 ; ++i) {
                fmt::print (sout, "{0:02x}", key[16 + i]) ;
            }
            REQUIRE (sout.str () == testvector[loop]) ;
        }
        SECTION ("Long test") {
            static const int     MAX_LOOP = 134217728 ;

            MD5Generator    md5 ;
            for (int loop = 0 ; loop < MAX_LOOP ; ++loop) {
                if ((loop % 100000) == 0) {
                    std::cerr << '.' << std::flush ;
                }
                Salsa20::Encrypt (state, cipher_text.data (), cipher_text.size ()) ;
                md5.update (cipher_text.data (), cipher_text.size ()) ;
            }
            MD5Generator::Digest    digest { md5.finalize () } ;

            std::stringstream   sout ;
            for (int i = 0 ; i < 16 ; ++i) {
                fmt::print (sout, "{0:02x}", digest [i]) ;
            }
            REQUIRE (sout.str () == "dcb0b1043c425ab0eb97a5f30410a685") ;
        }
    }
}

TEST_CASE ("Incremental update", "[incremental update]") {
    auto expected = std::array<uint8_t, 4096> {} ;
    auto actual = std::array<uint8_t, 4096> {} ;

    expected.fill (0) ;
    actual.fill (0) ;
    std::string key_string { "No one could maintain the public order." } ;
    Salsa20::State  state_0 { key_string.c_str (), key_string.size (), 0x87654321u } ;
    Salsa20::State  state_1 { state_0 } ;

    Salsa20::Apply (state_0, expected.data (), expected.size ()) ;

    for (int i = 0 ; i < actual.size () ; i += 7) {
        Salsa20::Apply (state_1, &actual [i], std::min<size_t> (7, actual.size () - i), i) ;
    }
    REQUIRE (::memcmp (expected.data (), actual.data (), actual.size ()) == 0) ;
}

/*
 * [END of FILE]
 */
<commit_msg>style: Move `static` functions into the anonymous namespace<commit_after>/*
 * main.cxx:
 *
 * Copyright (c) 2015-2017 Masashi Fujita
 *
 */

#include "common.h"
#include "md5.h"
#include "salsa20.h"
#include <array>

#define CATCH_CONFIG_MAIN
#include <catch/catch.hpp>
#include <fmt/format.h>
#include <fmt/ostream.h>

namespace {
    bool    operator== ( const Salsa20::hash_value_t &a
                       , const Salsa20::hash_value_t &b) {
        for (int_fast32_t i = 0 ; i < a.size () ; ++i) {
            if (a[i] != b[i]) {
                return false;
            }
        }
        return true;
    }

    uint32_t    to_uint (int a, int b, int c, int d) {
        return ( (static_cast<unsigned int> (a & 0xFFu) <<  0)
               | (static_cast<unsigned int> (b & 0xFFu) <<  8)
               | (static_cast<unsigned int> (c & 0xFFu) << 16)
               | (static_cast<unsigned int> (d & 0xFFu) << 24));
    }

    uint64_t    to_uint (int a, int b, int c, int d, int e, int f, int g, int h) {
        return ( (static_cast<uint64_t> (a & 0xFFu) <<  0)
               | (static_cast<uint64_t> (b & 0xFFu) <<  8)
               | (static_cast<uint64_t> (c & 0xFFu) << 16)
               | (static_cast<uint64_t> (d & 0xFFu) << 24)
               | (static_cast<uint64_t> (e & 0xFFu) << 32)
               | (static_cast<uint64_t> (f & 0xFFu) << 40)
               | (static_cast<uint64_t> (g & 0xFFu) << 48)
               | (static_cast<uint64_t> (h & 0xFFu) << 56));
    }

    std::ostream &  operator<< (std::ostream &out, const Salsa20::hash_value_t &value) {
        for (size_t i = 0 ; i < value.size () ; ++i) {
            fmt::print (out, " {0:3d}", value[i]);
        }
        return out;
    }
}

namespace Catch {
    template <> struct StringMaker<Salsa20::hash_value_t> {
        static std::string convert (Salsa20::hash_value_t const&value) {
            std::stringstream s ;
            for (size_t i = 0 ; i < value.size () ; ++i) {
                fmt::print (s, " {0:3d}", value [i]) ;
            }
            return s.str () ;
        }
    };
}

TEST_CASE ("Simple salsa20 test", "[simple]") {
    auto const  key = std::array<uint8_t, 32> {
          1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,
        201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216
    } ;
    auto const  IV = to_uint (101, 102, 103, 104, 105, 106, 107, 108) ;
    SECTION ("Long key") {
        const Salsa20::hash_value_t expected {  69,  37,  68,  39,  41,  15, 107, 193, 255, 139, 122,   6, 170, 233, 217,  98
                                             ,  89, 144, 182, 106,  21,  51, 200,  65, 239,  49, 222,  34, 215, 114,  40, 126
                                             , 104, 197,   7, 225, 197, 153,  31,   2, 102,  78,  76, 176,  84, 245, 246, 184
                                             , 177, 160, 133, 130,   6,  72, 149, 119, 192, 195, 132, 236, 234, 103, 246,  74 } ;
        Salsa20::State  state (&key [0], key.size (), IV) ;
        state.SetSequenceNumber (to_uint (109, 110, 111, 112, 113, 114, 115, 116)) ;
        auto const result = state.ComputeHashValue () ;

        REQUIRE (result == expected) ;
    }
    SECTION ("Truncated key") {
        const Salsa20::hash_value_t expected {  39, 173,  46, 248,  30, 200,  82,  17,  48, 67, 254, 239,  37,  18,  13, 247
                                             , 241, 200,  61, 144,  10,  55,  50, 185,   6, 47, 246, 253, 143,  86, 187, 225
                                             , 134,  85, 110, 246, 161, 163,  43, 235, 231, 94, 171,  51, 145, 214, 112,  29
                                             ,  14, 232,   5,  16, 151, 140, 183, 141, 171,  9, 122, 181, 104, 182, 177, 193 } ;

        Salsa20::State  state (&key [0], 16, IV) ;
        state.SetSequenceNumber (to_uint (109, 110, 111, 112, 113, 114, 115, 116)) ;

        auto const result = state.ComputeHashValue () ;

        REQUIRE (result == expected) ;
    }
}

TEST_CASE ("Big salsa20 test", "[bigtest][hide]") {
    auto message = std::array<uint8_t, 4096> {} ;
    auto cipher_text = std::array<uint8_t, 4096> {} ;
    auto deciphered = std::array<uint8_t, 4096> {} ;
    auto key = std::array<uint8_t, 32> {} ;
    auto IV = std::array<uint8_t, 8> {} ;

    message.fill (0) ;
    cipher_text.fill (0) ;
    deciphered.fill (0) ;
    key.fill (0) ;
    IV.fill (0) ;

    Salsa20::State  state ;

    SECTION ("Construct state") {
        auto const testvector = std::array<std::string, 10>
                { std::string { "e2d22467015c0ffb0adc5fac0ee88ccf8d467a7f07ab53d4efeac8da47fd833e" }
                , std::string { "42ace6ef6e8dbfa909114e7b3ba45ba8fb8a1ee1215a5cf7099c3d7d54ea7dd2" }
                , std::string { "1db38ebb933ef1969b1f28d9f897fce505d7dc51f5480a37692c3af33f5af678" }
                , std::string { "96858517a69b888de857855809e12779b1d664b624a833b5557c6f2c5d86c890" }
                , std::string { "b6dde6c97a15a8d97440e39d191288ff51adbc7e97b8d2ccb128a47df0800202" }
                , std::string { "7b057f22ee78a6496310686ddc7417824eedd94d4be1ebe8d1166cc23fe6123a" }
                , std::string { "4eea51772404b0fb77ce3f37f19a19f2e758f3aa672f4850c936a7b8cd4a5230" }
                , std::string { "13cdd99b631fdc5c6355985eed37507b015d07236b41a3ab1d04d1721e243b48" }
                , std::string { "247b71ca788aea9c0aae22cc7988d42f5efe3f24782b9481a61620719c7a3c9b" }
                , std::string { "1c47c12a40457949d723b86e97a9f2989344ea7bbad6be8a24b0d3486aa954e1" } } ;

        for (int loop = 0 ; loop < 10 ; ++loop) {
            MD5Generator    md5 ;

            for (int bytes = 0 ; bytes <= message.size () ; ++bytes) {
                state.SetKey (key.data (), ((loop & 1) != 0) ? 32 : 16) ;

                state.SetInitialVector (to_uint (IV[0], IV[1],  IV[2],  IV[3], IV[4], IV[5], IV[6], IV[7])) ;
                Salsa20::Encrypt (state, cipher_text.data (), message.data (), bytes) ;
                md5.update (cipher_text.data (), bytes) ;
                state.SetInitialVector (to_uint (IV[0], IV[1],  IV[2],  IV[3], IV[4], IV[5], IV[6], IV[7])) ;
                Salsa20::Decrypt (state, deciphered.data (), cipher_text.data (), bytes) ;

                for (int i = 0 ; i < bytes ; ++i) {
                    if (deciphered[i] != message[i]) {
                        fmt::print (std::cerr, "Mismatched at position {0:4d}/{1:4d}\n", i, bytes) ;
                    }
                }
                switch (bytes % 3) {
                case 0:
                    for (int i = 0 ; i < std::min<int> (bytes, key.size ()) ; ++i) {
                        key[i] ^= cipher_text[i] ;
                    }
                    break ;
                case 1:
                    for (int i = 0 ; i < std::min<int> (bytes, IV.size ()) ; ++i) {
                        IV[i] ^= cipher_text[i] ;
                    }
                    break ;
                case 2:
                    for (int i = 0 ; i < bytes ; ++i) {
                        message[i] = cipher_text[i] ;
                    }
                    break ;
                }
            }
            MD5Generator::Digest    digest { md5.finalize () } ;

            std::stringstream   sout ;
            for (int i = 0 ; i < 16 ; ++i) {
                fmt::print (sout, "{0:02x}", digest [i]) ;
            }
            for (int i = 0 ; i < 16 ; ++i) {
                fmt::print (sout, "{0:02x}", key[16 + i]) ;
            }
            REQUIRE (sout.str () == testvector[loop]) ;
        }
        SECTION ("Long test") {
            static const int     MAX_LOOP = 134217728 ;

            MD5Generator    md5 ;
            for (int loop = 0 ; loop < MAX_LOOP ; ++loop) {
                if ((loop % 100000) == 0) {
                    std::cerr << '.' << std::flush ;
                }
                Salsa20::Encrypt (state, cipher_text.data (), cipher_text.size ()) ;
                md5.update (cipher_text.data (), cipher_text.size ()) ;
            }
            MD5Generator::Digest    digest { md5.finalize () } ;

            std::stringstream   sout ;
            for (int i = 0 ; i < 16 ; ++i) {
                fmt::print (sout, "{0:02x}", digest [i]) ;
            }
            REQUIRE (sout.str () == "dcb0b1043c425ab0eb97a5f30410a685") ;
        }
    }
}

TEST_CASE ("Incremental update", "[incremental update]") {
    auto expected = std::array<uint8_t, 4096> {} ;
    auto actual = std::array<uint8_t, 4096> {} ;

    expected.fill (0) ;
    actual.fill (0) ;
    std::string key_string { "No one could maintain the public order." } ;
    Salsa20::State  state_0 { key_string.c_str (), key_string.size (), 0x87654321u } ;
    Salsa20::State  state_1 { state_0 } ;

    Salsa20::Apply (state_0, expected.data (), expected.size ()) ;

    for (int i = 0 ; i < actual.size () ; i += 7) {
        Salsa20::Apply (state_1, &actual [i], std::min<size_t> (7, actual.size () - i), i) ;
    }
    REQUIRE (::memcmp (expected.data (), actual.data (), actual.size ()) == 0) ;
}

/*
 * [END of FILE]
 */
<|endoftext|>


<commit_before>#include <sstream>
#include <iostream>

#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <asm-generic/socket.h>
using namespace std;

#define I_ACKNOWLEDGE_THAT_NATUS_IS_NOT_STABLE
#include <natus/natus.h>
using namespace natus;

static Value socket_from_sock(Value& ctx, int sock, int domain, int type, int protocol);

static Value throwexc_eai(const Value& ctx, int error) {
	const char* type = "IOError";
	switch (error) {
	case EAI_SYSTEM:
		return throwException(ctx, errno);
	case EAI_MEMORY:
		return NULL;
	case EAI_ADDRFAMILY:
	case EAI_AGAIN:
	case EAI_BADFLAGS:
	case EAI_FAIL:
	case EAI_FAMILY:
	case EAI_NODATA:
	case EAI_NONAME:
	case EAI_SERVICE:
	case EAI_SOCKTYPE:
	default:
		break;
	}

	return throwException(ctx, type, gai_strerror(error), error);
}

class SocketClass : public Class {
	virtual Class::Flags getFlags() {
		return Class::FlagGetProperty;
	}

	virtual Value get(Value& obj, string key) {
		sockaddr_storage addr;
		socklen_t len = sizeof(sockaddr_storage);
		char name[1024], port[21];
		int status = 0;

		int fd = (long) obj.getPrivate("posix.fd");

		if (key == "remoteAddress" || key == "remotePort")
			status = getpeername(fd, (sockaddr*) &addr, &len);
		else if (key == "localAddress" || key == "localPort")
			status = getsockname(fd, (sockaddr*) &addr, &len);
		else
			return obj.newUndefined().toException(); // Don't intercept on other properties
		if (status < 0)
			return throwException(obj, errno);

		status = getnameinfo((sockaddr*) &addr, len, name, 1024, port, 21, NI_NUMERICHOST | NI_NUMERICSERV);
		if (status < 0)
			return throwexc_eai(obj, status);

		if (key.find("Address") != string::npos)
			return obj.newString(name);
		return obj.newNumber(atoi(port));
	}
};

static Value socket_accept(Value& ths, Value& fnc, vector<Value>& arg) {
	int fd = (long) ths.getPrivate("posix.fd");

	int newsock = accept(fd, NULL, NULL);
	if (newsock < 0) return throwException(ths, errno);
	return socket_from_sock(ths, newsock, ths.get("domain").toInt(), ths.get("type").toInt(), ths.get("protocol").toInt());
}

static Value socket_bind(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|s(sn)");
	if (exc.isException()) return exc;

	int    fd = (long) ths.getPrivate("posix.fd");
	string ip = "0.0.0.0";
	string port;

	if (arg.size() > 0) {
		ip = arg[0].toString();
		if (arg.size() > 1)
			port = arg[1].toString();
	}

	struct addrinfo* ai = NULL;
	int status = getaddrinfo(ip.c_str(), port.empty() ? NULL : port.c_str(), NULL, &ai);
	if (status != 0) {
		freeaddrinfo(ai);
		return throwexc_eai(ths, status);
	}
	if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
		freeaddrinfo(ai);
		return throwException(ths, errno);
	}
	freeaddrinfo(ai);
	return ths.newUndefined();
}

static Value socket_connect(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "s(sn)");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");

	struct addrinfo* ai = NULL;
	int status = getaddrinfo(arg[0].toString().c_str(), arg[1].toString().c_str(), NULL, &ai);
	if (status != 0) {
		freeaddrinfo(ai);
		return throwexc_eai(ths, status);
	}
	if (connect(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
		freeaddrinfo(ai);
		return throwException(ths, errno);
	}
	freeaddrinfo(ai);
	return ths.newUndefined();
}

static Value socket_listen(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|n");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");
	if (listen(fd, arg.size() > 0 ? arg[0].toInt() : 1024) < 0)
		return throwException(ths, errno);
	return ths.newUndefined();
}

static Value fd_read(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|n");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");

	int bs = arg.size() > 0 ? arg[0].toInt() : 1024;
	char *buff = new char[bs];
	ssize_t rcvd = read(fd, buff, bs);
	if (rcvd < 0) {
		delete[] buff;
		return throwException(ths, errno);
	}
	string ret = string(buff, rcvd);
	delete[] buff;
	return ths.newString(ret);
}

static Value socket_receive(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|n");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");

	int bs = arg.size() > 0 ? arg[0].toInt() : 1024;
	char *buff = new char[bs];
	ssize_t rcvd = recv(fd, buff, bs, 0);
	if (rcvd < 0) {
		delete[] buff;
		return throwException(ths, errno);
	}
	string ret = string(buff, rcvd);
	delete[] buff;
	return ths.newString(ret);
}

static Value socket_send(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "s");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");

	string buff = arg[0].toString();
	ssize_t snt = send(fd, buff.c_str(), buff.length(), 0);
	if (snt < 0) return throwException(ths, errno);
	return ths.newNumber(snt);
}

static Value socket_shutdown(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|n");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");
	if (shutdown(fd, arg.size() > 0 ? arg[0].toInt() : SHUT_RDWR) < 0)
		return throwException(ths, errno);
	return ths.newUndefined();
}

static Value fd_write(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "s");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");
	string buff = arg[0].toString();
	ssize_t snt = write(fd, buff.c_str(), buff.length());
	if (snt < 0) return throwException(ths, errno);
	return ths.newNumber(snt);
}

static Value fd_close(Value& ths, Value& fnc, vector<Value>& arg) {
	int fd = (long) ths.getPrivate("posix.fd");
	if (close(fd) < 0)
		return throwException(ths, errno);
	return ths.newUndefined();
}

static Value socket_ctor(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|nnn");
	if (exc.isException()) return exc;

	int domain = AF_INET, type = SOCK_STREAM, prot = 0;
	if (arg.size() > 0) {
		domain = arg[0].toInt();
		if (arg.size() > 1) {
			type = arg[1].toInt();
			if (arg.size() > 2)
				prot = arg[2].toInt();
		}
	}

	int fd = socket(domain, type, prot);
	if (fd < 0) return throwException(ths, errno);
	return socket_from_sock(ths, fd, domain, type, prot);
}

static Value socket_from_sock(Value& ctx, int sock, int domain, int type, int protocol) {
	Value obj = ctx.newObject(new SocketClass);
	obj.setPrivate("posix.fd", (void*) sock);
	obj.set("accept",        socket_accept);
	obj.set("bind",          socket_bind);
	obj.set("connect",       socket_connect);
	obj.set("close",         fd_close);
	obj.set("listen",        socket_listen);
	obj.set("read",          fd_read);
	obj.set("receive",       socket_receive);
	obj.set("recv",          socket_receive);
	obj.set("send",          socket_send);
	obj.set("shutdown",      socket_shutdown);
	obj.set("write",         fd_write);
	obj.set("isConnected",   false);
	obj.set("isReadable",    false);
	obj.set("isWritable",    false);
	obj.set("localAddress",  "");
	obj.set("localPort",     -1);
	obj.set("remoteAddress", "");
	obj.set("remotePort",    -1);
	obj.set("domain",        domain);
	obj.set("type",          type);
	obj.set("protocol",      protocol);
	return obj;
}

#define OK(x) ok = (x) || ok
#define NCONST(macro) OK(base.set("exports." # macro, macro))

extern "C" bool natus_require(Value& base) {
	bool ok = false;

	// Objects
	OK(base.set("exports.Socket", socket_ctor));

	// Constants
	NCONST(AF_APPLETALK);
	NCONST(AF_ASH);
	NCONST(AF_ATMPVC);
	NCONST(AF_ATMSVC);
	NCONST(AF_AX25);
	NCONST(AF_BRIDGE);
	NCONST(AF_DECnet);
	NCONST(AF_ECONET);
	NCONST(AF_INET);
	NCONST(AF_INET6);
	NCONST(AF_IPX);
	NCONST(AF_IRDA);
	NCONST(AF_KEY);
	NCONST(AF_LLC);
	NCONST(AF_NETBEUI);
	NCONST(AF_NETLINK);
	NCONST(AF_NETROM);
	NCONST(AF_PACKET);
	NCONST(AF_PPPOX);
	NCONST(AF_ROSE);
	NCONST(AF_ROUTE);
	NCONST(AF_SECURITY);
	NCONST(AF_SNA);
	NCONST(AF_TIPC);
	NCONST(AF_UNIX);
	NCONST(AF_UNSPEC);
	NCONST(AF_WANPIPE);
	NCONST(AF_X25);
	NCONST(SOCK_DGRAM);
	NCONST(SOCK_RAW);
	NCONST(SOCK_RDM);
	NCONST(SOCK_SEQPACKET);
	NCONST(SOCK_STREAM);
	NCONST(SHUT_RD);
	NCONST(SHUT_RDWR);
	NCONST(SHUT_WR);
	NCONST(SOL_IP);
	NCONST(SOL_SOCKET);
	NCONST(SOL_TCP);
	NCONST(SOL_UDP);
	NCONST(SO_DEBUG);
	NCONST(SO_REUSEADDR);
	NCONST(SO_TYPE);
	NCONST(SO_ERROR);
	NCONST(SO_DONTROUTE);
	NCONST(SO_BROADCAST);
	NCONST(SO_SNDBUF);
	NCONST(SO_RCVBUF);
	NCONST(SO_SNDBUFFORCE);
	NCONST(SO_RCVBUFFORCE);
	NCONST(SO_KEEPALIVE);
	NCONST(SO_OOBINLINE);
	NCONST(SO_NO_CHECK);
	NCONST(SO_PRIORITY);
	NCONST(SO_LINGER);
	NCONST(SO_BSDCOMPAT);
	NCONST(SO_PASSCRED);
	NCONST(SO_PEERCRED);
	NCONST(SO_RCVLOWAT);
	NCONST(SO_SNDLOWAT);
	NCONST(SO_RCVTIMEO);
	NCONST(SO_SNDTIMEO);
	NCONST(SO_SECURITY_AUTHENTICATION);
	NCONST(SO_SECURITY_ENCRYPTION_TRANSPORT);
	NCONST(SO_SECURITY_ENCRYPTION_NETWORK);
	NCONST(SO_BINDTODEVICE);
	NCONST(SO_ATTACH_FILTER);
	NCONST(SO_DETACH_FILTER);
	NCONST(SO_PEERNAME);
	NCONST(SO_TIMESTAMP);
	NCONST(SO_ACCEPTCONN);
	NCONST(SO_PEERSEC);
	NCONST(SO_PASSSEC);
	NCONST(SO_TIMESTAMPNS);
	NCONST(SO_MARK);
	NCONST(SO_TIMESTAMPING);
	NCONST(SO_PROTOCOL);
	NCONST(SO_DOMAIN);
	NCONST(SO_RXQ_OVFL);
	NCONST(TCP_CORK);
	NCONST(TCP_KEEPIDLE);
	NCONST(TCP_KEEPINTVL);
	NCONST(TCP_KEEPCNT);
	NCONST(TCP_SYNCNT);
	NCONST(TCP_LINGER2);
	NCONST(TCP_DEFER_ACCEPT);
	NCONST(TCP_WINDOW_CLAMP);
	NCONST(TCP_INFO);
	NCONST(TCP_CONGESTION);
	NCONST(TCP_MD5SIG);
	NCONST(TCP_MD5SIG_MAXKEYLEN);

	return ok;
}
<commit_msg>make SO_BSDCOMPAT conditional in the socket module<commit_after>#include <sstream>
#include <iostream>

#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <asm-generic/socket.h>
using namespace std;

#define I_ACKNOWLEDGE_THAT_NATUS_IS_NOT_STABLE
#include <natus/natus.h>
using namespace natus;

static Value socket_from_sock(Value& ctx, int sock, int domain, int type, int protocol);

static Value throwexc_eai(const Value& ctx, int error) {
	const char* type = "IOError";
	switch (error) {
	case EAI_SYSTEM:
		return throwException(ctx, errno);
	case EAI_MEMORY:
		return NULL;
	case EAI_ADDRFAMILY:
	case EAI_AGAIN:
	case EAI_BADFLAGS:
	case EAI_FAIL:
	case EAI_FAMILY:
	case EAI_NODATA:
	case EAI_NONAME:
	case EAI_SERVICE:
	case EAI_SOCKTYPE:
	default:
		break;
	}

	return throwException(ctx, type, gai_strerror(error), error);
}

class SocketClass : public Class {
	virtual Class::Flags getFlags() {
		return Class::FlagGetProperty;
	}

	virtual Value get(Value& obj, string key) {
		sockaddr_storage addr;
		socklen_t len = sizeof(sockaddr_storage);
		char name[1024], port[21];
		int status = 0;

		int fd = (long) obj.getPrivate("posix.fd");

		if (key == "remoteAddress" || key == "remotePort")
			status = getpeername(fd, (sockaddr*) &addr, &len);
		else if (key == "localAddress" || key == "localPort")
			status = getsockname(fd, (sockaddr*) &addr, &len);
		else
			return obj.newUndefined().toException(); // Don't intercept on other properties
		if (status < 0)
			return throwException(obj, errno);

		status = getnameinfo((sockaddr*) &addr, len, name, 1024, port, 21, NI_NUMERICHOST | NI_NUMERICSERV);
		if (status < 0)
			return throwexc_eai(obj, status);

		if (key.find("Address") != string::npos)
			return obj.newString(name);
		return obj.newNumber(atoi(port));
	}
};

static Value socket_accept(Value& ths, Value& fnc, vector<Value>& arg) {
	int fd = (long) ths.getPrivate("posix.fd");

	int newsock = accept(fd, NULL, NULL);
	if (newsock < 0) return throwException(ths, errno);
	return socket_from_sock(ths, newsock, ths.get("domain").toInt(), ths.get("type").toInt(), ths.get("protocol").toInt());
}

static Value socket_bind(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|s(sn)");
	if (exc.isException()) return exc;

	int    fd = (long) ths.getPrivate("posix.fd");
	string ip = "0.0.0.0";
	string port;

	if (arg.size() > 0) {
		ip = arg[0].toString();
		if (arg.size() > 1)
			port = arg[1].toString();
	}

	struct addrinfo* ai = NULL;
	int status = getaddrinfo(ip.c_str(), port.empty() ? NULL : port.c_str(), NULL, &ai);
	if (status != 0) {
		freeaddrinfo(ai);
		return throwexc_eai(ths, status);
	}
	if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
		freeaddrinfo(ai);
		return throwException(ths, errno);
	}
	freeaddrinfo(ai);
	return ths.newUndefined();
}

static Value socket_connect(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "s(sn)");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");

	struct addrinfo* ai = NULL;
	int status = getaddrinfo(arg[0].toString().c_str(), arg[1].toString().c_str(), NULL, &ai);
	if (status != 0) {
		freeaddrinfo(ai);
		return throwexc_eai(ths, status);
	}
	if (connect(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
		freeaddrinfo(ai);
		return throwException(ths, errno);
	}
	freeaddrinfo(ai);
	return ths.newUndefined();
}

static Value socket_listen(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|n");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");
	if (listen(fd, arg.size() > 0 ? arg[0].toInt() : 1024) < 0)
		return throwException(ths, errno);
	return ths.newUndefined();
}

static Value fd_read(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|n");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");

	int bs = arg.size() > 0 ? arg[0].toInt() : 1024;
	char *buff = new char[bs];
	ssize_t rcvd = read(fd, buff, bs);
	if (rcvd < 0) {
		delete[] buff;
		return throwException(ths, errno);
	}
	string ret = string(buff, rcvd);
	delete[] buff;
	return ths.newString(ret);
}

static Value socket_receive(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|n");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");

	int bs = arg.size() > 0 ? arg[0].toInt() : 1024;
	char *buff = new char[bs];
	ssize_t rcvd = recv(fd, buff, bs, 0);
	if (rcvd < 0) {
		delete[] buff;
		return throwException(ths, errno);
	}
	string ret = string(buff, rcvd);
	delete[] buff;
	return ths.newString(ret);
}

static Value socket_send(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "s");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");

	string buff = arg[0].toString();
	ssize_t snt = send(fd, buff.c_str(), buff.length(), 0);
	if (snt < 0) return throwException(ths, errno);
	return ths.newNumber(snt);
}

static Value socket_shutdown(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|n");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");
	if (shutdown(fd, arg.size() > 0 ? arg[0].toInt() : SHUT_RDWR) < 0)
		return throwException(ths, errno);
	return ths.newUndefined();
}

static Value fd_write(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "s");
	if (exc.isException()) return exc;

	int fd = (long) ths.getPrivate("posix.fd");
	string buff = arg[0].toString();
	ssize_t snt = write(fd, buff.c_str(), buff.length());
	if (snt < 0) return throwException(ths, errno);
	return ths.newNumber(snt);
}

static Value fd_close(Value& ths, Value& fnc, vector<Value>& arg) {
	int fd = (long) ths.getPrivate("posix.fd");
	if (close(fd) < 0)
		return throwException(ths, errno);
	return ths.newUndefined();
}

static Value socket_ctor(Value& ths, Value& fnc, vector<Value>& arg) {
	Value exc = checkArguments(ths, arg, "|nnn");
	if (exc.isException()) return exc;

	int domain = AF_INET, type = SOCK_STREAM, prot = 0;
	if (arg.size() > 0) {
		domain = arg[0].toInt();
		if (arg.size() > 1) {
			type = arg[1].toInt();
			if (arg.size() > 2)
				prot = arg[2].toInt();
		}
	}

	int fd = socket(domain, type, prot);
	if (fd < 0) return throwException(ths, errno);
	return socket_from_sock(ths, fd, domain, type, prot);
}

static Value socket_from_sock(Value& ctx, int sock, int domain, int type, int protocol) {
	Value obj = ctx.newObject(new SocketClass);
	obj.setPrivate("posix.fd", (void*) sock);
	obj.set("accept",        socket_accept);
	obj.set("bind",          socket_bind);
	obj.set("connect",       socket_connect);
	obj.set("close",         fd_close);
	obj.set("listen",        socket_listen);
	obj.set("read",          fd_read);
	obj.set("receive",       socket_receive);
	obj.set("recv",          socket_receive);
	obj.set("send",          socket_send);
	obj.set("shutdown",      socket_shutdown);
	obj.set("write",         fd_write);
	obj.set("isConnected",   false);
	obj.set("isReadable",    false);
	obj.set("isWritable",    false);
	obj.set("localAddress",  "");
	obj.set("localPort",     -1);
	obj.set("remoteAddress", "");
	obj.set("remotePort",    -1);
	obj.set("domain",        domain);
	obj.set("type",          type);
	obj.set("protocol",      protocol);
	return obj;
}

#define OK(x) ok = (x) || ok
#define NCONST(macro) OK(base.set("exports." # macro, macro))

extern "C" bool natus_require(Value& base) {
	bool ok = false;

	// Objects
	OK(base.set("exports.Socket", socket_ctor));

	// Constants
	NCONST(AF_APPLETALK);
	NCONST(AF_ASH);
	NCONST(AF_ATMPVC);
	NCONST(AF_ATMSVC);
	NCONST(AF_AX25);
	NCONST(AF_BRIDGE);
	NCONST(AF_DECnet);
	NCONST(AF_ECONET);
	NCONST(AF_INET);
	NCONST(AF_INET6);
	NCONST(AF_IPX);
	NCONST(AF_IRDA);
	NCONST(AF_KEY);
	NCONST(AF_LLC);
	NCONST(AF_NETBEUI);
	NCONST(AF_NETLINK);
	NCONST(AF_NETROM);
	NCONST(AF_PACKET);
	NCONST(AF_PPPOX);
	NCONST(AF_ROSE);
	NCONST(AF_ROUTE);
	NCONST(AF_SECURITY);
	NCONST(AF_SNA);
	NCONST(AF_TIPC);
	NCONST(AF_UNIX);
	NCONST(AF_UNSPEC);
	NCONST(AF_WANPIPE);
	NCONST(AF_X25);
	NCONST(SOCK_DGRAM);
	NCONST(SOCK_RAW);
	NCONST(SOCK_RDM);
	NCONST(SOCK_SEQPACKET);
	NCONST(SOCK_STREAM);
	NCONST(SHUT_RD);
	NCONST(SHUT_RDWR);
	NCONST(SHUT_WR);
	NCONST(SOL_IP);
	NCONST(SOL_SOCKET);
	NCONST(SOL_TCP);
	NCONST(SOL_UDP);
	NCONST(SO_DEBUG);
	NCONST(SO_REUSEADDR);
	NCONST(SO_TYPE);
	NCONST(SO_ERROR);
	NCONST(SO_DONTROUTE);
	NCONST(SO_BROADCAST);
	NCONST(SO_SNDBUF);
	NCONST(SO_RCVBUF);
	NCONST(SO_SNDBUFFORCE);
	NCONST(SO_RCVBUFFORCE);
	NCONST(SO_KEEPALIVE);
	NCONST(SO_OOBINLINE);
	NCONST(SO_NO_CHECK);
	NCONST(SO_PRIORITY);
	NCONST(SO_LINGER);
#ifdef SO_BSDCOMPAT
	NCONST(SO_BSDCOMPAT);
#endif
	NCONST(SO_PASSCRED);
	NCONST(SO_PEERCRED);
	NCONST(SO_RCVLOWAT);
	NCONST(SO_SNDLOWAT);
	NCONST(SO_RCVTIMEO);
	NCONST(SO_SNDTIMEO);
	NCONST(SO_SECURITY_AUTHENTICATION);
	NCONST(SO_SECURITY_ENCRYPTION_TRANSPORT);
	NCONST(SO_SECURITY_ENCRYPTION_NETWORK);
	NCONST(SO_BINDTODEVICE);
	NCONST(SO_ATTACH_FILTER);
	NCONST(SO_DETACH_FILTER);
	NCONST(SO_PEERNAME);
	NCONST(SO_TIMESTAMP);
	NCONST(SO_ACCEPTCONN);
	NCONST(SO_PEERSEC);
	NCONST(SO_PASSSEC);
	NCONST(SO_TIMESTAMPNS);
	NCONST(SO_MARK);
	NCONST(SO_TIMESTAMPING);
	NCONST(SO_PROTOCOL);
	NCONST(SO_DOMAIN);
	NCONST(SO_RXQ_OVFL);
	NCONST(TCP_CORK);
	NCONST(TCP_KEEPIDLE);
	NCONST(TCP_KEEPINTVL);
	NCONST(TCP_KEEPCNT);
	NCONST(TCP_SYNCNT);
	NCONST(TCP_LINGER2);
	NCONST(TCP_DEFER_ACCEPT);
	NCONST(TCP_WINDOW_CLAMP);
	NCONST(TCP_INFO);
	NCONST(TCP_CONGESTION);
	NCONST(TCP_MD5SIG);
	NCONST(TCP_MD5SIG_MAXKEYLEN);

	return ok;
}
<|endoftext|>


<commit_before>
#include "cmdline/cmdline.h"
#include "mhap/overlap.h"
#include "mhap/parser.h"
#include "ra/include/ra/ra.hpp"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>

// trimming params
int READ_LEN_THRESHOLD = 100000;

// BFS params in bubble popping
size_t MAX_NODES = 750;
int MAX_DISTANCE = MAX_NODES * 10000;
double MAX_DIFFERENCE = 0.25;

// contig extraction params
size_t MAX_BRANCHES = 10000;
size_t MAX_START_NODES = 24;

using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::fstream;
using std::max;
using std::string;
using std::vector;

// map reads so we can access reads with mapped[read_id]
void map_reads(vector<Read*>* mapped, vector<Read*>& reads) {

  int max_id = -1;
  for (auto r: reads) {
    max_id = max(max_id, r->getId());
  }

  mapped->resize(max_id + 1, nullptr);
  for (auto r: reads) {
    (*mapped)[r->getId()] = r;
  }
}

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

  cmdline::parser args;

  // input params
  args.add<string>("reads", 'r', "reads file", true);
  args.add<string>("reads_format", 's', "reads format; supported: fasta, fastq, afg", false, "fasta");
  args.add<int>("reads_id_offset", 'a', "reads id offset (first read id)", false, 0);
  args.add<string>("overlaps", 'x', "overlaps file", true);
  args.add<string>("overlaps_format", 'f', "overlaps file format; supported: afg, mhap", false, "afg");

  args.add<bool>("verbose", 'v', "verbose output", false);

  // bubble popping params
  args.add<int>("bp_max_nodes", 'm', "max nodes in bubble branch", false, 750);
  args.add<double>("bp_max_diff", 'n', "max difference between bubble branches", false, 0.25);

  args.parse_check(argc, argv);

  const int thread_num = std::max(std::thread::hardware_concurrency(), 1U);
  const string reads_filename = args.get<string>("reads");
  const string reads_format = args.get<string>("reads_format");
  const string overlaps_filename = args.get<string>("overlaps");
  const string overlaps_format = args.get<string>("overlaps_format");
  const bool verbose_output = args.get<bool>("verbose");
  const int reads_id_offset = args.get<int>("reads_id_offset");

  MAX_NODES = args.get<int>("bp_max_nodes");
  MAX_DISTANCE = MAX_NODES * 10000;
  MAX_DIFFERENCE = args.get<double>("bp_max_diff");

  vector<Overlap*> overlaps, filtered;
  vector<Read*> reads;
  vector<Read*> reads_mapped;

  if (reads_format == "fasta") {
    readFastaReads(reads, reads_filename.c_str());
  } else if (reads_format == "fastq") {
    readFastqReads(reads, reads_filename.c_str());
  } else if (reads_format == "afg") {
    readAfgReads(reads, reads_filename.c_str());
  } else {
    assert(false);
  }

  // map reads so we have reads_mapped[read_id] -> read
  map_reads(&reads_mapped, reads);

  std::cerr << "Read " << reads.size() << " reads" << std::endl;

  if (overlaps_format == "afg") {
    readAfgOverlaps(overlaps, overlaps_filename.c_str());
  } else if (overlaps_format == "mhap") {
    fstream overlaps_file(overlaps_filename);
    MHAP::read_overlaps(overlaps_file, &overlaps);
    overlaps_file.close();
  } else {
    assert(false);
  }

  // fix overlap read ids
  for (auto o: overlaps) {
    o->setA(o->getA() - reads_id_offset);
    o->setB(o->getB() - reads_id_offset);
  }

  for (auto o: overlaps) {
    const auto a = o->getA();
    const auto b = o->getB();
    if (reads_mapped[a] == nullptr) {
      cerr << "Read " << a << " not found" << endl;
      exit(1);
    }
    if (reads_mapped[b] == nullptr) {
      cerr << "Read " << b << " not found" << endl;
      exit(1);
    }

    o->setReadA(reads_mapped[a]);
    o->setReadB(reads_mapped[b]);
  }

  cerr << overlaps.size() << " overlaps read" << endl;

  vector<Overlap*> nocontainments;
  filterContainedOverlaps(nocontainments, overlaps, reads_mapped, true);

  {
    int filtered =  overlaps.size() - nocontainments.size();
    cerr << "Removed " << filtered << " overlaps as contained "
      << "(" << (1.*filtered)/overlaps.size() << ")" << endl;
  }

  if (verbose_output) {
    writeAfgOverlaps(nocontainments, "nocont.afg");
  }

  vector<Overlap*> notransitives;
  filterTransitiveOverlaps(notransitives, nocontainments, thread_num, true);

  {
    int filtered = nocontainments.size() - notransitives.size();
    cerr << "Removed " << filtered << " overlaps as transitive "
      << "(" << (1.*filtered)/nocontainments.size() << ")" << endl;
  }

  if (verbose_output) {
    writeAfgOverlaps(notransitives, "nocont.notran.afg");
  }

  createReverseComplements(reads, thread_num);

  StringGraph* graph = new StringGraph(reads, notransitives);
  graph->simplify();

  std::vector<StringGraphComponent*> components;
  graph->extractComponents(components);

  std::vector<Contig*> contigs;

  for (const auto& component : components) {

    Contig* contig = component->createContig();

    if (contig != nullptr) {
      contigs.emplace_back(contig);
    }
  }

  std::cerr << "number of contigs " << contigs.size() << std::endl;

  writeAfgContigs(contigs, "contigs.afg");

  for (auto r: reads)      delete r;
  for (auto o: overlaps)   delete o;
  for (auto c: components) delete c;
  for (auto c: contigs)    delete c;

  delete graph;

  return 0;
}
<commit_msg>layout: add outputting graph after SG simplification<commit_after>
#include "cmdline/cmdline.h"
#include "mhap/overlap.h"
#include "mhap/parser.h"
#include "ra/include/ra/ra.hpp"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>

// trimming params
int READ_LEN_THRESHOLD = 100000;

// BFS params in bubble popping
size_t MAX_NODES = 750;
int MAX_DISTANCE = MAX_NODES * 10000;
double MAX_DIFFERENCE = 0.25;

// contig extraction params
size_t MAX_BRANCHES = 10000;
size_t MAX_START_NODES = 24;

using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::fstream;
using std::max;
using std::string;
using std::vector;

// map reads so we can access reads with mapped[read_id]
void map_reads(vector<Read*>* mapped, vector<Read*>& reads) {

  int max_id = -1;
  for (auto r: reads) {
    max_id = max(max_id, r->getId());
  }

  mapped->resize(max_id + 1, nullptr);
  for (auto r: reads) {
    (*mapped)[r->getId()] = r;
  }
}

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

  cmdline::parser args;

  // input params
  args.add<string>("reads", 'r', "reads file", true);
  args.add<string>("reads_format", 's', "reads format; supported: fasta, fastq, afg", false, "fasta");
  args.add<int>("reads_id_offset", 'a', "reads id offset (first read id)", false, 0);
  args.add<string>("overlaps", 'x', "overlaps file", true);
  args.add<string>("overlaps_format", 'f', "overlaps file format; supported: afg, mhap", false, "afg");

  args.add<bool>("verbose", 'v', "verbose output", false);

  // bubble popping params
  args.add<int>("bp_max_nodes", 'm', "max nodes in bubble branch", false, 750);
  args.add<double>("bp_max_diff", 'n', "max difference between bubble branches", false, 0.25);

  args.parse_check(argc, argv);

  const int thread_num = std::max(std::thread::hardware_concurrency(), 1U);
  const string reads_filename = args.get<string>("reads");
  const string reads_format = args.get<string>("reads_format");
  const string overlaps_filename = args.get<string>("overlaps");
  const string overlaps_format = args.get<string>("overlaps_format");
  const bool verbose_output = args.get<bool>("verbose");
  const int reads_id_offset = args.get<int>("reads_id_offset");

  MAX_NODES = args.get<int>("bp_max_nodes");
  MAX_DISTANCE = MAX_NODES * 10000;
  MAX_DIFFERENCE = args.get<double>("bp_max_diff");

  vector<Overlap*> overlaps, filtered;
  vector<Read*> reads;
  vector<Read*> reads_mapped;

  if (reads_format == "fasta") {
    readFastaReads(reads, reads_filename.c_str());
  } else if (reads_format == "fastq") {
    readFastqReads(reads, reads_filename.c_str());
  } else if (reads_format == "afg") {
    readAfgReads(reads, reads_filename.c_str());
  } else {
    assert(false);
  }

  // map reads so we have reads_mapped[read_id] -> read
  map_reads(&reads_mapped, reads);

  std::cerr << "Read " << reads.size() << " reads" << std::endl;

  if (overlaps_format == "afg") {
    readAfgOverlaps(overlaps, overlaps_filename.c_str());
  } else if (overlaps_format == "mhap") {
    fstream overlaps_file(overlaps_filename);
    MHAP::read_overlaps(overlaps_file, &overlaps);
    overlaps_file.close();
  } else {
    assert(false);
  }

  // fix overlap read ids
  for (auto o: overlaps) {
    o->setA(o->getA() - reads_id_offset);
    o->setB(o->getB() - reads_id_offset);
  }

  for (auto o: overlaps) {
    const auto a = o->getA();
    const auto b = o->getB();
    if (reads_mapped[a] == nullptr) {
      cerr << "Read " << a << " not found" << endl;
      exit(1);
    }
    if (reads_mapped[b] == nullptr) {
      cerr << "Read " << b << " not found" << endl;
      exit(1);
    }

    o->setReadA(reads_mapped[a]);
    o->setReadB(reads_mapped[b]);
  }

  cerr << overlaps.size() << " overlaps read" << endl;

  vector<Overlap*> nocontainments;
  filterContainedOverlaps(nocontainments, overlaps, reads_mapped, true);

  {
    int filtered =  overlaps.size() - nocontainments.size();
    cerr << "Removed " << filtered << " overlaps as contained "
      << "(" << (1.*filtered)/overlaps.size() << ")" << endl;
  }

  if (verbose_output) {
    writeAfgOverlaps(nocontainments, "nocont.afg");
  }

  vector<Overlap*> notransitives;
  filterTransitiveOverlaps(notransitives, nocontainments, thread_num, true);

  {
    int filtered = nocontainments.size() - notransitives.size();
    cerr << "Removed " << filtered << " overlaps as transitive "
      << "(" << (1.*filtered)/nocontainments.size() << ")" << endl;
  }

  if (verbose_output) {
    writeAfgOverlaps(notransitives, "nocont.notran.afg");
  }

  createReverseComplements(reads, thread_num);

  StringGraph* graph = new StringGraph(reads, notransitives);
  graph->simplify();

  if (verbose_output) {
    vector<Overlap*> simplified_overlaps;
    graph->extractOverlaps(simplified_overlaps);
    writeAfgOverlaps(notransitives, "simplified.afg");
  }

  std::vector<StringGraphComponent*> components;
  graph->extractComponents(components);

  std::vector<Contig*> contigs;

  for (const auto& component : components) {

    Contig* contig = component->createContig();

    if (contig != nullptr) {
      contigs.emplace_back(contig);
    }
  }

  std::cerr << "number of contigs " << contigs.size() << std::endl;

  writeAfgContigs(contigs, "contigs.afg");

  for (auto r: reads)      delete r;
  for (auto o: overlaps)   delete o;
  for (auto c: components) delete c;
  for (auto c: contigs)    delete c;

  delete graph;

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Hash table of monitors.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "lb_hmonitor.hxx"
#include "lb_monitor.hxx"
#include "lb_ping_monitor.hxx"
#include "lb_syn_monitor.hxx"
#include "lb_expect_monitor.hxx"
#include "lb_config.hxx"
#include "pool.hxx"
#include "tpool.hxx"
#include "net/SocketAddress.hxx"

#include <map>

#include <string.h>

inline bool
LbMonitorMap::Key::operator<(const Key &other) const
{
    auto r = strcmp(monitor_name, other.monitor_name);
    if (r != 0)
        return r < 0;

    r = strcmp(node_name, other.node_name);
    if (r != 0)
        return r < 0;

    return port < other.port;
}

char *
LbMonitorMap::Key::ToString(struct pool &pool) const
{
    return p_sprintf(&pool, "%s:[%s]:%u", monitor_name, node_name, port);
}

LbMonitorMap::LbMonitorMap(struct pool &_pool)
    :pool(pool_new_linear(&_pool, "LbMonitorMap", 4096))
{
}

LbMonitorMap::~LbMonitorMap()
{
    Clear();

    pool_unref(pool);
}

void
LbMonitorMap::Enable()
{
    for (auto i : map)
        lb_monitor_enable(i.second);
}

void
LbMonitorMap::Add(const LbNodeConfig &node, unsigned port,
                  const LbMonitorConfig &config, EventLoop &event_loop)
{
    const LbMonitorClass *class_ = nullptr;
    switch (config.type) {
    case LbMonitorConfig::Type::NONE:
        /* nothing to do */
        return;

    case LbMonitorConfig::Type::PING:
        class_ = &ping_monitor_class;
        break;

    case LbMonitorConfig::Type::CONNECT:
        class_ = &syn_monitor_class;
        break;

    case LbMonitorConfig::Type::TCP_EXPECT:
        class_ = &expect_monitor_class;
        break;
    }

    assert(class_ != NULL);

    const AutoRewindPool auto_rewind(*tpool);

    const Key key{config.name.c_str(), node.name.c_str(), port};
    auto r = map.insert(std::make_pair(key, nullptr));
    if (r.second) {
        /* doesn't exist yet: create it */
        struct pool *_pool = pool_new_linear(pool, "monitor", 1024);

        AllocatedSocketAddress address = node.address;
        if (port > 0)
            address.SetPort(port);

        r.first->second =
            lb_monitor_new(event_loop, *_pool, key.ToString(*_pool), config,
                           SocketAddress(address,
                                         node.address.GetSize()),
                           *class_);
        pool_unref(_pool);
    }
}

void
LbMonitorMap::Clear()
{
    for (auto i : map)
        lb_monitor_free(i.second);

    map.clear();
}
<commit_msg>lb_hmonitor: fix shadow warnings<commit_after>/*
 * Hash table of monitors.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "lb_hmonitor.hxx"
#include "lb_monitor.hxx"
#include "lb_ping_monitor.hxx"
#include "lb_syn_monitor.hxx"
#include "lb_expect_monitor.hxx"
#include "lb_config.hxx"
#include "pool.hxx"
#include "tpool.hxx"
#include "net/SocketAddress.hxx"

#include <map>

#include <string.h>

inline bool
LbMonitorMap::Key::operator<(const Key &other) const
{
    auto r = strcmp(monitor_name, other.monitor_name);
    if (r != 0)
        return r < 0;

    r = strcmp(node_name, other.node_name);
    if (r != 0)
        return r < 0;

    return port < other.port;
}

char *
LbMonitorMap::Key::ToString(struct pool &_pool) const
{
    return p_sprintf(&_pool, "%s:[%s]:%u", monitor_name, node_name, port);
}

LbMonitorMap::LbMonitorMap(struct pool &_pool)
    :pool(pool_new_linear(&_pool, "LbMonitorMap", 4096))
{
}

LbMonitorMap::~LbMonitorMap()
{
    Clear();

    pool_unref(pool);
}

void
LbMonitorMap::Enable()
{
    for (auto i : map)
        lb_monitor_enable(i.second);
}

void
LbMonitorMap::Add(const LbNodeConfig &node, unsigned port,
                  const LbMonitorConfig &config, EventLoop &event_loop)
{
    const LbMonitorClass *class_ = nullptr;
    switch (config.type) {
    case LbMonitorConfig::Type::NONE:
        /* nothing to do */
        return;

    case LbMonitorConfig::Type::PING:
        class_ = &ping_monitor_class;
        break;

    case LbMonitorConfig::Type::CONNECT:
        class_ = &syn_monitor_class;
        break;

    case LbMonitorConfig::Type::TCP_EXPECT:
        class_ = &expect_monitor_class;
        break;
    }

    assert(class_ != NULL);

    const AutoRewindPool auto_rewind(*tpool);

    const Key key{config.name.c_str(), node.name.c_str(), port};
    auto r = map.insert(std::make_pair(key, nullptr));
    if (r.second) {
        /* doesn't exist yet: create it */
        struct pool *_pool = pool_new_linear(pool, "monitor", 1024);

        AllocatedSocketAddress address = node.address;
        if (port > 0)
            address.SetPort(port);

        r.first->second =
            lb_monitor_new(event_loop, *_pool, key.ToString(*_pool), config,
                           SocketAddress(address,
                                         node.address.GetSize()),
                           *class_);
        pool_unref(_pool);
    }
}

void
LbMonitorMap::Clear()
{
    for (auto i : map)
        lb_monitor_free(i.second);

    map.clear();
}
<|endoftext|>