Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gauthier Quesnel
irritator
Commits
092757e7
Commit
092757e7
authored
Nov 26, 2020
by
Gauthier Quesnel
Browse files
io: add streambuf to detect line/column
parent
f0845e61
Pipeline
#22423
passed with stage
in 2 minutes and 20 seconds
Changes
2
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
lib/include/irritator/io.hpp
View file @
092757e7
...
...
@@ -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
);
...
...
lib/test/public-api.cpp
View file @
092757e7
...
...
@@ -678,6 +678,24 @@ main()
expect
(
sim
.
models
.
size
()
==
49
);
}
{
std
::
string
string_error
{
"1
\n
0 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
(
constant
3
,
sim
.
constant_models
.
get_id
(
constant
3
))))
>>
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
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment