Commit 73130e7e authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

io: use c++ stream to fix Win32 FS API

parent 33871967
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "imnodes.hpp" #include "imnodes.hpp"
#include <filesystem> #include <filesystem>
#include <fstream>
#include <future> #include <future>
#include <mutex> #include <mutex>
#include <string> #include <string>
...@@ -733,12 +734,14 @@ struct editor ...@@ -733,12 +734,14 @@ struct editor
if (!path.empty() && ImGui::MenuItem("Save")) { if (!path.empty() && ImGui::MenuItem("Save")) {
log_w.log(3, "Write into file %s\n", path.string().c_str()); log_w.log(3, "Write into file %s\n", path.string().c_str());
writer w(std::fopen(path.string().c_str(), "w")); if (auto os = std::ofstream(path); os.is_open()) {
auto ret = w(sim); writer w(os);
if (is_success(ret)) auto ret = w(sim);
log_w.log(5, "success\n"); if (is_success(ret))
else log_w.log(5, "success\n");
log_w.log(4, "error writing\n"); else
log_w.log(4, "error writing\n");
}
} }
if (ImGui::MenuItem("Save as...")) if (ImGui::MenuItem("Save as..."))
...@@ -788,12 +791,14 @@ struct editor ...@@ -788,12 +791,14 @@ struct editor
if (load_file_dialog(path)) { if (load_file_dialog(path)) {
show_load_file_dialog = false; show_load_file_dialog = false;
log_w.log(5, "Load file from %s\n", path.string().c_str()); log_w.log(5, "Load file from %s\n", path.string().c_str());
reader r(std::fopen(path.string().c_str(), "r")); if (auto is = std::ifstream(path); is.is_open()) {
auto ret = r(sim); reader r(is);
if (is_success(ret)) auto ret = r(sim);
log_w.log(5, "success\n"); if (is_success(ret))
else log_w.log(5, "success\n");
log_w.log(4, "error writing\n"); else
log_w.log(4, "error writing\n");
}
} }
} }
...@@ -809,12 +814,14 @@ struct editor ...@@ -809,12 +814,14 @@ struct editor
log_w.log(5, "Save file to %s\n", path.string().c_str()); log_w.log(5, "Save file to %s\n", path.string().c_str());
log_w.log(3, "Write into file %s\n", path.string().c_str()); log_w.log(3, "Write into file %s\n", path.string().c_str());
writer w(std::fopen(path.string().c_str(), "w")); if (auto os = std::ofstream(path); os.is_open()) {
auto ret = w(sim); writer w(os);
if (is_success(ret)) auto ret = w(sim);
log_w.log(5, "success\n"); if (is_success(ret))
else log_w.log(5, "success\n");
log_w.log(4, "error writing\n"); else
log_w.log(4, "error writing\n");
}
} }
} }
......
...@@ -8,37 +8,35 @@ ...@@ -8,37 +8,35 @@
#include <irritator/core.hpp> #include <irritator/core.hpp>
#include <algorithm> #include <algorithm>
#include <istream>
#include <cstdio> #include <ostream>
namespace irt { namespace irt {
class reader class reader
{ {
private: private:
::std::FILE* file = stdin; std::istream& is;
array<model_id> map; array<model_id> map;
int model_error = 0; int model_error = 0;
int connection_error = 0; int connection_error = 0;
char temp_1[32];
char temp_2[32];
public: public:
reader(::std::FILE* file_ = stdin) noexcept reader(std::istream& is_) noexcept
: file(file_ == nullptr ? stdin : file_) : is(is_)
{} {}
~reader() noexcept ~reader() noexcept = default;
{
if (file && file != stdin)
::std::fclose(file);
}
status operator()(simulation& sim) noexcept status operator()(simulation& sim) noexcept
{ {
int model_number = 0; int model_number = 0;
irt_return_if_fail(std::fscanf(file, "%d", &model_number) == 1, irt_return_if_fail((is >> model_number), status::io_file_format_error);
status::io_file_format_error);
irt_return_if_fail(model_number > 0, irt_return_if_fail(model_number > 0,
status::io_file_format_model_number_error); status::io_file_format_model_number_error);
...@@ -47,130 +45,119 @@ public: ...@@ -47,130 +45,119 @@ public:
std::fill_n(std::begin(map), std::size(map), static_cast<model_id>(0)); std::fill_n(std::begin(map), std::size(map), static_cast<model_id>(0));
int id; int id;
char name[8];
char dynamics[11];
for (int i = 0; i != model_number; ++i, ++model_error) { for (int i = 0; i != model_number; ++i, ++model_error) {
irt_return_if_fail( irt_return_if_fail((is >> id >> temp_1 >> temp_2),
3 == std::fscanf(file, "%d %7s %10s", &id, name, dynamics), status::io_file_format_model_error);
status::io_file_format_model_error);
irt_return_if_fail(0 <= id && id < model_number, irt_return_if_fail(0 <= id && id < model_number,
status::io_file_format_model_error); status::io_file_format_model_error);
irt_return_if_bad(read(sim, id, name, dynamics)); irt_return_if_bad(read(sim, id, temp_1, temp_2));
} }
while (!std::feof(file)) { while (is) {
int mdl_src_index, port_src_index, mdl_dst_index, port_dst_index; int mdl_src_index, port_src_index, mdl_dst_index, port_dst_index;
int read = std::fscanf(file, if (!(is >> mdl_src_index >> port_src_index >> mdl_dst_index >>
"%d %d %d %d", port_dst_index)) {
&mdl_src_index, if (is.eof())
&port_src_index, break;
&mdl_dst_index,
&port_dst_index);
irt_return_if_fail(read == -1 || read == 0 || read == 4, irt_bad_return(status::io_file_format_error);
status::io_file_format_error); }
if (read == -1)
break;
if (read == 4) { auto* mdl_src = sim.models.try_to_get(mdl_src_index);
auto* mdl_src = sim.models.try_to_get(mdl_src_index); irt_return_if_fail(mdl_src, status::io_file_format_model_unknown);
irt_return_if_fail(mdl_src,
status::io_file_format_model_unknown);
auto* mdl_dst = sim.models.try_to_get(mdl_dst_index); auto* mdl_dst = sim.models.try_to_get(mdl_dst_index);
irt_return_if_fail(mdl_dst, irt_return_if_fail(mdl_dst, status::io_file_format_model_unknown);
status::io_file_format_model_unknown);
output_port_id output_port; output_port_id output_port;
input_port_id input_port; input_port_id input_port;
irt_return_if_bad(sim.get_output_port_id( irt_return_if_bad(
*mdl_src, port_src_index, &output_port)); sim.get_output_port_id(*mdl_src, port_src_index, &output_port));
irt_return_if_bad( irt_return_if_bad(
sim.get_input_port_id(*mdl_dst, port_dst_index, &input_port)); sim.get_input_port_id(*mdl_dst, port_dst_index, &input_port));
irt_return_if_bad(sim.connect(output_port, input_port)); irt_return_if_bad(sim.connect(output_port, input_port));
++connection_error; ++connection_error;
}
} }
return status::success; return status::success;
} }
private: private:
bool convert(const char* dynamics_name, dynamics_type* type) noexcept bool convert(const std::string_view dynamics_name,
dynamics_type* type) noexcept
{ {
if (std::strcmp(dynamics_name, "none") == 0) { if (dynamics_name == "none") {
*type = dynamics_type::none; *type = dynamics_type::none;
return true; return true;
} }
if (std::strcmp(dynamics_name, "integrator") == 0) { if (dynamics_name == "integrator") {
*type = dynamics_type::integrator; *type = dynamics_type::integrator;
return true; return true;
} }
if (std::strcmp(dynamics_name, "quantifier") == 0) { if (dynamics_name == "quantifier") {
*type = dynamics_type::quantifier; *type = dynamics_type::quantifier;
return true; return true;
} }
if (std::strcmp(dynamics_name, "adder_2") == 0) { if (dynamics_name == "adder_2") {
*type = dynamics_type::adder_2; *type = dynamics_type::adder_2;
return true; return true;
} }
if (std::strcmp(dynamics_name, "adder_3") == 0) { if (dynamics_name == "adder_3") {
*type = dynamics_type::adder_3; *type = dynamics_type::adder_3;
return true; return true;
} }
if (std::strcmp(dynamics_name, "adder_4") == 0) { if (dynamics_name == "adder_4") {
*type = dynamics_type::adder_4; *type = dynamics_type::adder_4;
return true; return true;
} }
if (std::strcmp(dynamics_name, "mult_2") == 0) { if (dynamics_name == "mult_2") {
*type = dynamics_type::mult_2; *type = dynamics_type::mult_2;
return true; return true;
} }
if (std::strcmp(dynamics_name, "mult_3") == 0) { if (dynamics_name == "mult_3") {
*type = dynamics_type::mult_3; *type = dynamics_type::mult_3;
return true; return true;
} }
if (std::strcmp(dynamics_name, "mult_4") == 0) { if (dynamics_name == "mult_4") {
*type = dynamics_type::mult_4; *type = dynamics_type::mult_4;
return true; return true;
} }
if (std::strcmp(dynamics_name, "counter") == 0) { if (dynamics_name == "counter") {
*type = dynamics_type::counter; *type = dynamics_type::counter;
return true; return true;
} }
if (std::strcmp(dynamics_name, "generator") == 0) { if (dynamics_name == "generator") {
*type = dynamics_type::generator; *type = dynamics_type::generator;
return true; return true;
} }
if (std::strcmp(dynamics_name, "constant") == 0) { if (dynamics_name == "constant") {
*type = dynamics_type::constant; *type = dynamics_type::constant;
return true; return true;
} }
if (std::strcmp(dynamics_name, "cross") == 0) { if (dynamics_name == "cross") {
*type = dynamics_type::cross; *type = dynamics_type::cross;
return true; return true;
} }
if (std::strcmp(dynamics_name, "time_func") == 0) { if (dynamics_name == "time_func") {
*type = dynamics_type::time_func; *type = dynamics_type::time_func;
return true; return true;
} }
...@@ -217,39 +204,27 @@ private: ...@@ -217,39 +204,27 @@ private:
bool read(integrator& dyn) noexcept bool read(integrator& dyn) noexcept
{ {
return 2 == std::fscanf(file, return !!(is >> dyn.default_current_value >> dyn.default_reset_value);
"%lf %lf",
&dyn.default_current_value,
&dyn.default_reset_value);
} }
bool read(quantifier& dyn) noexcept bool read(quantifier& dyn) noexcept
{ {
char state[16]; if (!(is >> dyn.default_step_size >> dyn.default_past_length >>
char init[8]; temp_1 >> temp_2))
int ret = std::fscanf(file,
"%lf %d %15s %7s",
&dyn.default_step_size,
&dyn.default_past_length,
state,
init);
if (ret != 4)
return false; return false;
if (std::strcmp(state, "possible") == 0) if (std::strcmp(temp_1, "possible") == 0)
dyn.default_adapt_state = quantifier::adapt_state::possible; dyn.default_adapt_state = quantifier::adapt_state::possible;
else if (std::strcmp(state, "impossible") == 0) else if (std::strcmp(temp_1, "impossible") == 0)
dyn.default_adapt_state = quantifier::adapt_state::impossible; dyn.default_adapt_state = quantifier::adapt_state::impossible;
else if (std::strcmp(state, "done") == 0) else if (std::strcmp(temp_1, "done") == 0)
dyn.default_adapt_state = quantifier::adapt_state::done; dyn.default_adapt_state = quantifier::adapt_state::done;
else else
return false; return false;
if (std::strcmp(init, "true") == 0) if (std::strcmp(temp_2, "true") == 0)
dyn.default_zero_init_offset = true; dyn.default_zero_init_offset = true;
else if (std::strcmp(init, "false") == 0) else if (std::strcmp(temp_2, "false") == 0)
dyn.default_zero_init_offset = false; dyn.default_zero_init_offset = false;
else else
return false; return false;
...@@ -259,74 +234,44 @@ private: ...@@ -259,74 +234,44 @@ private:
bool read(adder_2& dyn) noexcept bool read(adder_2& dyn) noexcept
{ {
return 4 == std::fscanf(file, return !!(is >> dyn.default_values[0] >> dyn.default_values[1] >>
"%lf %lf %lf %lf", dyn.default_input_coeffs[0] >> dyn.default_input_coeffs[1]);
&dyn.default_values[0],
&dyn.default_values[1],
&dyn.default_input_coeffs[0],
&dyn.default_input_coeffs[1]);
} }
bool read(adder_3& dyn) noexcept bool read(adder_3& dyn) noexcept
{ {
return 6 == std::fscanf(file, return !!(is >> dyn.default_values[0] >> dyn.default_values[1] >>
"%lf %lf %lf %lf %lf %lf", dyn.default_values[2] >> dyn.default_input_coeffs[0] >>
&dyn.default_values[0], dyn.default_input_coeffs[1] >> dyn.default_input_coeffs[2]);
&dyn.default_values[1],
&dyn.default_values[2],
&dyn.default_input_coeffs[0],
&dyn.default_input_coeffs[1],
&dyn.default_input_coeffs[2]);
} }
bool read(adder_4& dyn) noexcept bool read(adder_4& dyn) noexcept
{ {
return 8 == std::fscanf(file, return !!(is >> dyn.default_values[0] >> dyn.default_values[1] >>
"%lf %lf %lf %lf %lf %lf %lf %lf", dyn.default_values[2] >> dyn.default_values[3] >>
&dyn.default_values[0], dyn.default_input_coeffs[0] >> dyn.default_input_coeffs[1] >>
&dyn.default_values[1], dyn.default_input_coeffs[2] >> dyn.default_input_coeffs[3]);
&dyn.default_values[2],
&dyn.default_values[3],
&dyn.default_input_coeffs[0],
&dyn.default_input_coeffs[1],
&dyn.default_input_coeffs[2],
&dyn.default_input_coeffs[3]);
} }
bool read(mult_2& dyn) noexcept bool read(mult_2& dyn) noexcept
{ {
return 4 == std::fscanf(file, return !!(is >> dyn.default_values[0] >> dyn.default_values[1] >>
"%lf %lf %lf %lf", dyn.default_input_coeffs[0] >> dyn.default_input_coeffs[1]);
&dyn.default_values[0],
&dyn.default_values[1],
&dyn.default_input_coeffs[0],
&dyn.default_input_coeffs[1]);
} }
bool read(mult_3& dyn) noexcept bool read(mult_3& dyn) noexcept
{ {
return 6 == std::fscanf(file, return !!(is >> dyn.default_values[0] >> dyn.default_values[1] >>
"%lf %lf %lf %lf %lf %lf", dyn.default_values[2] >> dyn.default_input_coeffs[0] >>
&dyn.default_values[0], dyn.default_input_coeffs[1] >> dyn.default_input_coeffs[2]);
&dyn.default_values[1],
&dyn.default_values[2],
&dyn.default_input_coeffs[0],
&dyn.default_input_coeffs[1],
&dyn.default_input_coeffs[2]);
} }
bool read(mult_4& dyn) noexcept bool read(mult_4& dyn) noexcept
{ {
return 8 == std::fscanf(file, return !!(is >> dyn.default_values[0] >> dyn.default_values[1] >>
"%lf %lf %lf %lf %lf %lf %lf %lf", dyn.default_values[2] >> dyn.default_values[3] >>
&dyn.default_values[0], dyn.default_input_coeffs[0] >> dyn.default_input_coeffs[1] >>
&dyn.default_values[1], dyn.default_input_coeffs[2] >> dyn.default_input_coeffs[3]);
&dyn.default_values[2],
&dyn.default_values[3],
&dyn.default_input_coeffs[0],
&dyn.default_input_coeffs[1],
&dyn.default_input_coeffs[2],
&dyn.default_input_coeffs[3]);
} }
bool read(counter& /*dyn*/) noexcept bool read(counter& /*dyn*/) noexcept
...@@ -341,24 +286,22 @@ private: ...@@ -341,24 +286,22 @@ private:
bool read(constant& dyn) noexcept bool read(constant& dyn) noexcept
{ {
return 1 == std::fscanf(file, "%lf", &dyn.default_value); return !!(is >> dyn.default_value);
} }
bool read(cross& dyn) noexcept bool read(cross& dyn) noexcept
{ {
return 1 == std::fscanf(file, "%lf", &dyn.default_threshold); return !!(is >> dyn.default_threshold);
} }
bool read(time_func& dyn) noexcept bool read(time_func& dyn) noexcept
{ {
char fn[10]; if (!(is >> temp_1))
if (1 != std::fscanf(file, "%9s", fn))
return false; return false;
if (std::strcmp(fn, "square") == 0) if (std::strcmp(temp_1, "square") == 0)
dyn.default_f = &square_time_function; dyn.default_f = &square_time_function;
else else
dyn.default_f = &time_function; dyn.default_f = &time_function;
return true; return true;
...@@ -367,24 +310,17 @@ private: ...@@ -367,24 +310,17 @@ private:
struct writer struct writer
{ {
std::FILE* file = stdout; std::ostream& os;