Maintenance - Mise à jour mensuelle Lundi 7 Décembre 2021 entre 7h00 et 9h00

Commit 092757e7 authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

io: add streambuf to detect line/column

parent f0845e61
Pipeline #22423 passed with stage
in 2 minutes and 20 seconds
......@@ -10,6 +10,7 @@
#include <algorithm>
#include <istream>
#include <ostream>
#include <streambuf>
#include <vector>
namespace irt {
......@@ -369,14 +370,106 @@ get_output_port_names(const dynamics_type type) noexcept
irt_unreachable();
}
class streambuf : public std::streambuf
{
public:
std::streambuf* m_stream_buffer = { nullptr };
std::streamsize m_file_position = { 0 };
int m_line_number = { 1 };
int m_last_line_number = { 1 };
int m_column = { 0 };
int m_prev_column = { -1 };
streambuf(std::streambuf* sbuf)
: m_stream_buffer(sbuf)
{}
streambuf(const streambuf&) = delete;
streambuf& operator=(const streambuf&) = delete;
protected:
std::streambuf::int_type underflow() override final
{
return m_stream_buffer->sgetc();
}
std::streambuf::int_type uflow() override final
{
int_type rc = m_stream_buffer->sbumpc();
m_last_line_number = m_line_number;
if (traits_type::eq_int_type(rc, traits_type::to_int_type('\n'))) {
++m_line_number;
m_prev_column = m_column + 1;
m_column = -1;
}
++m_column;
++m_file_position;
return rc;
}
std::streambuf::int_type pbackfail(std::streambuf::int_type c) override final
{
if (traits_type::eq_int_type(c, traits_type::to_int_type('\n'))) {
--m_line_number;
m_last_line_number = m_line_number;
m_column = m_prev_column;
m_prev_column = 0;
}
--m_column;
--m_file_position;
if (c != traits_type::eof())
return m_stream_buffer->sputbackc(traits_type::to_char_type(c));
return m_stream_buffer->sungetc();
}
std::ios::pos_type seekoff(std::ios::off_type pos,
std::ios_base::seekdir dir,
std::ios_base::openmode mode) override final
{
if (dir == std::ios_base::beg &&
pos == static_cast<std::ios::off_type>(0)) {
m_last_line_number = 1;
m_line_number = 1;
m_column = 0;
m_prev_column = -1;
m_file_position = 0;
return m_stream_buffer->pubseekoff(pos, dir, mode);
}
return std::streambuf::seekoff(pos, dir, mode);
}
std::ios::pos_type seekpos(std::ios::pos_type pos,
std::ios_base::openmode mode) override final
{
if (pos == static_cast<std::ios::pos_type>(0)) {
m_last_line_number = 1;
m_line_number = 1;
m_column = 0;
m_prev_column = -1;
m_file_position = 0;
return m_stream_buffer->pubseekpos(pos, mode);
}
return std::streambuf::seekpos(pos, mode);
}
};
class reader
{
private:
std::istream& is;
streambuf buf;
std::istream is;
std::vector<model_id> map;
int model_error = 0;
int connection_error = 0;
int model_number = 0;
char temp_1[32];
......@@ -384,18 +477,24 @@ private:
public:
reader(std::istream& is_) noexcept
: is(is_)
: buf(is_.rdbuf())
, is(&buf)
{}
~reader() noexcept = default;
int model_error = 0;
int connection_error = 0;
int line_error = 0;
int column_error = 0;
status operator()(simulation& sim) noexcept
{
irt_return_if_bad(do_read_model_number());
for (int i = 0; i != model_number; ++i, ++model_error) {
int id;
do_read_model(sim, &id);
irt_return_if_bad(do_read_model(sim, &id));
}
irt_return_if_bad(do_read_connections(sim));
......@@ -420,11 +519,19 @@ public:
}
private:
void update_error_report() noexcept
{
line_error = buf.m_line_number;
column_error = buf.m_column;
}
status do_read_model_number() noexcept
{
model_number = 0;
update_error_report();
irt_return_if_fail((is >> model_number), status::io_file_format_error);
irt_return_if_fail(model_number > 0,
status::io_file_format_model_number_error);
......@@ -439,6 +546,7 @@ private:
status do_read_model(simulation& sim, int* id) noexcept
{
update_error_report();
irt_return_if_fail((is >> *id >> temp_1),
status::io_file_format_model_error);
......@@ -455,6 +563,7 @@ private:
while (is) {
int mdl_src_id, port_src_index, mdl_dst_id, port_dst_index;
update_error_report();
if (!(is >> mdl_src_id >> port_src_index >> mdl_dst_id >>
port_dst_index)) {
if (is.eof())
......@@ -593,6 +702,7 @@ private:
sim.alloc(dyn, dyn_id);
mdl_id = dyn.id;
update_error_report();
irt_return_if_fail(read(dyn),
status::io_file_format_dynamics_init_error);
......
......@@ -678,6 +678,24 @@ main()
expect(sim.models.size() == 49);
}
{
std::string string_error{ "1\n0 qss1_integrator A B C\n" };
std::istringstream is{ string_error };
irt::simulation sim;
expect(irt::is_success(sim.init(64lu, 32lu)));
irt::is_fatal_breakpoint = false;
irt::reader r(is);
expect(irt::is_bad(r(sim)));
expect(r.line_error == 2);
expect(r.column_error == 17);
expect(r.model_error == 0);
expect(r.connection_error == 0);
irt::is_fatal_breakpoint = true;
}
};
"constant_simulation"_test = [] {
......@@ -1435,17 +1453,25 @@ main()
cross.default_threshold = Vt;
expect(sim.models.can_alloc(10));
expect((
irt::is_success(sim.alloc(sum, sim.adder_2_models.get_id(sum)))) >> fatal);
expect((irt::is_success(
sim.alloc(quantifier, sim.quantifier_models.get_id(quantifier)))) >> fatal);
expect((irt::is_success(
sim.alloc(integrator, sim.integrator_models.get_id(integrator)))) >> fatal);
expect((irt::is_success(sim.alloc(I, sim.time_func_models.get_id(I)))) >> fatal);
expect(
(irt::is_success(sim.alloc(sum, sim.adder_2_models.get_id(sum)))) >>
fatal);
expect((irt::is_success(sim.alloc(
constant_cross, sim.constant_models.get_id(constant_cross)))) >> fatal);
expect((
irt::is_success(sim.alloc(cross, sim.cross_models.get_id(cross)))) >> fatal);
quantifier, sim.quantifier_models.get_id(quantifier)))) >>
fatal);
expect((irt::is_success(sim.alloc(
integrator, sim.integrator_models.get_id(integrator)))) >>
fatal);
expect(
(irt::is_success(sim.alloc(I, sim.time_func_models.get_id(I)))) >>
fatal);
expect(
(irt::is_success(sim.alloc(
constant_cross, sim.constant_models.get_id(constant_cross)))) >>
fatal);
expect(
(irt::is_success(sim.alloc(cross, sim.cross_models.get_id(cross)))) >>
fatal);
expect((sim.models.size() == 6_ul) >> fatal);
......@@ -1614,16 +1640,22 @@ main()
cross.default_threshold = Vt;
expect(sim.models.can_alloc(10));
expect((
irt::is_success(sim.alloc(sum, sim.qss2_wsum_2_models.get_id(sum)))) >> fatal);
expect((irt::is_success(sim.alloc(
integrator, sim.qss2_integrator_models.get_id(integrator)))) >> fatal);
expect((irt::is_success(
sim.alloc(constant, sim.constant_models.get_id(constant)))) >> fatal);
sim.alloc(sum, sim.qss2_wsum_2_models.get_id(sum)))) >>
fatal);
expect((irt::is_success(sim.alloc(
constant_cross, sim.constant_models.get_id(constant_cross)))) >> fatal);
integrator, sim.qss2_integrator_models.get_id(integrator)))) >>
fatal);
expect((irt::is_success(
sim.alloc(cross, sim.qss2_cross_models.get_id(cross)))) >> fatal);
sim.alloc(constant, sim.constant_models.get_id(constant)))) >>
fatal);
expect(
(irt::is_success(sim.alloc(
constant_cross, sim.constant_models.get_id(constant_cross)))) >>
fatal);
expect((irt::is_success(
sim.alloc(cross, sim.qss2_cross_models.get_id(cross)))) >>
fatal);
expect((sim.models.size() == 5_ul) >> fatal);
......@@ -1726,32 +1758,46 @@ main()
sum_d.default_input_coeffs[1] = d;
expect((sim.models.can_alloc(12)) >> fatal);
expect((irt::is_success(sim.alloc(
constant3, sim.constant_models.get_id(constant3)))) >>
fatal);
expect((irt::is_success(
sim.alloc(constant3, sim.constant_models.get_id(constant3)))) >> fatal);
expect((irt::is_success(
sim.alloc(constant, sim.constant_models.get_id(constant)))) >> fatal);
expect((irt::is_success(
sim.alloc(constant2, sim.constant_models.get_id(constant2)))) >> fatal);
sim.alloc(constant, sim.constant_models.get_id(constant)))) >>
fatal);
expect((irt::is_success(sim.alloc(
constant2, sim.constant_models.get_id(constant2)))) >>
fatal);
expect((irt::is_success(
sim.alloc(sum_a, sim.qss1_wsum_2_models.get_id(sum_a)))) >> fatal);
sim.alloc(sum_a, sim.qss1_wsum_2_models.get_id(sum_a)))) >>
fatal);
expect((irt::is_success(
sim.alloc(sum_b, sim.qss1_wsum_2_models.get_id(sum_b)))) >> fatal);
sim.alloc(sum_b, sim.qss1_wsum_2_models.get_id(sum_b)))) >>
fatal);
expect((irt::is_success(
sim.alloc(sum_c, sim.qss1_wsum_4_models.get_id(sum_c)))) >> fatal);
sim.alloc(sum_c, sim.qss1_wsum_4_models.get_id(sum_c)))) >>
fatal);
expect((irt::is_success(
sim.alloc(sum_d, sim.qss1_wsum_2_models.get_id(sum_d)))) >> fatal);
sim.alloc(sum_d, sim.qss1_wsum_2_models.get_id(sum_d)))) >>
fatal);
expect((irt::is_success(
sim.alloc(product, sim.qss1_multiplier_models.get_id(product)))) >> fatal);
expect((irt::is_success(sim.alloc(
integrator_a, sim.qss1_integrator_models.get_id(integrator_a)))) >> fatal);
expect((irt::is_success(sim.alloc(
integrator_b, sim.qss1_integrator_models.get_id(integrator_b)))) >> fatal);
product, sim.qss1_multiplier_models.get_id(product)))) >>
fatal);
expect(
(irt::is_success(sim.alloc(
integrator_a, sim.qss1_integrator_models.get_id(integrator_a)))) >>
fatal);
expect(
(irt::is_success(sim.alloc(
integrator_b, sim.qss1_integrator_models.get_id(integrator_b)))) >>
fatal);
expect((irt::is_success(
sim.alloc(cross, sim.qss1_cross_models.get_id(cross)))) >> fatal);
sim.alloc(cross, sim.qss1_cross_models.get_id(cross)))) >>
fatal);
expect((irt::is_success(
sim.alloc(cross2, sim.qss1_cross_models.get_id(cross2)))) >> fatal);
sim.alloc(cross2, sim.qss1_cross_models.get_id(cross2)))) >>
fatal);
expect((sim.models.size() == 12_ul) >> fatal);
......@@ -2128,16 +2174,22 @@ main()
cross.default_threshold = Vt;
expect(sim.models.can_alloc(10));
expect((
irt::is_success(sim.alloc(sum, sim.qss3_wsum_2_models.get_id(sum)))) >> fatal);
expect((irt::is_success(sim.alloc(
integrator, sim.qss3_integrator_models.get_id(integrator)))) >> fatal);
expect((irt::is_success(
sim.alloc(constant, sim.constant_models.get_id(constant)))) >> fatal);
sim.alloc(sum, sim.qss3_wsum_2_models.get_id(sum)))) >>
fatal);
expect((irt::is_success(sim.alloc(
constant_cross, sim.constant_models.get_id(constant_cross)))) >> fatal);
integrator, sim.qss3_integrator_models.get_id(integrator)))) >>
fatal);
expect((irt::is_success(
sim.alloc(constant, sim.constant_models.get_id(constant)))) >>
fatal);
expect(
(irt::is_success(sim.alloc(
constant_cross, sim.constant_models.get_id(constant_cross)))) >>
fatal);
expect((irt::is_success(
sim.alloc(cross, sim.qss3_cross_models.get_id(cross)))) >> fatal);
sim.alloc(cross, sim.qss3_cross_models.get_id(cross)))) >>
fatal);
expect((sim.models.size() == 5_ul) >> fatal);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment