Skip to content

Commit

Permalink
API change: Modify IO error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
pierre-dejoue committed Aug 10, 2023
1 parent 46d212b commit 0c8b825
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 46 deletions.
2 changes: 1 addition & 1 deletion outputs/invalid_input.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ERROR [invalid_input.txt]: Parsing error [Invalid token GRILL (parsing_state = COLUMN_SECTION)] on line 105: GRILL Beaf
PARSING_ERROR [invalid_input.txt]: [Invalid token GRILL (parsing_state = COLUMN_SECTION)] on line 105: GRILL Beaf
GRID 1: Fishy
Size: 22x20
Invalid grid. Error message: Number of filled tiles on rows (153) and columns (154) do not match
Expand Down
2 changes: 1 addition & 1 deletion outputs/validation.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
File,Grid,Size,Valid,Difficulty,Solutions,Timing (ms),Misc,Linear reductions,Full reductions,Min depth,Max depth,Searched line alternatives
invalid_input.txt,,,ZERO,NOT_APPLICABLE,0,,"Parsing error [Invalid token GRILL (parsing_state = COLUMN_SECTION)] on line 105: GRILL Beaf"
invalid_input.txt,,,ZERO,NOT_APPLICABLE,0,,"PARSING_ERROR [Invalid token GRILL (parsing_state = COLUMN_SECTION)] on line 105: GRILL Beaf"
invalid_input.txt,Fishy,22x20,ERR,NOT_APPLICABLE,0,,"Number of filled tiles on rows (153) and columns (154) do not match"
invalid_input.txt,False note,10x0,ERR,NOT_APPLICABLE,0,,"Invalid height = 0"
invalid_input.txt,Ill-formed,3x3,ERR,NOT_APPLICABLE,0,,"Height = 3 of the grid is too small for constraint: Constraint on a COL: [ 4 ]; min_line_size = 4"
Expand Down
17 changes: 9 additions & 8 deletions src/cli/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,16 @@ int main(int argc, char *argv[])
ValidationModeData file_data;
file_data.filename = stdutils::string::filename(filepath);

const picross::io::ErrorHandler err_handler_classic = [&return_status, &file_data](std::string_view msg, picross::io::ExitCode code)
const picross::io::ErrorHandler err_handler_classic = [&return_status, &file_data](picross::io::ErrorCodeT code, std::string_view msg)
{
std::cout << (code == 0 ? "WARNING" : "ERROR" ) << " [" << file_data.filename << "]: " << msg << std::endl;
if (code != 0)
return_status = code;
std::cout << picross::io::str_error_code(code) << " [" << file_data.filename << "]: " << msg << std::endl;
return_status = code;
};
const picross::io::ErrorHandler err_handler_validation = [&file_data](std::string_view msg, picross::io::ExitCode code)
const picross::io::ErrorHandler err_handler_validation = [&file_data](picross::io::ErrorCodeT code, std::string_view msg)
{
file_data.misc = msg.empty() ? std::to_string(code) : msg;
std::ostringstream oss;
oss << picross::io::str_error_code(code) << " " << msg;
file_data.misc = oss.str();
};

const auto format = [&args, &filepath]() -> picross::io::PicrossFileFormat {
Expand Down Expand Up @@ -391,11 +392,11 @@ int main(int argc, char *argv[])
if (validation_mode)
{
grid_data.validation_result.validation_code = -1; // ERR
grid_data.misc = "EXCPT " + std::string(e.what());
grid_data.misc = "EXCEPTION";
}
else
{
std::cout << "EXCPT [" << file_data.filename << "][" << input_grid.name() << "]: " << e.what() << std::endl;
std::cout << "EXCEPTION [" << file_data.filename << "][" << input_grid.name() << "]: " << e.what() << std::endl;
return_status = 5;
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/gui/src/err_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,9 @@ void ErrWindow::print(std::string_view msg)
std::lock_guard<std::mutex> lock(pImpl->text_buffer_lock);
pImpl->text_buffer.appendf("%s\n", msg.data());
}

void ErrWindow::print(std::string_view hdr, std::string_view msg)
{
std::lock_guard<std::mutex> lock(pImpl->text_buffer_lock);
pImpl->text_buffer.appendf("%s %s\n", hdr.data(), msg.data());
}
1 change: 1 addition & 0 deletions src/gui/src/err_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class ErrWindow

void visit(bool& can_be_erased);
void print(std::string_view msg);
void print(std::string_view hdr, std::string_view msg);

private:
struct Impl;
Expand Down
4 changes: 2 additions & 2 deletions src/gui/src/grid_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,10 @@ void GridWindow::save_grid()

if (!file_path.empty())
{
const auto err_handler = [this](std::string_view msg, picross::io::ExitCode)
const auto err_handler = [this](picross::io::ErrorCodeT code, std::string_view msg)
{
std::lock_guard<std::mutex> lock(this->text_buffer->mutex);
this->text_buffer->buffer.appendf("%s\n", msg);
this->text_buffer->buffer.appendf("%s %s\n", picross::io::str_error_code(code).c_str(), msg);
};

const auto solution = (solutions.empty() || !solutions[0].is_completed()) ? std::nullopt : std::optional<picross::OutputGrid>(solutions[0]);
Expand Down
4 changes: 2 additions & 2 deletions src/gui/src/picross_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ void PicrossFile::visit_windows(bool& can_be_erased, Settings& settings)
if (!is_file_open)
{
is_file_open = true;
const auto err_handler = [this](std::string_view msg, picross::io::ExitCode)
const auto err_handler = [this](picross::io::ErrorCodeT code, std::string_view msg)
{
this->get_err_window().print(msg);
this->get_err_window().print(picross::io::str_error_code(code), msg);
};
std::optional<picross::OutputGrid> goal;
std::vector<picross::IOGrid> grids_to_solve = picross::io::parse_picross_file(file_path, file_format, err_handler);
Expand Down
15 changes: 12 additions & 3 deletions src/picross/include/picross/picross_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,19 @@ namespace io
/*
* IO error handling
*/
using ExitCode = int;
inline constexpr ExitCode PARSER_ERROR = 1;
using ErrorCodeT = int;
struct ErrorCode
{
// All codes != 0
static constexpr ErrorCodeT PARSING_ERROR = 1;
static constexpr ErrorCodeT FILE_ERROR = 2;
static constexpr ErrorCodeT EXCEPTION = 3;
static constexpr ErrorCodeT WARNING = 4;
};

std::string str_error_code(ErrorCodeT code);

using ErrorHandler = std::function<void(std::string_view, ExitCode)>;
using ErrorHandler = std::function<void(ErrorCodeT, std::string_view)>;

/*
* File parser, native file format
Expand Down
55 changes: 41 additions & 14 deletions src/picross/src/picross_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,31 @@ IOGrid::IOGrid(InputGrid&& input_grid, std::optional<OutputGrid>&& goal) noexcep
namespace io
{

std::string str_error_code(ErrorCodeT code)
{
switch (code)
{
case ErrorCode::PARSING_ERROR:
return "PARSING_ERROR";

case ErrorCode::FILE_ERROR:
return "FILE_ERROR";

case ErrorCode::EXCEPTION:
return "EXCEPTION";

case ErrorCode::WARNING:
return "WARNING";

default:
{
std::ostringstream oss;
oss << "ERROR_CODE(" << code << ")";
return oss.str();
}
}
}

namespace
{

Expand All @@ -55,6 +80,8 @@ struct GridComponents
std::optional<OutputGrid> m_goal;
};

using ParserErrorHandler = std::function<void(std::string_view)>;

template <typename F>
class FileParser;

Expand All @@ -78,7 +105,7 @@ class FileParser<FileFormat::Native>
{
}

void parse_line(const std::string& line_to_parse, std::vector<GridComponents>& grids, const ErrorHandler& error_handler)
void parse_line(const std::string& line_to_parse, std::vector<GridComponents>& grids, const ParserErrorHandler& error_handler)
{
std::istringstream iss(line_to_parse);
std::string token;
Expand Down Expand Up @@ -175,11 +202,11 @@ class FileParser<FileFormat::Native>
return "UNKNOWN";
}

void error_decorator(const ErrorHandler& error_handler, const std::string_view& msg)
void error_decorator(const ParserErrorHandler& error_handler, const std::string_view& msg)
{
std::ostringstream oss;
oss << msg << " (parsing_state = " << parsing_state_str() << ")";
error_handler(oss.str(), PARSER_ERROR);
error_handler(oss.str());
}
private:
ParsingState parsing_state;
Expand Down Expand Up @@ -209,7 +236,7 @@ class FileParser<FileFormat::Nin>
{
}

void parse_line(const std::string& line_to_parse, std::vector<GridComponents>& grids, const ErrorHandler& error_handler)
void parse_line(const std::string& line_to_parse, std::vector<GridComponents>& grids, const ParserErrorHandler& error_handler)
{
UNUSED(error_handler);

Expand Down Expand Up @@ -286,11 +313,11 @@ class FileParser<FileFormat::Nin>
return "UNKNOWN";
}

void error_decorator(const ErrorHandler& error_handler, const std::string_view& msg)
void error_decorator(const ParserErrorHandler& error_handler, const std::string_view& msg)
{
std::ostringstream oss;
oss << msg << " (parsing_state = " << parsing_state_str() << ")";
error_handler(oss.str(), PARSER_ERROR);
error_handler(oss.str());
}
private:
ParsingState parsing_state;
Expand Down Expand Up @@ -322,7 +349,7 @@ class FileParser<FileFormat::Non>

}

void parse_line(const std::string& line_to_parse, std::vector<GridComponents>& grids, const ErrorHandler& error_handler)
void parse_line(const std::string& line_to_parse, std::vector<GridComponents>& grids, const ParserErrorHandler& error_handler)
{
std::istringstream iss(line_to_parse);
std::string token;
Expand Down Expand Up @@ -543,14 +570,14 @@ class FileParser<FileFormat::Non>
return "UNKNOWN";
}

void error_decorator(const ErrorHandler& error_handler, std::string_view msg, std::string_view token = "")
void error_decorator(const ParserErrorHandler& error_handler, std::string_view msg, std::string_view token = "")
{
std::ostringstream oss;
oss << msg << " (parsing_state = " << parsing_state_str();
if (!token.empty())
oss << "; token = " << token;
oss << ")";
error_handler(oss.str(), PARSER_ERROR);
error_handler(oss.str());
}
private:
ParsingState parsing_state;
Expand Down Expand Up @@ -587,11 +614,11 @@ std::vector<IOGrid> parse_input_file_generic(std::string_view filepath, const Er
{
line_nb++;
std::string line = line_ss.str();
parser.parse_line(line, grids, [line_nb, &line, &error_handler](std::string_view msg, ExitCode code)
parser.parse_line(line, grids, [line_nb, &line, &error_handler](std::string_view msg)
{
std::ostringstream oss;
oss << "Parsing error [" << msg << "] on line " << line_nb << ": " << line;
error_handler(oss.str(), code);
oss << "[" << msg << "] on line " << line_nb << ": " << line;
error_handler(ErrorCode::PARSING_ERROR, oss.str());
});
line_ss.str("");
}
Expand All @@ -614,14 +641,14 @@ std::vector<IOGrid> parse_input_file_generic(std::string_view filepath, const Er
{
std::ostringstream oss;
oss << "Cannot open file " << filepath;
error_handler(oss.str(), 1);
error_handler(ErrorCode::FILE_ERROR, oss.str());
}
}
catch (std::exception& e)
{
std::ostringstream oss;
oss << "Unhandled exception during file parsing: " << e.what();
error_handler(oss.str(), 2);
error_handler(ErrorCode::EXCEPTION, oss.str());
}

return result;
Expand Down
4 changes: 2 additions & 2 deletions src/utils/src/bitmap_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ picross::OutputGrid import_bitmap_pbm(const std::string& filepath, const picross
}
catch(const std::exception& e)
{
error_handler(e.what(), 0);
error_handler(picross::io::ErrorCode::EXCEPTION, e.what());
}
return picross::OutputGrid(0, 0, picross::Tile::UNKNOWN, "Invalid");
}
Expand All @@ -49,6 +49,6 @@ void export_bitmap_pbm(const std::string& filepath, const picross::OutputGrid& g
}
catch (const std::exception& e)
{
error_handler(e.what(), 0);
error_handler(picross::io::ErrorCode::EXCEPTION, e.what());
}
}
16 changes: 8 additions & 8 deletions src/utils/src/picross_file_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ std::vector<IOGrid> parse_picross_file(std::string_view filepath, PicrossFileFor
}
catch (const std::exception& e)
{
error_handler(e.what(), 2);
error_handler(ErrorCode::EXCEPTION, e.what());
}
return {};
}
Expand All @@ -126,7 +126,7 @@ void save_picross_file(std::string_view filepath, PicrossFileFormat format, cons
{
std::ofstream out(filepath.data());
if (!out.good())
error_handler("Error writing file " + std::string(filepath), 1);
error_handler(ErrorCode::FILE_ERROR, "Error writing file " + std::string(filepath));
picross::io::write_input_grid_native(out, io_grid);
break;
}
Expand All @@ -135,7 +135,7 @@ void save_picross_file(std::string_view filepath, PicrossFileFormat format, cons
{
std::ofstream out(filepath.data());
if (!out.good())
error_handler("Error writing file " + std::string(filepath), 1);
error_handler(ErrorCode::FILE_ERROR, "Error writing file " + std::string(filepath));
picross::io::write_input_grid_nin_format(out, io_grid);
break;
}
Expand All @@ -144,26 +144,26 @@ void save_picross_file(std::string_view filepath, PicrossFileFormat format, cons
{
std::ofstream out(filepath.data());
if (!out.good())
error_handler("Error writing file " + std::string(filepath), 1);
error_handler(ErrorCode::FILE_ERROR, "Error writing file " + std::string(filepath));
picross::io::write_input_grid_non_format(out, io_grid);
break;
}

case PicrossFileFormat::PBM:
{
if (!io_grid.m_goal)
error_handler(goal_non_set_error_msg(filepath, format), 2);
error_handler(ErrorCode::WARNING, goal_non_set_error_msg(filepath, format));
export_bitmap_pbm(std::string(filepath), *io_grid.m_goal, error_handler);
break;
}

case PicrossFileFormat::OutputGrid:
{
if (!io_grid.m_goal)
error_handler(goal_non_set_error_msg(filepath, format), 2);
error_handler(ErrorCode::WARNING, goal_non_set_error_msg(filepath, format));
std::ofstream out(filepath.data());
if (!out.good())
error_handler("Error writing file " + std::string(filepath), 1);
error_handler(ErrorCode::FILE_ERROR, "Error writing file " + std::string(filepath));
out << *io_grid.m_goal;
break;
}
Expand All @@ -175,7 +175,7 @@ void save_picross_file(std::string_view filepath, PicrossFileFormat format, cons
}
catch (const std::exception& e)
{
error_handler(e.what(), 3);
error_handler(ErrorCode::EXCEPTION, e.what());
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/utils/src/text_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,18 @@ OutputGrid io::parse_output_grid_from_file(std::string_view filepath, const io::
{
std::ostringstream oss;
oss << "Cannot open file " << filepath;
error_handler(oss.str(), 1);
error_handler(ErrorCode::FILE_ERROR, oss.str());
}
}
catch (std::logic_error& l)
{
std::ostringstream oss;
oss << "Parsing error: " << l.what();
error_handler(oss.str(), 2);
error_handler(ErrorCode::PARSING_ERROR, l.what());
}
catch (std::exception& e)
{
std::ostringstream oss;
oss << "Unhandled exception during file parsing: " << e.what();
error_handler(oss.str(), 3);
error_handler(ErrorCode::EXCEPTION, oss.str());
}
return OutputGrid(0, 0, Tile::UNKNOWN, "Invalid");
}
Expand Down

0 comments on commit 0c8b825

Please sign in to comment.