<commit_before>/*
 *  This file is part of Poedit (https://poedit.net)
 *
 *  Copyright (C) 2014-2017 Vaclav Slavik
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include "syntaxhighlighter.h"

#include "catalog.h"

#include <unicode/uchar.h>

#include <regex>

namespace
{

class BasicSyntaxHighlighter : public SyntaxHighlighter
{
public:
    void Highlight(const std::wstring& s, const CallbackType& highlight) override
    {
        if (s.empty())
            return;

        const int length = int(s.length());

        for (auto i = s.begin(); i != s.end(); ++i)
        {
            if (!u_isblank(*i))
            {
                int wlen = int(i - s.begin());
                if (wlen)
                    highlight(0, wlen, LeadingWhitespace);
                break;
            }
        }

        for (auto i = s.rbegin(); i != s.rend(); ++i)
        {
            if (!u_isblank(*i))
            {
                int wlen = int(i - s.rbegin());
                if (wlen)
                    highlight(length - wlen, length, LeadingWhitespace);
                break;
            }
        }

        for (auto i = s.begin(); i != s.end(); ++i)
        {
            if (*i == '\\')
            {
                int pos = int(i - s.begin());
                if (++i == s.end())
                    break;
                // Note: this must match AnyTranslatableTextCtrl::EscapePlainText()
                switch (*i)
                {
                    case '0':
                    case 'n':
                    case 'r':
                    case 't':
                    case '\\':
                        highlight(pos, pos + 2, Escape);
                        break;
                    default:
                        break;
                }
            }
        }
    }
};

/// Highlighter that runs multiple sub-highlighters
class CompositeSyntaxHighlighter : public SyntaxHighlighter
{
public:
    void Add(std::shared_ptr<SyntaxHighlighter> h) { m_sub.push_back(h); }

    void Highlight(const std::wstring& s, const CallbackType& highlight) override
    {
        for (auto h : m_sub)
            h->Highlight(s, highlight);
    }

private:
    std::vector<std::shared_ptr<SyntaxHighlighter>> m_sub;
};

/// Match regular expressions for highlighting
class RegexSyntaxHighlighter : public SyntaxHighlighter
{
public:
    /// Ctor. Notice that @a re is a reference and must outlive the highlighter!
    RegexSyntaxHighlighter(std::wregex& re, TextKind kind) : m_re(re), m_kind(kind) {}

    void Highlight(const std::wstring& s, const CallbackType& highlight) override
    {
        std::wsregex_iterator next(s.begin(), s.end(), m_re);
        std::wsregex_iterator end;
        while (next != end)
        {
            auto match = *next++;
            if (match.empty())
                continue;
            int pos = static_cast<int>(match.position());
            highlight(pos, pos + static_cast<int>(match.length()), m_kind);
        }
    }

private:
    std::wregex& m_re;
    TextKind m_kind;
};

std::wregex RE_HTML_MARKUP(LR"(<\/?[a-zA-Z]+(\s+\w+(=(\w+|"[^"]*"|'[^']*'))?)*\s*\/?>)",
                           std::regex_constants::ECMAScript | std::regex_constants::optimize);

// php-format per http://php.net/manual/en/function.sprintf.php plus positionals
std::wregex RE_PHP_FORMAT(LR"(%(\d+\$)?[-+]{0,2}([ 0]|'.)?-?\d*(\..?\d+)?[%bcdeEfFgGosuxX])",
                          std::regex_constants::ECMAScript | std::regex_constants::optimize);

// c-format per http://en.cppreference.com/w/cpp/io/c/fprintf,
//              http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
std::wregex RE_C_FORMAT(LR"(%(\d+\$)?[-+ #0]{0,5}(\d+|\*)?(\.(\d+|\*))?(hh|ll|[hljztL])?[%csdioxXufFeEaAgGnp])",
                        std::regex_constants::ECMAScript | std::regex_constants::optimize);

} // anonymous namespace

SyntaxHighlighterPtr SyntaxHighlighter::ForItem(const CatalogItem& item)
{
    auto formatFlag = item.GetFormatFlag();
    bool needsHTML = item.GetString().Contains('<');

    static auto basic = std::make_shared<BasicSyntaxHighlighter>();
    if (!needsHTML && formatFlag.empty())
        return basic;

    auto all = std::make_shared<CompositeSyntaxHighlighter>();

    // HTML goes first, has lowest priority than special-purpose stuff like format strings:
    if (needsHTML)
    {
        static auto html = std::make_shared<RegexSyntaxHighlighter>(RE_HTML_MARKUP, TextKind::Markup);
        all->Add(html);
    }

    // TODO: more/all languages
    if (formatFlag == "php")
    {
        static auto php_format = std::make_shared<RegexSyntaxHighlighter>(RE_PHP_FORMAT, TextKind::Format);
        all->Add(php_format);
    }
    else if (formatFlag == "c")
    {
        static auto c_format = std::make_shared<RegexSyntaxHighlighter>(RE_C_FORMAT, TextKind::Format);
        all->Add(c_format);
    }

    // basic higlighting has highest priority, so should come last in the order:
    all->Add(basic);

    return all;
}
<commit_msg>Highlight 2+ spaces in the middle of string too<commit_after>/*
 *  This file is part of Poedit (https://poedit.net)
 *
 *  Copyright (C) 2014-2017 Vaclav Slavik
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include "syntaxhighlighter.h"

#include "catalog.h"

#include <unicode/uchar.h>

#include <regex>

namespace
{

class BasicSyntaxHighlighter : public SyntaxHighlighter
{
public:
    void Highlight(const std::wstring& s, const CallbackType& highlight) override
    {
        if (s.empty())
            return;

        const int length = int(s.length());

        for (auto i = s.begin(); i != s.end(); ++i)
        {
            if (!u_isblank(*i))
            {
                int wlen = int(i - s.begin());
                if (wlen)
                    highlight(0, wlen, LeadingWhitespace);
                break;
            }
        }

        for (auto i = s.rbegin(); i != s.rend(); ++i)
        {
            if (!u_isblank(*i))
            {
                int wlen = int(i - s.rbegin());
                if (wlen)
                    highlight(length - wlen, length, LeadingWhitespace);
                break;
            }
        }

        int blank_block_pos = -1;

        for (auto i = s.begin(); i != s.end(); ++i)
        {
            if (u_isblank(*i))
            {
                if (blank_block_pos == -1)
                    blank_block_pos = int(i - s.begin());
            }
            else if (blank_block_pos != -1)
            {
                int endpos = int(i - s.begin());
                if (endpos - blank_block_pos >= 2)
                    highlight(blank_block_pos, endpos, LeadingWhitespace);
                blank_block_pos = -1;
            }

            if (*i == '\\')
            {
                int pos = int(i - s.begin());
                if (++i == s.end())
                    break;
                // Note: this must match AnyTranslatableTextCtrl::EscapePlainText()
                switch (*i)
                {
                    case '0':
                    case 'n':
                    case 'r':
                    case 't':
                    case '\\':
                        highlight(pos, pos + 2, Escape);
                        break;
                    default:
                        break;
                }
            }
        }
    }
};

/// Highlighter that runs multiple sub-highlighters
class CompositeSyntaxHighlighter : public SyntaxHighlighter
{
public:
    void Add(std::shared_ptr<SyntaxHighlighter> h) { m_sub.push_back(h); }

    void Highlight(const std::wstring& s, const CallbackType& highlight) override
    {
        for (auto h : m_sub)
            h->Highlight(s, highlight);
    }

private:
    std::vector<std::shared_ptr<SyntaxHighlighter>> m_sub;
};

/// Match regular expressions for highlighting
class RegexSyntaxHighlighter : public SyntaxHighlighter
{
public:
    /// Ctor. Notice that @a re is a reference and must outlive the highlighter!
    RegexSyntaxHighlighter(std::wregex& re, TextKind kind) : m_re(re), m_kind(kind) {}

    void Highlight(const std::wstring& s, const CallbackType& highlight) override
    {
        std::wsregex_iterator next(s.begin(), s.end(), m_re);
        std::wsregex_iterator end;
        while (next != end)
        {
            auto match = *next++;
            if (match.empty())
                continue;
            int pos = static_cast<int>(match.position());
            highlight(pos, pos + static_cast<int>(match.length()), m_kind);
        }
    }

private:
    std::wregex& m_re;
    TextKind m_kind;
};

std::wregex RE_HTML_MARKUP(LR"(<\/?[a-zA-Z]+(\s+\w+(=(\w+|"[^"]*"|'[^']*'))?)*\s*\/?>)",
                           std::regex_constants::ECMAScript | std::regex_constants::optimize);

// php-format per http://php.net/manual/en/function.sprintf.php plus positionals
std::wregex RE_PHP_FORMAT(LR"(%(\d+\$)?[-+]{0,2}([ 0]|'.)?-?\d*(\..?\d+)?[%bcdeEfFgGosuxX])",
                          std::regex_constants::ECMAScript | std::regex_constants::optimize);

// c-format per http://en.cppreference.com/w/cpp/io/c/fprintf,
//              http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
std::wregex RE_C_FORMAT(LR"(%(\d+\$)?[-+ #0]{0,5}(\d+|\*)?(\.(\d+|\*))?(hh|ll|[hljztL])?[%csdioxXufFeEaAgGnp])",
                        std::regex_constants::ECMAScript | std::regex_constants::optimize);

} // anonymous namespace

SyntaxHighlighterPtr SyntaxHighlighter::ForItem(const CatalogItem& item)
{
    auto formatFlag = item.GetFormatFlag();
    bool needsHTML = item.GetString().Contains('<');

    static auto basic = std::make_shared<BasicSyntaxHighlighter>();
    if (!needsHTML && formatFlag.empty())
        return basic;

    auto all = std::make_shared<CompositeSyntaxHighlighter>();

    // HTML goes first, has lowest priority than special-purpose stuff like format strings:
    if (needsHTML)
    {
        static auto html = std::make_shared<RegexSyntaxHighlighter>(RE_HTML_MARKUP, TextKind::Markup);
        all->Add(html);
    }

    // TODO: more/all languages
    if (formatFlag == "php")
    {
        static auto php_format = std::make_shared<RegexSyntaxHighlighter>(RE_PHP_FORMAT, TextKind::Format);
        all->Add(php_format);
    }
    else if (formatFlag == "c")
    {
        static auto c_format = std::make_shared<RegexSyntaxHighlighter>(RE_C_FORMAT, TextKind::Format);
        all->Add(c_format);
    }

    // basic higlighting has highest priority, so should come last in the order:
    all->Add(basic);

    return all;
}
<|endoftext|>


<commit_before>//   Copyright 2016-2020 Jean-Francois Poilpret
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

/*
 * Simple example, checking all get methods of VL53L0X Time-of-flight range
 * sensor I2C device.
 *
 * Wiring:
 * - on ATmega328P based boards (including Arduino UNO):
 *   - A4 (PC4, SDA): connected to VL53L0X SDA pin
 *   - A5 (PC5, SCL): connected to VL53L0X SCL pin
 *   - direct USB access
 */

#include <fastarduino/time.h>
#include <fastarduino/uart.h>
#include <fastarduino/i2c_handler.h>
#include <fastarduino/i2c_debug.h>
#include <fastarduino/i2c_status.h>
#include <fastarduino/devices/vl53l0x.h>
#include <fastarduino/memory.h>

#define DEBUG_I2C
// #define FORCE_SYNC

// static constexpr const i2c::I2CMode MODE = i2c::I2CMode::FAST;
static constexpr const i2c::I2CMode MODE = i2c::I2CMode::STANDARD;

static constexpr const board::USART UART = board::USART::USART0;
static constexpr const uint8_t OUTPUT_BUFFER_SIZE = 128;
static char output_buffer[OUTPUT_BUFFER_SIZE];

REGISTER_UATX_ISR(0)

#ifdef DEBUG_I2C
static constexpr const uint8_t DEBUG_SIZE = 96;
#	if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
using DEBUGGER = i2c::debug::I2CDebugStatusRecorder<DEBUG_SIZE, DEBUG_SIZE>;
#define DEBUG(OUT) debugger.trace(OUT)
#define RESET_DEBUG() debugger.reset()
using MANAGER = i2c::I2CAsyncStatusDebugManager<
	MODE, i2c::I2CErrorPolicy::CLEAR_ALL_COMMANDS, DEBUGGER&, DEBUGGER&>;
static constexpr const uint8_t I2C_BUFFER_SIZE = 32;
static MANAGER::I2CCOMMAND i2c_buffer[I2C_BUFFER_SIZE];
#	else
using DEBUGGER = i2c::debug::I2CDebugStatusLiveLogger;
#define DEBUG(OUT)
#define RESET_DEBUG()
using MANAGER = i2c::I2CSyncStatusDebugManager<MODE, DEBUGGER&, DEBUGGER&>;
#	endif

#else

#	if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
using MANAGER = i2c::I2CAsyncManager<
	MODE, i2c::I2CErrorPolicy::CLEAR_ALL_COMMANDS>;
static constexpr const uint8_t I2C_BUFFER_SIZE = 32;
static MANAGER::I2CCOMMAND i2c_buffer[I2C_BUFFER_SIZE];
#	else
using MANAGER = i2c::I2CSyncManager<MODE>;
#	endif
#define DEBUG(OUT)
#define RESET_DEBUG()

#endif

#if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
REGISTER_I2C_ISR(MANAGER)
#endif

using streams::dec;
using streams::hex;
using streams::fixed;
using streams::endl;
using streams::flush;

using namespace devices::vl53l0x;
using TOF = VL53L0X<MANAGER>;

void display_memory(streams::ostream& out)
{
	out << F("free mem=") << dec << memory::free_mem() << endl;
}

void check_timing(streams::ostream& out, TOF& tof, SequenceSteps steps)
{
	bool ok = tof.set_sequence_steps(steps);
	out << F("tof.set_sequence_steps(") << steps << F(") = ") << ok << endl;
	out << endl;

	SequenceStepsTimeout timeouts{};
	ok = tof.get_sequence_steps_timeout(timeouts);
	out << F("tof.get_sequence_steps_timeout(timeouts) = ") << ok << flush
		<< F(", pre_range_vcsel_period_pclks = ") << dec << timeouts.pre_range_vcsel_period_pclks() << flush
		<< F(", final_range_vcsel_period_pclks = ") << dec << timeouts.final_range_vcsel_period_pclks() << flush
		<< F(", msrc_dss_tcc_mclks = ") << dec << timeouts.msrc_dss_tcc_mclks() << flush
		<< F(", pre_range_mclks = ") << dec << timeouts.pre_range_mclks() << flush
		<< F(", final_range_mclks = ") << dec << timeouts.final_range_mclks(steps.is_pre_range()) << endl;
	out << F("timeouts.msrc_dss_tcc_us() = ") << dec << timeouts.msrc_dss_tcc_us() << flush
		<< F(", timeouts.pre_range_us() = ") << dec << timeouts.pre_range_us() << flush
		<< F(", timeouts.final_range_us() = ") << dec << timeouts.final_range_us(steps.is_pre_range()) << endl;
	out << endl;

	uint32_t budget_us = 0;
	ok = tof.get_measurement_timing_budget(budget_us);
	out << F("tof.get_measurement_timing_budget() = ") << ok << F(", budget_us = ") << dec << budget_us << endl;
	out << endl;
}

int main() __attribute__((OS_main));
int main()
{
	board::init();
	sei();

	// open UART for traces
	serial::hard::UATX<UART> uart{output_buffer};
	streams::ostream out = uart.out();
	// uart.begin(115200);
	uart.begin(230400);
	out << streams::boolalpha;
	out << F("Start") << endl;

	// Initialize I2C async handler
#ifdef DEBUG_I2C
#	if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
	DEBUGGER debugger;
#	else
	DEBUGGER debugger{out};
#	endif
#endif

#if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
#	ifdef DEBUG_I2C
	MANAGER manager{i2c_buffer, debugger, debugger};
#	else
	MANAGER manager{i2c_buffer};
#	endif
#else
#	ifdef DEBUG_I2C
	MANAGER manager{debugger, debugger};
#	else
	MANAGER manager;
#	endif
#endif

	display_memory(out);

	out << F("Instantiate VL53L0X") << endl;
	TOF tof{manager};
	display_memory(out);

	out << F("Start I2C manager") << endl;
	manager.begin();
	display_memory(out);

	uint8_t result = 0;
	bool ok = false;
	int error = 0;

	{
		out << F("Read VL53L0X status") << endl;
		ok = tof.get_revision(result);
		display_memory(out);
		out << F("tof.get_revision(result) = ") << ok << F(", result = ") << hex << result << endl;
		DEBUG(out);
	}

	{
		ok = tof.get_model(result);
		display_memory(out);
		out << F("tof.get_model(result) = ") << ok << F(", result = ") << hex << result << endl;
		DEBUG(out);
	}

	{
		PowerMode mode = PowerMode::STANDBY;
		ok = tof.get_power_mode(mode);
		display_memory(out);
		out << F("tof.get_power_mode(mode) = ") << ok << F(", mode = ") << mode << endl;
		DEBUG(out);
	}

	{
		DeviceStatus status;
		ok = tof.get_range_status(status);
		display_memory(out);
		out << F("tof.get_range_status(status) = ") << ok
			<< F(", status = ") << status << endl;
		DEBUG(out);
	}

	{
		SequenceSteps steps1;
		ok = tof.get_sequence_steps(steps1);
		display_memory(out);
		out << F("tof.get_sequence_steps(status) = ") << ok << F(", steps =") << steps1 << endl;
		DEBUG(out);
	}

	{
		uint8_t period = 0;
		ok = tof.get_vcsel_pulse_period<VcselPeriodType::PRE_RANGE>(period);
		display_memory(out);
		out << F("tof.get_vcsel_pulse_period<PRE_RANGE>(period) = ") << ok << F(", period = ") << dec << period << endl;
		ok = tof.get_vcsel_pulse_period<VcselPeriodType::FINAL_RANGE>(period);
		display_memory(out);
		out << F("tof.get_vcsel_pulse_period<FINAL_RANGE>(period) = ") << ok << F(", period = ") << dec << period << endl;
		DEBUG(out);
	}

	{
		// The following block adds 3KB to program size (float arithmetic libs)
		float signal_rate = 0.0;
		ok = tof.get_signal_rate_limit(signal_rate);
		display_memory(out);
		out << F("tof.get_signal_rate_limit(signal_rate) = ") << ok << F(", signal_rate = ")
			<< fixed << signal_rate << endl;
		DEBUG(out);
	}

	{
		TOF::GetSPADInfoFuture future3{};
		error = tof.get_SPAD_info(future3);
		display_memory(out);
		out << F("tof.get_SPAD_info(future) = ") << dec << error << endl;
		time::delay_ms(500);
		DEBUG(out);
		out << F("future.status() = ") << future3.status() << endl;
		SPADInfo SPAD_info{};
		future3.get(SPAD_info);
		out << F("SPADInfo = ") << SPAD_info << endl;
		DEBUG(out);
	}

	{
		TOF::GetSequenceStepsTimeoutFuture future2{};
		error = tof.get_sequence_steps_timeout(future2);
		display_memory(out);
		out << F("tof.get_sequence_steps_timeout(future) = ") << dec << error << endl;
		time::delay_ms(100);
		DEBUG(out);
		out << F("future.status() = ") << future2.status() << endl;
		SequenceStepsTimeout timeouts{};
		future2.get(timeouts);
		out << F("tof.get_sequence_steps_timeout(timeouts) = ") << ok << flush
			<< F(", pre_range_vcsel_period_pclks = ") << dec << timeouts.pre_range_vcsel_period_pclks() << flush
			<< F(", final_range_vcsel_period_pclks = ") << dec << timeouts.final_range_vcsel_period_pclks() << flush
			<< F(", msrc_dss_tcc_mclks = ") << dec << timeouts.msrc_dss_tcc_mclks() << flush
			<< F(", pre_range_mclks = ") << dec << timeouts.pre_range_mclks() << flush
			<< F(", final_range_mclks = ") << dec << timeouts.final_range_mclks(true) << endl;
		// check calculated values
		out << F("timeouts.msrc_dss_tcc_us() = ") << dec << timeouts.msrc_dss_tcc_us() << flush
			<< F(", timeouts.pre_range_us() = ") << dec << timeouts.pre_range_us() << flush
			<< F(", timeouts.final_range_us() = ") << dec << timeouts.final_range_us(true) << endl;
		DEBUG(out);
	}

	{
		TOF::GetGPIOSettingsFuture future{};
		error = tof.get_GPIO_settings(future);
		display_memory(out);
		out << F("tof.get_GPIO_settings(future) = ") << dec << error << endl;
		time::delay_ms(100);
		DEBUG(out);
		out << F("future.status() = ") << future.status() << endl;
		GPIOSettings settings{};
		future.get(settings);
		out << F("GPIO setting=") << settings << endl;
	}

	{
		InterruptStatus status{};
		ok = tof.get_interrupt_status(status);
		display_memory(out);
		out << F("tof.get_interrupt_status(status) = ") << ok
			<< F(", status = ") << hex << uint8_t(status) << endl;
	}

	{
		// Check timings
		check_timing(out, tof, SequenceSteps::all());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::all().no_dss());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::all().no_tcc());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::all().no_msrc());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::all().no_pre_range());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::create().pre_range().final_range());
		DEBUG(out);
	}

	manager.end();
}
<commit_msg>Reverse to I2C 400KHz in example.<commit_after>//   Copyright 2016-2020 Jean-Francois Poilpret
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

/*
 * Simple example, checking all get methods of VL53L0X Time-of-flight range
 * sensor I2C device.
 *
 * Wiring:
 * - on ATmega328P based boards (including Arduino UNO):
 *   - A4 (PC4, SDA): connected to VL53L0X SDA pin
 *   - A5 (PC5, SCL): connected to VL53L0X SCL pin
 *   - direct USB access
 */

#include <fastarduino/time.h>
#include <fastarduino/uart.h>
#include <fastarduino/i2c_handler.h>
#include <fastarduino/i2c_debug.h>
#include <fastarduino/i2c_status.h>
#include <fastarduino/devices/vl53l0x.h>
#include <fastarduino/memory.h>

#define DEBUG_I2C
// #define FORCE_SYNC

static constexpr const i2c::I2CMode MODE = i2c::I2CMode::FAST;
// static constexpr const i2c::I2CMode MODE = i2c::I2CMode::STANDARD;

static constexpr const board::USART UART = board::USART::USART0;
static constexpr const uint8_t OUTPUT_BUFFER_SIZE = 128;
static char output_buffer[OUTPUT_BUFFER_SIZE];

REGISTER_UATX_ISR(0)

#ifdef DEBUG_I2C
static constexpr const uint8_t DEBUG_SIZE = 96;
#	if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
using DEBUGGER = i2c::debug::I2CDebugStatusRecorder<DEBUG_SIZE, DEBUG_SIZE>;
#define DEBUG(OUT) debugger.trace(OUT)
#define RESET_DEBUG() debugger.reset()
using MANAGER = i2c::I2CAsyncStatusDebugManager<
	MODE, i2c::I2CErrorPolicy::CLEAR_ALL_COMMANDS, DEBUGGER&, DEBUGGER&>;
static constexpr const uint8_t I2C_BUFFER_SIZE = 32;
static MANAGER::I2CCOMMAND i2c_buffer[I2C_BUFFER_SIZE];
#	else
using DEBUGGER = i2c::debug::I2CDebugStatusLiveLogger;
#define DEBUG(OUT)
#define RESET_DEBUG()
using MANAGER = i2c::I2CSyncStatusDebugManager<MODE, DEBUGGER&, DEBUGGER&>;
#	endif

#else

#	if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
using MANAGER = i2c::I2CAsyncManager<
	MODE, i2c::I2CErrorPolicy::CLEAR_ALL_COMMANDS>;
static constexpr const uint8_t I2C_BUFFER_SIZE = 32;
static MANAGER::I2CCOMMAND i2c_buffer[I2C_BUFFER_SIZE];
#	else
using MANAGER = i2c::I2CSyncManager<MODE>;
#	endif
#define DEBUG(OUT)
#define RESET_DEBUG()

#endif

#if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
REGISTER_I2C_ISR(MANAGER)
#endif

using streams::dec;
using streams::hex;
using streams::fixed;
using streams::endl;
using streams::flush;

using namespace devices::vl53l0x;
using TOF = VL53L0X<MANAGER>;

void display_memory(streams::ostream& out)
{
	out << F("free mem=") << dec << memory::free_mem() << endl;
}

void check_timing(streams::ostream& out, TOF& tof, SequenceSteps steps)
{
	bool ok = tof.set_sequence_steps(steps);
	out << F("tof.set_sequence_steps(") << steps << F(") = ") << ok << endl;
	out << endl;

	SequenceStepsTimeout timeouts{};
	ok = tof.get_sequence_steps_timeout(timeouts);
	out << F("tof.get_sequence_steps_timeout(timeouts) = ") << ok << flush
		<< F(", pre_range_vcsel_period_pclks = ") << dec << timeouts.pre_range_vcsel_period_pclks() << flush
		<< F(", final_range_vcsel_period_pclks = ") << dec << timeouts.final_range_vcsel_period_pclks() << flush
		<< F(", msrc_dss_tcc_mclks = ") << dec << timeouts.msrc_dss_tcc_mclks() << flush
		<< F(", pre_range_mclks = ") << dec << timeouts.pre_range_mclks() << flush
		<< F(", final_range_mclks = ") << dec << timeouts.final_range_mclks(steps.is_pre_range()) << endl;
	out << F("timeouts.msrc_dss_tcc_us() = ") << dec << timeouts.msrc_dss_tcc_us() << flush
		<< F(", timeouts.pre_range_us() = ") << dec << timeouts.pre_range_us() << flush
		<< F(", timeouts.final_range_us() = ") << dec << timeouts.final_range_us(steps.is_pre_range()) << endl;
	out << endl;

	uint32_t budget_us = 0;
	ok = tof.get_measurement_timing_budget(budget_us);
	out << F("tof.get_measurement_timing_budget() = ") << ok << F(", budget_us = ") << dec << budget_us << endl;
	out << endl;
}

int main() __attribute__((OS_main));
int main()
{
	board::init();
	sei();

	// open UART for traces
	serial::hard::UATX<UART> uart{output_buffer};
	streams::ostream out = uart.out();
	// uart.begin(115200);
	uart.begin(230400);
	out << streams::boolalpha;
	out << F("Start") << endl;

	// Initialize I2C async handler
#ifdef DEBUG_I2C
#	if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
	DEBUGGER debugger;
#	else
	DEBUGGER debugger{out};
#	endif
#endif

#if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
#	ifdef DEBUG_I2C
	MANAGER manager{i2c_buffer, debugger, debugger};
#	else
	MANAGER manager{i2c_buffer};
#	endif
#else
#	ifdef DEBUG_I2C
	MANAGER manager{debugger, debugger};
#	else
	MANAGER manager;
#	endif
#endif

	display_memory(out);

	out << F("Instantiate VL53L0X") << endl;
	TOF tof{manager};
	display_memory(out);

	out << F("Start I2C manager") << endl;
	manager.begin();
	display_memory(out);

	uint8_t result = 0;
	bool ok = false;
	int error = 0;

	{
		out << F("Read VL53L0X status") << endl;
		ok = tof.get_revision(result);
		display_memory(out);
		out << F("tof.get_revision(result) = ") << ok << F(", result = ") << hex << result << endl;
		DEBUG(out);
	}

	{
		ok = tof.get_model(result);
		display_memory(out);
		out << F("tof.get_model(result) = ") << ok << F(", result = ") << hex << result << endl;
		DEBUG(out);
	}

	{
		PowerMode mode = PowerMode::STANDBY;
		ok = tof.get_power_mode(mode);
		display_memory(out);
		out << F("tof.get_power_mode(mode) = ") << ok << F(", mode = ") << mode << endl;
		DEBUG(out);
	}

	{
		DeviceStatus status;
		ok = tof.get_range_status(status);
		display_memory(out);
		out << F("tof.get_range_status(status) = ") << ok
			<< F(", status = ") << status << endl;
		DEBUG(out);
	}

	{
		SequenceSteps steps1;
		ok = tof.get_sequence_steps(steps1);
		display_memory(out);
		out << F("tof.get_sequence_steps(status) = ") << ok << F(", steps =") << steps1 << endl;
		DEBUG(out);
	}

	{
		uint8_t period = 0;
		ok = tof.get_vcsel_pulse_period<VcselPeriodType::PRE_RANGE>(period);
		display_memory(out);
		out << F("tof.get_vcsel_pulse_period<PRE_RANGE>(period) = ") << ok << F(", period = ") << dec << period << endl;
		ok = tof.get_vcsel_pulse_period<VcselPeriodType::FINAL_RANGE>(period);
		display_memory(out);
		out << F("tof.get_vcsel_pulse_period<FINAL_RANGE>(period) = ") << ok << F(", period = ") << dec << period << endl;
		DEBUG(out);
	}

	{
		// The following block adds 3KB to program size (float arithmetic libs)
		float signal_rate = 0.0;
		ok = tof.get_signal_rate_limit(signal_rate);
		display_memory(out);
		out << F("tof.get_signal_rate_limit(signal_rate) = ") << ok << F(", signal_rate = ")
			<< fixed << signal_rate << endl;
		DEBUG(out);
	}

	{
		TOF::GetSPADInfoFuture future3{};
		error = tof.get_SPAD_info(future3);
		display_memory(out);
		out << F("tof.get_SPAD_info(future) = ") << dec << error << endl;
		time::delay_ms(500);
		DEBUG(out);
		out << F("future.status() = ") << future3.status() << endl;
		SPADInfo SPAD_info{};
		future3.get(SPAD_info);
		out << F("SPADInfo = ") << SPAD_info << endl;
		DEBUG(out);
	}

	{
		TOF::GetSequenceStepsTimeoutFuture future2{};
		error = tof.get_sequence_steps_timeout(future2);
		display_memory(out);
		out << F("tof.get_sequence_steps_timeout(future) = ") << dec << error << endl;
		time::delay_ms(100);
		DEBUG(out);
		out << F("future.status() = ") << future2.status() << endl;
		SequenceStepsTimeout timeouts{};
		future2.get(timeouts);
		out << F("tof.get_sequence_steps_timeout(timeouts) = ") << ok << flush
			<< F(", pre_range_vcsel_period_pclks = ") << dec << timeouts.pre_range_vcsel_period_pclks() << flush
			<< F(", final_range_vcsel_period_pclks = ") << dec << timeouts.final_range_vcsel_period_pclks() << flush
			<< F(", msrc_dss_tcc_mclks = ") << dec << timeouts.msrc_dss_tcc_mclks() << flush
			<< F(", pre_range_mclks = ") << dec << timeouts.pre_range_mclks() << flush
			<< F(", final_range_mclks = ") << dec << timeouts.final_range_mclks(true) << endl;
		// check calculated values
		out << F("timeouts.msrc_dss_tcc_us() = ") << dec << timeouts.msrc_dss_tcc_us() << flush
			<< F(", timeouts.pre_range_us() = ") << dec << timeouts.pre_range_us() << flush
			<< F(", timeouts.final_range_us() = ") << dec << timeouts.final_range_us(true) << endl;
		DEBUG(out);
	}

	{
		TOF::GetGPIOSettingsFuture future{};
		error = tof.get_GPIO_settings(future);
		display_memory(out);
		out << F("tof.get_GPIO_settings(future) = ") << dec << error << endl;
		time::delay_ms(100);
		DEBUG(out);
		out << F("future.status() = ") << future.status() << endl;
		GPIOSettings settings{};
		future.get(settings);
		out << F("GPIO setting=") << settings << endl;
	}

	{
		InterruptStatus status{};
		ok = tof.get_interrupt_status(status);
		display_memory(out);
		out << F("tof.get_interrupt_status(status) = ") << ok
			<< F(", status = ") << hex << uint8_t(status) << endl;
	}

	{
		// Check timings
		check_timing(out, tof, SequenceSteps::all());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::all().no_dss());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::all().no_tcc());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::all().no_msrc());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::all().no_pre_range());
		DEBUG(out);
		check_timing(out, tof, SequenceSteps::create().pre_range().final_range());
		DEBUG(out);
	}

	manager.end();
}
<|endoftext|>


<commit_before>#include <stdio.h>

#include <rtl/process.h>
#include <rtl/bootstrap.hxx>
#include <rtl/string.hxx>
#include <rtl/byteseq.hxx>

#include <osl/process.h>

using namespace ::rtl;

void main( int argc, char *argv[] )
{
    sal_Int32 nCount = rtl_getAppCommandArgCount();
    fprintf( stdout, "rtl-commandargs (%d)" , nCount );
    for( sal_Int32 i = 0 ; i < nCount ; i ++ )
    {
        OUString data;
        rtl_getAppCommandArg( i , &(data.pData) );
        OString o = OUStringToOString( data, RTL_TEXTENCODING_ASCII_US );
        fprintf( stdout, " %s", o.getStr() );
    }
    fprintf( stdout, "\n" );

    if( nCount == 0 )
    {
        printf( "usage : testbootstrap <checkedValueOfMyBootstrapValue>\n" );
        exit( 1 );
    }

    OUString name( RTL_CONSTASCII_USTRINGPARAM( "MYBOOTSTRAPTESTVALUE" ));
    OUString myDefault( RTL_CONSTASCII_USTRINGPARAM( "default" ));

    OUString value;
      Bootstrap::get( name, value, myDefault );

    OSL_ASSERT( OUString::createFromAscii( argv[1] ) == value );

    // test the default case
    name = OUString( RTL_CONSTASCII_USTRINGPARAM( "no_one_has_set_this_name" ) );
    OSL_ASSERT( ! Bootstrap::get( name, value ) );

    myDefault = OUString( RTL_CONSTASCII_USTRINGPARAM( "1" ) );
    OUString myDefault2 = OUString( RTL_CONSTASCII_USTRINGPARAM( "2" ) );

    Bootstrap::get( name, value, myDefault );
    OSL_ASSERT( value == myDefault );
    Bootstrap::get( name, value, myDefault2 );
    OSL_ASSERT( value == myDefault2 );
}
<commit_msg>more verbose in error case (#88338#)<commit_after>#include <stdio.h>

#include <rtl/process.h>
#include <rtl/bootstrap.hxx>
#include <rtl/string.hxx>
#include <rtl/byteseq.hxx>

#include <osl/process.h>

using namespace ::rtl;

void main( int argc, char *argv[] )
{
    sal_Int32 nCount = rtl_getAppCommandArgCount();
    fprintf( stdout, "rtl-commandargs (%d) real args:%i ", nCount, argc);
    for( sal_Int32 i = 0 ; i < nCount ; i ++ )
    {
        OUString data;
        rtl_getAppCommandArg( i , &(data.pData) );
        OString o = OUStringToOString( data, RTL_TEXTENCODING_ASCII_US );
        fprintf( stdout, " %s", o.getStr() );
    }
    fprintf( stdout, "\n" );

    if( nCount == 0 )
    {
        printf( "usage : testbootstrap <checkedValueOfMyBootstrapValue>\n" );
        exit( 1 );
    }

    OUString name( RTL_CONSTASCII_USTRINGPARAM( "MYBOOTSTRAPTESTVALUE" ));
    OUString myDefault( RTL_CONSTASCII_USTRINGPARAM( "default" ));

    OUString value;
      Bootstrap::get( name, value, myDefault );

    OUString para(OUString::createFromAscii( argv[1] ));
    if(para != value)
    {
        OString para_tmp = OUStringToOString(para, RTL_TEXTENCODING_ASCII_US);
        OString value_tmp = OUStringToOString(value, RTL_TEXTENCODING_ASCII_US);

        fprintf(stderr, "para(%s) != value(%s)\n", para_tmp.getStr(), value_tmp.getStr());
    }

    // test the default case
    name = OUString( RTL_CONSTASCII_USTRINGPARAM( "no_one_has_set_this_name" ) );
    OSL_ASSERT( ! Bootstrap::get( name, value ) );

    myDefault = OUString( RTL_CONSTASCII_USTRINGPARAM( "1" ) );
    OUString myDefault2 = OUString( RTL_CONSTASCII_USTRINGPARAM( "2" ) );

    Bootstrap::get( name, value, myDefault );
    OSL_ASSERT( value == myDefault );
    Bootstrap::get( name, value, myDefault2 );
    OSL_ASSERT( value == myDefault2 );
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/status_icons/status_tray_win.h"

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/status_icons/status_icon_observer.h"
#include "chrome/browser/ui/views/status_icons/status_icon_win.h"
#include "grit/theme_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/resource/resource_bundle.h"

class SkBitmap;

class MockStatusIconObserver : public StatusIconObserver {
 public:
  MOCK_METHOD0(OnStatusIconClicked, void());
};

TEST(StatusTrayWinTest, CreateTray) {
  // Just tests creation/destruction.
  StatusTrayWin tray;
}

TEST(StatusTrayWinTest, CreateIconAndMenu) {
  // Create an icon, set the images, tooltip, and context menu, then shut it
  // down.
  StatusTrayWin tray;
  StatusIcon* icon = tray.CreateStatusIcon();
  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
  icon->SetImage(*image);
  icon->SetPressedImage(*image);
  icon->SetToolTip(ASCIIToUTF16("tool tip"));
  ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(NULL);
  menu->AddItem(0, L"foo");
  icon->SetContextMenu(menu);
}

TEST(StatusTrayWinTest, ClickOnIcon) {
  // Create an icon, send a fake click event, make sure observer is called.
  StatusTrayWin tray;
  StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon());
  MockStatusIconObserver observer;
  icon->AddObserver(&observer);
  EXPECT_CALL(observer, OnStatusIconClicked());
  // Mimic a click.
  tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_LBUTTONDOWN);
  // Mimic a right-click - observer should not be called.
  tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_RBUTTONDOWN);
  icon->RemoveObserver(&observer);
}
<commit_msg>Don't run StatusTrayWinTest.ClickOnIcon on bots since it fails on them. It does pass locally though.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/status_icons/status_tray_win.h"

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/status_icons/status_icon_observer.h"
#include "chrome/browser/ui/views/status_icons/status_icon_win.h"
#include "grit/theme_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/resource/resource_bundle.h"

class SkBitmap;

class MockStatusIconObserver : public StatusIconObserver {
 public:
  MOCK_METHOD0(OnStatusIconClicked, void());
};

TEST(StatusTrayWinTest, CreateTray) {
  // Just tests creation/destruction.
  StatusTrayWin tray;
}

TEST(StatusTrayWinTest, CreateIconAndMenu) {
  // Create an icon, set the images, tooltip, and context menu, then shut it
  // down.
  StatusTrayWin tray;
  StatusIcon* icon = tray.CreateStatusIcon();
  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
  icon->SetImage(*image);
  icon->SetPressedImage(*image);
  icon->SetToolTip(ASCIIToUTF16("tool tip"));
  ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(NULL);
  menu->AddItem(0, L"foo");
  icon->SetContextMenu(menu);
}

#if !defined(USE_AURA)  // http://crbug.com/156370
TEST(StatusTrayWinTest, ClickOnIcon) {
  // Create an icon, send a fake click event, make sure observer is called.
  StatusTrayWin tray;
  StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon());
  MockStatusIconObserver observer;
  icon->AddObserver(&observer);
  EXPECT_CALL(observer, OnStatusIconClicked());
  // Mimic a click.
  tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_LBUTTONDOWN);
  // Mimic a right-click - observer should not be called.
  tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_RBUTTONDOWN);
  icon->RemoveObserver(&observer);
}
// !defined(USE_AURA)
<|endoftext|>


<commit_before>#include "Arduino.h"
#include "ODriveArduino.h"

static const int kMotorOffsetFloat = 2;
static const int kMotorStrideFloat = 28;
static const int kMotorOffsetInt32 = 0;
static const int kMotorStrideInt32 = 4;
static const int kMotorOffsetBool = 0;
static const int kMotorStrideBool = 4;
static const int kMotorOffsetUint16 = 0;
static const int kMotorStrideUint16 = 2;

// Print with stream operator
template<class T> inline Print& operator <<(Print &obj,     T arg) { obj.print(arg);    return obj; }
template<>        inline Print& operator <<(Print &obj, float arg) { obj.print(arg, 4); return obj; }

ODriveArduino::ODriveArduino(Stream& serial)
    : serial_(serial) {}

void ODriveArduino::SetPosition(int motor_number, float position) {
    SetPosition(motor_number, position, 0.0f, 0.0f);
}

void ODriveArduino::SetPosition(int motor_number, float position, float velocity_feedforward) {
    SetPosition(motor_number, position, velocity_feedforward, 0.0f);
}

void ODriveArduino::SetPosition(int motor_number, float position, float velocity_feedforward, float current_feedforward) {
    serial_ << "p " << motor_number  << " " << position << " " << velocity_feedforward << " " << current_feedforward << "\n";
}

void ODriveArduino::SetVelocity(int motor_number, float velocity) {
    SetVelocity(motor_number, velocity, 0.0f);
}

void ODriveArduino::SetVelocity(int motor_number, float velocity, float current_feedforward) {
    serial_ << "v " << motor_number  << " " << velocity << " " << current_feedforward << "\n";
}

void ODriveArduino::SetCurrent(int motor_number, float current) {
    serial_ << "c " << motor_number << " " << current << "\n";
}

void ODriveArduino::TrapezoidalMove(int motor_number, float position) {
    serial_ << "t " << motor_number << " " << position << "\n";
}

float ODriveArduino::readFloat() {
    return readString().toFloat();
}

float ODriveArduino::GetVelocity(int motor_number) {
	serial_<< "r axis" << motor_number << ".encoder.vel_estimate\n";
	return ODriveArduino::readFloat();
}

float ODriveArduino::GetPosition(int motor_number) {
    serial_ << "r axis" << motor_number << ".encoder.pos_estimate\n";
    return ODriveArduino::readFloat();
}

int32_t ODriveArduino::readInt() {
    return readString().toInt();
}

bool ODriveArduino::run_state(int axis, int requested_state, bool wait_for_idle, float timeout) {
    int timeout_ctr = (int)(timeout * 10.0f);
    serial_ << "w axis" << axis << ".requested_state " << requested_state << '\n';
    if (wait_for_idle) {
        do {
            delay(100);
            serial_ << "r axis" << axis << ".current_state\n";
        } while (readInt() != AXIS_STATE_IDLE && --timeout_ctr > 0);
    }

    return timeout_ctr > 0;
}

String ODriveArduino::readString() {
    String str = "";
    static const unsigned long timeout = 1000;
    unsigned long timeout_start = millis();
    for (;;) {
        while (!serial_.available()) {
            if (millis() - timeout_start >= timeout) {
                return str;
            }
        }
        char c = serial_.read();
        if (c == '\n')
            break;
        str += c;
    }
    return str;
}
<commit_msg>Update ODriveArduino.cpp<commit_after>
#include "Arduino.h"
#include "ODriveArduino.h"

static const int kMotorOffsetFloat = 2;
static const int kMotorStrideFloat = 28;
static const int kMotorOffsetInt32 = 0;
static const int kMotorStrideInt32 = 4;
static const int kMotorOffsetBool = 0;
static const int kMotorStrideBool = 4;
static const int kMotorOffsetUint16 = 0;
static const int kMotorStrideUint16 = 2;

// Print with stream operator
template<class T> inline Print& operator <<(Print &obj,     T arg) { obj.print(arg);    return obj; }
template<>        inline Print& operator <<(Print &obj, float arg) { obj.print(arg, 4); return obj; }

ODriveArduino::ODriveArduino(Stream& serial)
    : serial_(serial) {}

void ODriveArduino::SetPosition(int motor_number, float position) {
    SetPosition(motor_number, position, 0.0f, 0.0f);
}

void ODriveArduino::SetPosition(int motor_number, float position, float velocity_feedforward) {
    SetPosition(motor_number, position, velocity_feedforward, 0.0f);
}

void ODriveArduino::SetPosition(int motor_number, float position, float velocity_feedforward, float current_feedforward) {
    serial_ << "p " << motor_number  << " " << position << " " << velocity_feedforward << " " << current_feedforward << "\n";
}

void ODriveArduino::SetVelocity(int motor_number, float velocity) {
    SetVelocity(motor_number, velocity, 0.0f);
}

void ODriveArduino::SetVelocity(int motor_number, float velocity, float current_feedforward) {
    serial_ << "v " << motor_number  << " " << velocity << " " << current_feedforward << "\n";
}

void ODriveArduino::SetCurrent(int motor_number, float current) {
    serial_ << "c " << motor_number << " " << current << "\n";
}

void ODriveArduino::TrapezoidalMove(int motor_number, float position) {
    serial_ << "t " << motor_number << " " << position << "\n";
}

float ODriveArduino::readFloat() {
    return readString().toFloat();
}

float ODriveArduino::GetVelocity(int motor_number) {
	serial_<< "r axis" << motor_number << ".encoder.vel_estimate\n";
	return ODriveArduino::readFloat();
}

float ODriveArduino::GetPosition(int motor_number) {
    serial_ << "r axis" << motor_number << ".encoder.pos_estimate\n";
    return ODriveArduino::readFloat();
}

int32_t ODriveArduino::readInt() {
    return readString().toInt();
}

bool ODriveArduino::run_state(int axis, int requested_state, bool wait_for_idle, float timeout) {
    int timeout_ctr = (int)(timeout * 10.0f);
    serial_ << "w axis" << axis << ".requested_state " << requested_state << '\n';
    if (wait_for_idle) {
        do {
            delay(100);
            serial_ << "r axis" << axis << ".current_state\n";
        } while (readInt() != AXIS_STATE_IDLE && --timeout_ctr > 0);
    }

    return timeout_ctr > 0;
}

String ODriveArduino::readString() {
    String str = "";
    static const unsigned long timeout = 1000;
    unsigned long timeout_start = millis();
    for (;;) {
        while (!serial_.available()) {
            if (millis() - timeout_start >= timeout) {
                return str;
            }
        }
        char c = serial_.read();
        if (c == '\n')
            break;
        str += c;
    }
    return str;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include "boost/program_options.hpp"
#include "boost/shared_ptr.hpp"

#include "Model.h"
#include "BookKeeper.h"
#include "Timer.h"
#include "InputXML.h"
#include "CycException.h"
#include "Env.h"
#include "Logger.h"
#include "IsoVector.h"

using namespace std;
namespace po = boost::program_options;

//-----------------------------------------------------------------------
// Main entry point for the test application...
//-----------------------------------------------------------------------
int main(int argc, char* argv[]) {
  // verbosity help msg
  std::string vmessage = "output log verbosity. Can be text:\n\n";
  vmessage += "   LEV_ERROR (least verbose, default), LEV_WARN, \n   LEV_INFO1 (through 5), and LEV_DEBUG1 (through 5).\n\n";
  vmessage += "Or an integer:\n\n   0 (LEV_ERROR equiv) through 11 (LEV_DEBUG5 equiv)\n";

  // parse command line options
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help,h", "produce help message")
    ("no-model", "only print log entries from cyclus core code")
    ("no-mem", "exclude memory log statement from logger output")
    ("verb,v", po::value<string>(), vmessage.c_str())
    ("input-file", po::value<string>(), "input file")
    ;

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  po::positional_options_description p;
  p.add("input-file", 1);

  //po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).
            options(desc).positional(p).run(), vm);
  po::notify(vm);

  // announce yourself
  cout << endl;
  cout << "|--------------------------------------------|" << endl;
  cout << "|                  Cyclus                    |" << endl;
  cout << "|       a nuclear fuel cycle simulator       |" << endl;
  cout << "|  from the University of Wisconsin-Madison  |" << endl;
  cout << "|--------------------------------------------|" << endl;
  cout << endl;

  // respond to command line args
  if (vm.count("help")) {
    string err_msg = "Cyclus usage requires an input file.\n";
    err_msg += "Usage:   cyclus [path/to/input/filename]\n";
    cout << err_msg << endl;
    cout << desc << "\n";
    return 0;
  }

  if (vm.count("no-model")) {
    Logger::NoModel() = true;
  }

  if (vm.count("no-mem")) {
    Logger::NoMem() = true;
  }

  if (! vm.count("input-file")) {
    string err_msg = "Cyclus usage requires an input file.\n";
    err_msg += "Usage:   cyclus [path/to/input/filename]\n";
    cout << err_msg << endl;
    cout << desc << "\n";
    return 0;
  }

  if (vm.count("verbosity")) {
    std::string v_level = vm["verbosity"].as<string>();
    if (v_level.length() < 3) {
      Logger::ReportLevel() = (LogLevel)strtol(v_level.c_str(), NULL, 10);
    } else {
      Logger::ReportLevel() = Logger::ToLogLevel(v_level);
    }
  }

  // tell ENV the path between the cwd and the cyclus executable
  string path = Env::pathBase(argv[0]);
  Env::setCyclusRelPath(path);

  // Create the output file
  try {
    BI->createDB();
  } catch (CycException ge) {
    CLOG(LEV_ERROR) << ge.what();
  }

  // read input file and setup simulation
  try {
    XMLinput->load_file(vm["input-file"].as<string>());
  } catch (CycIOException ge) {
    CLOG(LEV_ERROR) << ge.what();
    return 0;
  } catch (CycException e) {
    CLOG(LEV_ERROR) << e.what();
  }

  Model::printModelList();
  //IsoVector::printRecipes();

  // Run the simulation
  try {
    TI->runSim();
  } catch (CycException err) {
    CLOG(LEV_ERROR) << err.what();
  }

  // Close the output file
  try {
    BI->closeDB();
  } catch (CycException ge) {
    CLOG(LEV_ERROR) << ge.what();
  }

  return 0;
}
<commit_msg>fixed cli verbosity option parsing error.<commit_after>#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include "boost/program_options.hpp"
#include "boost/shared_ptr.hpp"

#include "Model.h"
#include "BookKeeper.h"
#include "Timer.h"
#include "InputXML.h"
#include "CycException.h"
#include "Env.h"
#include "Logger.h"
#include "IsoVector.h"

using namespace std;
namespace po = boost::program_options;

//-----------------------------------------------------------------------
// Main entry point for the test application...
//-----------------------------------------------------------------------
int main(int argc, char* argv[]) {
  // verbosity help msg
  std::string vmessage = "output log verbosity. Can be text:\n\n";
  vmessage += "   LEV_ERROR (least verbose, default), LEV_WARN, \n   LEV_INFO1 (through 5), and LEV_DEBUG1 (through 5).\n\n";
  vmessage += "Or an integer:\n\n   0 (LEV_ERROR equiv) through 11 (LEV_DEBUG5 equiv)\n";

  // parse command line options
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help,h", "produce help message")
    ("no-model", "only print log entries from cyclus core code")
    ("no-mem", "exclude memory log statement from logger output")
    ("verb,v", po::value<string>(), vmessage.c_str())
    ("input-file", po::value<string>(), "input file")
    ;

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  po::positional_options_description p;
  p.add("input-file", 1);

  //po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).
            options(desc).positional(p).run(), vm);
  po::notify(vm);

  // announce yourself
  cout << endl;
  cout << "|--------------------------------------------|" << endl;
  cout << "|                  Cyclus                    |" << endl;
  cout << "|       a nuclear fuel cycle simulator       |" << endl;
  cout << "|  from the University of Wisconsin-Madison  |" << endl;
  cout << "|--------------------------------------------|" << endl;
  cout << endl;

  // respond to command line args
  if (vm.count("help")) {
    string err_msg = "Cyclus usage requires an input file.\n";
    err_msg += "Usage:   cyclus [path/to/input/filename]\n";
    cout << err_msg << endl;
    cout << desc << "\n";
    return 0;
  }

  if (vm.count("no-model")) {
    Logger::NoModel() = true;
  }

  if (vm.count("no-mem")) {
    Logger::NoMem() = true;
  }

  if (! vm.count("input-file")) {
    string err_msg = "Cyclus usage requires an input file.\n";
    err_msg += "Usage:   cyclus [path/to/input/filename]\n";
    cout << err_msg << endl;
    cout << desc << "\n";
    return 0;
  }

  if (vm.count("verb")) {
    std::string v_level = vm["verb"].as<string>();
    if (v_level.length() < 3) {
      Logger::ReportLevel() = (LogLevel)strtol(v_level.c_str(), NULL, 10);
    } else {
      Logger::ReportLevel() = Logger::ToLogLevel(v_level);
    }
  }

  // tell ENV the path between the cwd and the cyclus executable
  string path = Env::pathBase(argv[0]);
  Env::setCyclusRelPath(path);

  // Create the output file
  try {
    BI->createDB();
  } catch (CycException ge) {
    CLOG(LEV_ERROR) << ge.what();
  }

  // read input file and setup simulation
  try {
    XMLinput->load_file(vm["input-file"].as<string>());
  } catch (CycIOException ge) {
    CLOG(LEV_ERROR) << ge.what();
    return 0;
  } catch (CycException e) {
    CLOG(LEV_ERROR) << e.what();
  }

  Model::printModelList();
  //IsoVector::printRecipes();

  // Run the simulation
  try {
    TI->runSim();
  } catch (CycException err) {
    CLOG(LEV_ERROR) << err.what();
  }

  // Close the output file
  try {
    BI->closeDB();
  } catch (CycException ge) {
    CLOG(LEV_ERROR) << ge.what();
  }

  return 0;
}
<|endoftext|>


<commit_before>#ifndef _SDD_HOM_SATURATION_SUM_HH_
#define _SDD_HOM_SATURATION_SUM_HH_

#include <algorithm>  // all_of, copy
#include <iosfwd>
#include <stdexcept>  //invalid_argument
#include <vector>

#include <boost/container/flat_set.hpp>
#include <boost/optional.hpp>

#include "sdd/dd/definition.hh"
#include "sdd/hom/context_fwd.hh"
#include "sdd/hom/definition_fwd.hh"
#include "sdd/hom/identity.hh"
#include "sdd/hom/local.hh"
#include "sdd/hom/sum.hh"

namespace sdd { namespace hom {

/*-------------------------------------------------------------------------------------------*/

/// @cond INTERNAL_DOC

/// @brief Saturation Sum homomorphism.
template <typename C>
class saturation_sum
{
public:

  /// @brief The type of an optional homomorphism.
  typedef boost::optional<homomorphism<C>> optional_type;

  /// @brief The variable type.
  typedef typename C::Variable variable_type;

  /// @brief The type of the homomorphism G part.
  typedef boost::container::flat_set<homomorphism<C>> g_type;

private:

  /// @brief The variable on which this sum works.
  const variable_type variable_;

  /// @brief The homomorphism's F part.
  const optional_type F_;

  /// @brief The homomorphism's G part.
  const g_type G_;

  /// @brief The homomorphism's L part.
  const optional_type L_;

public:

  /// @brief Constructor.
  saturation_sum( const variable_type& var, const optional_type& f, g_type&& g
                , const optional_type& l)
    : variable_(var)
    , F_(f)
    , G_(std::move(g))
    , L_(l)
  {
  }

  /// @brief Evaluation.
  SDD<C>
  operator()(context<C>& cxt, const SDD<C>& s)
  const
  {
    sum_builder<C, SDD<C>> sum_operands(G_.size() + 2);

    if (F_)
    {
      sum_operands.add((*F_)(cxt, s));
    }

    for (const auto& g : G_)
    {
      sum_operands.add(g(cxt, s));
    }

    if (L_)
    {
      sum_operands.add((*L_)(cxt, s));
    }

    try
    {
      return sdd::sum(cxt.sdd_context(), std::move(sum_operands));
    }
    catch (top<C>& t)
    {
      evaluation_error<C> e(s);
      e.add_top(t);
      throw e;
    }
  }

  /// @brief Skip variable predicate.
  bool
  skip(const typename C::Variable& v)
  const noexcept
  {
    return variable_ != v;
  }

  /// @brief Selector predicate.
  bool
  selector()
  const noexcept
  {
    return (F_ ? F_->selector() : true)
       and (L_ ? L_->selector() : true)
       and std::all_of( G_.begin(), G_.end()
                      , [&](const homomorphism<C>& h){return h.selector();});
  }

  /// @brief Get the targeted variable.
  const variable_type&
  variable()
  const noexcept
  {
    return variable_;
  }

  /// @brief Get the forwardable part.
  const optional_type&
  F()
  const noexcept
  {
    return F_;
  }

  /// @brief Get the global part.
  const g_type&
  G()
  const noexcept
  {
    return G_;
  }

  /// @brief Get the local part.
  const optional_type&
  L()
  const noexcept
  {
    return L_;
  }
};

/*-------------------------------------------------------------------------------------------*/

/// @brief Equality of two saturation_sum.
/// @related saturation_sum
template <typename C>
inline
bool
operator==(const saturation_sum<C>& lhs, const saturation_sum<C>& rhs)
noexcept
{
  return lhs.variable() == rhs.variable()
     and lhs.F() == rhs.F()
     and lhs.L() == rhs.L()
     and lhs.G() == rhs.G();
}

/// @related sum
template <typename C>
std::ostream&
operator<<(std::ostream& os, const saturation_sum<C>& s)
{
  os << "Sat(@" << (int)s.variable() << ",  ";
  if (s.F())
  {
    os << *s.F();
  }
  os << " + ";
  if (s.L())
  {
    os << *s.L();
  }
  if (not s.G().empty())
  {
    os << " + ";
    std::copy( s.G().begin(), std::prev(s.G().end())
             , std::ostream_iterator<homomorphism<C>>(os, " + "));
    os << *std::prev(s.G().end()) << ")";
  }
  return os;
}

/// @endcond

/*-------------------------------------------------------------------------------------------*/

/// @brief Create the Saturation Sum homomorphism.
/// @related homomorphism
///
/// We suppose that a saturation sum is created in the rewriting process. Thus, we assume that
/// operands of the G part are already optimized (local merged and sums flatten).
template <typename C, typename InputIterator>
homomorphism<C>
SaturationSum( const typename C::Variable& var
             , const typename saturation_sum<C>::optional_type& f
             , InputIterator gbegin, InputIterator gend
             , const typename saturation_sum<C>::optional_type& l)
{
  const std::size_t g_size = std::distance(gbegin, gend);

  if (f and g_size == 0 and not l)
  {
    return *f;
  }

  if (not f and g_size > 1 and not l)
  {
    return Sum<C>(gbegin, gend);
  }

  if (not f and g_size == 0 and l)
  {
    return *l;
  }

  return homomorphism<C>::create( internal::mem::construct<saturation_sum<C>>()
                                , var
                                , f
                                , typename saturation_sum<C>::g_type(gbegin, gend)
                                , l);
}

/*-------------------------------------------------------------------------------------------*/

}} // namespace sdd::hom

namespace std {

/*-------------------------------------------------------------------------------------------*/

/// @cond INTERNAL_DOC

/// @brief Hash specialization for sdd::hom::saturation_sum.
template <typename C>
struct hash<sdd::hom::saturation_sum<C>>
{
  std::size_t
  operator()(const sdd::hom::saturation_sum<C>& s)
  const noexcept
  {
    std::size_t seed = 0;
    sdd::internal::util::hash_combine(seed, s.variable());
    if (s.F())
    {
      sdd::internal::util::hash_combine(seed, *s.F());
    }
    if (s.L())
    {
      sdd::internal::util::hash_combine(seed, *s.L());
    }
    for (const auto& g : s.G())
    {
      sdd::internal::util::hash_combine(seed, g);
    }
    return seed;
  }
};

/// @endcond

/*-------------------------------------------------------------------------------------------*/

} // namespace std

#endif // _SDD_HOM_SATURATION_SUM_HH_
<commit_msg>Remove redundant test.<commit_after>#ifndef _SDD_HOM_SATURATION_SUM_HH_
#define _SDD_HOM_SATURATION_SUM_HH_

#include <algorithm>  // all_of, copy
#include <iosfwd>
#include <stdexcept>  //invalid_argument
#include <vector>

#include <boost/container/flat_set.hpp>
#include <boost/optional.hpp>

#include "sdd/dd/definition.hh"
#include "sdd/hom/context_fwd.hh"
#include "sdd/hom/definition_fwd.hh"
#include "sdd/hom/identity.hh"
#include "sdd/hom/local.hh"
#include "sdd/hom/sum.hh"

namespace sdd { namespace hom {

/*-------------------------------------------------------------------------------------------*/

/// @cond INTERNAL_DOC

/// @brief Saturation Sum homomorphism.
template <typename C>
class saturation_sum
{
public:

  /// @brief The type of an optional homomorphism.
  typedef boost::optional<homomorphism<C>> optional_type;

  /// @brief The variable type.
  typedef typename C::Variable variable_type;

  /// @brief The type of the homomorphism G part.
  typedef boost::container::flat_set<homomorphism<C>> g_type;

private:

  /// @brief The variable on which this sum works.
  const variable_type variable_;

  /// @brief The homomorphism's F part.
  const optional_type F_;

  /// @brief The homomorphism's G part.
  const g_type G_;

  /// @brief The homomorphism's L part.
  const optional_type L_;

public:

  /// @brief Constructor.
  saturation_sum( const variable_type& var, const optional_type& f, g_type&& g
                , const optional_type& l)
    : variable_(var)
    , F_(f)
    , G_(std::move(g))
    , L_(l)
  {
  }

  /// @brief Evaluation.
  SDD<C>
  operator()(context<C>& cxt, const SDD<C>& s)
  const
  {
    sum_builder<C, SDD<C>> sum_operands(G_.size() + 2);

    if (F_)
    {
      sum_operands.add((*F_)(cxt, s));
    }

    for (const auto& g : G_)
    {
      sum_operands.add(g(cxt, s));
    }

    if (L_)
    {
      sum_operands.add((*L_)(cxt, s));
    }

    try
    {
      return sdd::sum(cxt.sdd_context(), std::move(sum_operands));
    }
    catch (top<C>& t)
    {
      evaluation_error<C> e(s);
      e.add_top(t);
      throw e;
    }
  }

  /// @brief Skip variable predicate.
  bool
  skip(const typename C::Variable& v)
  const noexcept
  {
    return variable_ != v;
  }

  /// @brief Selector predicate.
  bool
  selector()
  const noexcept
  {
    return (F_ ? F_->selector() : true)
       and (L_ ? L_->selector() : true)
       and std::all_of( G_.begin(), G_.end()
                      , [&](const homomorphism<C>& h){return h.selector();});
  }

  /// @brief Get the targeted variable.
  const variable_type&
  variable()
  const noexcept
  {
    return variable_;
  }

  /// @brief Get the forwardable part.
  const optional_type&
  F()
  const noexcept
  {
    return F_;
  }

  /// @brief Get the global part.
  const g_type&
  G()
  const noexcept
  {
    return G_;
  }

  /// @brief Get the local part.
  const optional_type&
  L()
  const noexcept
  {
    return L_;
  }
};

/*-------------------------------------------------------------------------------------------*/

/// @brief Equality of two saturation_sum.
/// @related saturation_sum
template <typename C>
inline
bool
operator==(const saturation_sum<C>& lhs, const saturation_sum<C>& rhs)
noexcept
{
  return lhs.variable() == rhs.variable()
     and lhs.F() == rhs.F()
     and lhs.L() == rhs.L()
     and lhs.G() == rhs.G();
}

/// @related sum
template <typename C>
std::ostream&
operator<<(std::ostream& os, const saturation_sum<C>& s)
{
  os << "Sat(@" << (int)s.variable() << ",  ";
  if (s.F())
  {
    os << *s.F();
  }
  os << " + ";
  if (s.L())
  {
    os << *s.L();
  }
  if (not s.G().empty())
  {
    os << " + ";
    std::copy( s.G().begin(), std::prev(s.G().end())
             , std::ostream_iterator<homomorphism<C>>(os, " + "));
    os << *std::prev(s.G().end()) << ")";
  }
  return os;
}

/// @endcond

/*-------------------------------------------------------------------------------------------*/

/// @brief Create the Saturation Sum homomorphism.
/// @related homomorphism
///
/// We suppose that a saturation sum is created in the rewriting process. Thus, we assume that
/// operands of the G part are already optimized (local merged and sums flatten).
template <typename C, typename InputIterator>
homomorphism<C>
SaturationSum( const typename C::Variable& var
             , const typename saturation_sum<C>::optional_type& f
             , InputIterator gbegin, InputIterator gend
             , const typename saturation_sum<C>::optional_type& l)
{
  const std::size_t g_size = std::distance(gbegin, gend);

  if (f and g_size == 0 and not l)
  {
    return *f;
  }

  if (not f and g_size == 0 and l)
  {
    return *l;
  }

  return homomorphism<C>::create( internal::mem::construct<saturation_sum<C>>()
                                , var
                                , f
                                , typename saturation_sum<C>::g_type(gbegin, gend)
                                , l);
}

/*-------------------------------------------------------------------------------------------*/

}} // namespace sdd::hom

namespace std {

/*-------------------------------------------------------------------------------------------*/

/// @cond INTERNAL_DOC

/// @brief Hash specialization for sdd::hom::saturation_sum.
template <typename C>
struct hash<sdd::hom::saturation_sum<C>>
{
  std::size_t
  operator()(const sdd::hom::saturation_sum<C>& s)
  const noexcept
  {
    std::size_t seed = 0;
    sdd::internal::util::hash_combine(seed, s.variable());
    if (s.F())
    {
      sdd::internal::util::hash_combine(seed, *s.F());
    }
    if (s.L())
    {
      sdd::internal::util::hash_combine(seed, *s.L());
    }
    for (const auto& g : s.G())
    {
      sdd::internal::util::hash_combine(seed, g);
    }
    return seed;
  }
};

/// @endcond

/*-------------------------------------------------------------------------------------------*/

} // namespace std

#endif // _SDD_HOM_SATURATION_SUM_HH_
<|endoftext|>


<commit_before>// Copyright (c) 2016-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <amount.h>
#include <policy/feerate.h>
#include <test/test_chaincoin.h>

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(amount_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(MoneyRangeTest)
{
    BOOST_CHECK_EQUAL(MoneyRange(CAmount(-1)), false);
    BOOST_CHECK_EQUAL(MoneyRange(MAX_MONEY + CAmount(1)), false);
    BOOST_CHECK_EQUAL(MoneyRange(CAmount(1)), true);
}

BOOST_AUTO_TEST_CASE(GetFeeTest)
{
    CFeeRate feeRate, altFeeRate;

    feeRate = CFeeRate(0);
    // Must always return 0
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0);
    BOOST_CHECK_EQUAL(feeRate.GetFee(1e5), 0);

    feeRate = CFeeRate(1000);
    // Must always just return the arg
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0);
    BOOST_CHECK_EQUAL(feeRate.GetFee(1), 1);
    BOOST_CHECK_EQUAL(feeRate.GetFee(121), 121);
    BOOST_CHECK_EQUAL(feeRate.GetFee(999), 999);
    BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), 1e3);
    BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), 9e3);

    feeRate = CFeeRate(-1000);
    // Must always just return -1 * arg
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0);
    BOOST_CHECK_EQUAL(feeRate.GetFee(1), -1);
    BOOST_CHECK_EQUAL(feeRate.GetFee(121), -121);
    BOOST_CHECK_EQUAL(feeRate.GetFee(999), -999);
    BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), -1e3);
    BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), -9e3);

    feeRate = CFeeRate(123);
    // Truncates the result, if not integer
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0);
    BOOST_CHECK_EQUAL(feeRate.GetFee(8), 1); // Special case: returns 1 instead of 0
    BOOST_CHECK_EQUAL(feeRate.GetFee(9), 1);
    BOOST_CHECK_EQUAL(feeRate.GetFee(121), 14);
    BOOST_CHECK_EQUAL(feeRate.GetFee(122), 15);
    BOOST_CHECK_EQUAL(feeRate.GetFee(999), 122);
    BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), 123);
    BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), 1107);

    feeRate = CFeeRate(-123);
    // Truncates the result, if not integer
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0);
    BOOST_CHECK_EQUAL(feeRate.GetFee(8), -1); // Special case: returns -1 instead of 0
    BOOST_CHECK_EQUAL(feeRate.GetFee(9), -1);

    // check alternate constructor
    feeRate = CFeeRate(1000);
    altFeeRate = CFeeRate(feeRate);
    BOOST_CHECK_EQUAL(feeRate.GetFee(100), altFeeRate.GetFee(100));

    // Check full constructor
    // default value
    BOOST_CHECK(CFeeRate(CAmount(-1), 1000) == CFeeRate(-1));
    BOOST_CHECK(CFeeRate(CAmount(0), 1000) == CFeeRate(0));
    BOOST_CHECK(CFeeRate(CAmount(1), 1000) == CFeeRate(1));
    // lost precision (can only resolve satoshis per kB)
    BOOST_CHECK(CFeeRate(CAmount(1), 1001) == CFeeRate(0));
    BOOST_CHECK(CFeeRate(CAmount(2), 1001) == CFeeRate(1));
    // some more integer checks
    BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32));
    BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34));
    // Maximum size in bytes, should not crash
    CFeeRate(MAX_MONEY, std::numeric_limits<size_t>::max() >> 1).GetFeePerK();
}

BOOST_AUTO_TEST_CASE(BinaryOperatorTest)
{
    CFeeRate a, b;
    a = CFeeRate(1);
    b = CFeeRate(2);
    BOOST_CHECK(a < b);
    BOOST_CHECK(b > a);
    BOOST_CHECK(a == a);
    BOOST_CHECK(a <= b);
    BOOST_CHECK(a <= a);
    BOOST_CHECK(b >= a);
    BOOST_CHECK(b >= b);
    // a should be 0.00000002 CTC/kB now
    a += a;
    BOOST_CHECK(a == b);
}

BOOST_AUTO_TEST_CASE(ToStringTest)
{
    CFeeRate feeRate;
    feeRate = CFeeRate(1);
    BOOST_CHECK_EQUAL(feeRate.ToString(), "0.00000001 CHC/kB");
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Improve CAmount tests<commit_after>// Copyright (c) 2016-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <amount.h>
#include <policy/feerate.h>
#include <test/test_chaincoin.h>

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(amount_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(MoneyRangeTest)
{
    BOOST_CHECK_EQUAL(MoneyRange(CAmount(-1)), false);
    BOOST_CHECK_EQUAL(MoneyRange(CAmount(0)), true);
    BOOST_CHECK_EQUAL(MoneyRange(CAmount(1)), true);
    BOOST_CHECK_EQUAL(MoneyRange(MAX_MONEY), true);
    BOOST_CHECK_EQUAL(MoneyRange(MAX_MONEY + CAmount(1)), false);
}

BOOST_AUTO_TEST_CASE(GetFeeTest)
{
    CFeeRate feeRate, altFeeRate;

    feeRate = CFeeRate(0);
    // Must always return 0
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
    BOOST_CHECK_EQUAL(feeRate.GetFee(1e5), CAmount(0));

    feeRate = CFeeRate(1000);
    // Must always just return the arg
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
    BOOST_CHECK_EQUAL(feeRate.GetFee(1), CAmount(1));
    BOOST_CHECK_EQUAL(feeRate.GetFee(121), CAmount(121));
    BOOST_CHECK_EQUAL(feeRate.GetFee(999), CAmount(999));
    BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), CAmount(1e3));
    BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), CAmount(9e3));

    feeRate = CFeeRate(-1000);
    // Must always just return -1 * arg
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
    BOOST_CHECK_EQUAL(feeRate.GetFee(1), CAmount(-1));
    BOOST_CHECK_EQUAL(feeRate.GetFee(121), CAmount(-121));
    BOOST_CHECK_EQUAL(feeRate.GetFee(999), CAmount(-999));
    BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), CAmount(-1e3));
    BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), CAmount(-9e3));

    feeRate = CFeeRate(123);
    // Truncates the result, if not integer
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
    BOOST_CHECK_EQUAL(feeRate.GetFee(8), CAmount(1)); // Special case: returns 1 instead of 0
    BOOST_CHECK_EQUAL(feeRate.GetFee(9), CAmount(1));
    BOOST_CHECK_EQUAL(feeRate.GetFee(121), CAmount(14));
    BOOST_CHECK_EQUAL(feeRate.GetFee(122), CAmount(15));
    BOOST_CHECK_EQUAL(feeRate.GetFee(999), CAmount(122));
    BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), CAmount(123));
    BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), CAmount(1107));

    feeRate = CFeeRate(-123);
    // Truncates the result, if not integer
    BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
    BOOST_CHECK_EQUAL(feeRate.GetFee(8), CAmount(-1)); // Special case: returns -1 instead of 0
    BOOST_CHECK_EQUAL(feeRate.GetFee(9), CAmount(-1));

    // check alternate constructor
    feeRate = CFeeRate(1000);
    altFeeRate = CFeeRate(feeRate);
    BOOST_CHECK_EQUAL(feeRate.GetFee(100), altFeeRate.GetFee(100));

    // Check full constructor
    BOOST_CHECK(CFeeRate(CAmount(-1), 0) == CFeeRate(0));
    BOOST_CHECK(CFeeRate(CAmount(0), 0) == CFeeRate(0));
    BOOST_CHECK(CFeeRate(CAmount(1), 0) == CFeeRate(0));
    // default value
    BOOST_CHECK(CFeeRate(CAmount(-1), 1000) == CFeeRate(-1));
    BOOST_CHECK(CFeeRate(CAmount(0), 1000) == CFeeRate(0));
    BOOST_CHECK(CFeeRate(CAmount(1), 1000) == CFeeRate(1));
    // lost precision (can only resolve satoshis per kB)
    BOOST_CHECK(CFeeRate(CAmount(1), 1001) == CFeeRate(0));
    BOOST_CHECK(CFeeRate(CAmount(2), 1001) == CFeeRate(1));
    // some more integer checks
    BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32));
    BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34));
    // Maximum size in bytes, should not crash
    CFeeRate(MAX_MONEY, std::numeric_limits<size_t>::max() >> 1).GetFeePerK();
}

BOOST_AUTO_TEST_CASE(BinaryOperatorTest)
{
    CFeeRate a, b;
    a = CFeeRate(1);
    b = CFeeRate(2);
    BOOST_CHECK(a < b);
    BOOST_CHECK(b > a);
    BOOST_CHECK(a == a);
    BOOST_CHECK(a <= b);
    BOOST_CHECK(a <= a);
    BOOST_CHECK(b >= a);
    BOOST_CHECK(b >= b);
    // a should be 0.00000002 CTC/kB now
    a += a;
    BOOST_CHECK(a == b);
}

BOOST_AUTO_TEST_CASE(ToStringTest)
{
    CFeeRate feeRate;
    feeRate = CFeeRate(1);
    BOOST_CHECK_EQUAL(feeRate.ToString(), "0.00000001 CHC/kB");
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <sys/time.h>

// This is a simple speed test to compare suppressing a signal/slot
// emission by one of two methods:
//
// 1) disconnect and reconnect the signal/slot.
//
// 2) define a bool suppress_ member which makes the slot do nothing.
//
// Results for Qt 4.6 are that disconnect/reconnect takes about 11
// times as long as boolean suppressor.

#include "connect_test.h"

double now()
{
  struct timeval tv;
  gettimeofday( &tv, NULL );
  return double(tv.tv_sec) + double(tv.tv_usec) / 1000000.0;
}

int main( int argc, char **argv )
{
  MyObject* obj = new MyObject;
  obj->enableChanges();

  QObject::connect( obj, SIGNAL( changed() ), obj, SLOT( onChanged() ));
  obj->emitChanged();

  double start, end;
  int count = 1000000;

  start = now();
  for( int i = 0; i < count; i++ )
  {
    QObject::disconnect( obj, SIGNAL( changed() ), obj, SLOT( onChanged() ));
    obj->emitChanged();
    QObject::connect( obj, SIGNAL( changed() ), obj, SLOT( onChanged() ));
  }
  end = now();
  printf("disconnect/emit/connect %d times took %lf seconds.\n", count, end - start );

  obj->emitChanged();

  start = now();
  for( int i = 0; i < count; i++ )
  {
    obj->suppressChanges();
    obj->emitChanged();
    obj->enableChanges();
  }
  end = now();
  printf("suppress/emit/enable %d times took %lf seconds.\n", count, end - start );

  return 0;
}
<commit_msg>Use std::chrono to replace gettimeofday. (#1337)<commit_after>/*
 * Copyright (c) 2011, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <chrono>

// This is a simple speed test to compare suppressing a signal/slot
// emission by one of two methods:
//
// 1) disconnect and reconnect the signal/slot.
//
// 2) define a bool suppress_ member which makes the slot do nothing.
//
// Results for Qt 4.6 are that disconnect/reconnect takes about 11
// times as long as boolean suppressor.

#include "connect_test.h"

int main( int argc, char **argv )
{
  MyObject* obj = new MyObject;
  obj->enableChanges();

  QObject::connect( obj, SIGNAL( changed() ), obj, SLOT( onChanged() ));
  obj->emitChanged();

  int count = 1000000;

  auto start = std::chrono::steady_clock::now();
  for( int i = 0; i < count; i++ )
  {
    QObject::disconnect( obj, SIGNAL( changed() ), obj, SLOT( onChanged() ));
    obj->emitChanged();
    QObject::connect( obj, SIGNAL( changed() ), obj, SLOT( onChanged() ));
  }
  auto end = std::chrono::steady_clock::now();
  printf("disconnect/emit/connect %d times took %lf seconds.\n", count,
    std::chrono::duration<double>(end - start).count());

  obj->emitChanged();

  start = std::chrono::steady_clock::now();
  for( int i = 0; i < count; i++ )
  {
    obj->suppressChanges();
    obj->emitChanged();
    obj->enableChanges();
  }
  end = std::chrono::steady_clock::now();
  printf("suppress/emit/enable %d times took %lf seconds.\n", count,
    std::chrono::duration<double>(end - start).count());

  return 0;
}
<|endoftext|>