Skip to content

Commit

Permalink
Max recurse count now gives proper error
Browse files Browse the repository at this point in the history
  • Loading branch information
grunt-lucas committed Aug 9, 2023
1 parent 28032d1 commit a21e1a3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 20 deletions.
12 changes: 7 additions & 5 deletions include/errors_warnings.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,18 @@ void error_invalidAlphaValue(ErrorsAndWarnings &err, const RGBATile &tile, std::
std::size_t col);

// Fatal compilation errors (due to bad user input), fatal errors die immediately
void fatalerror(ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode, std::string message);
void fatalerror_missingRequiredAnimFrameFile(ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
void fatalerror(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode, std::string message);
void fatalerror_missingRequiredAnimFrameFile(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
const std::string &animation, std::size_t index);
void fatalerror_tooManyUniqueColorsTotal(ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
void fatalerror_tooManyUniqueColorsTotal(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
std::size_t allowed, std::size_t found);
void fatalerror_animFrameDimensionsDoNotMatchOtherFrames(ErrorsAndWarnings &err, const InputPaths &inputs,
void fatalerror_animFrameDimensionsDoNotMatchOtherFrames(const ErrorsAndWarnings &err, const InputPaths &inputs,
CompilerMode mode, std::string animName, std::string frame,
std::string dimensionName, png::uint_32 dimension);
void fatalerror_tooManyUniqueTiles(ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
void fatalerror_tooManyUniqueTiles(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
std::size_t numTiles, std::size_t maxAllowedTiles);
void fatalerror_tooManyAssignmentRecurses(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
std::size_t maxRecurses);

// Compilation warnings
void warn_colorPrecisionLoss(ErrorsAndWarnings &err);
Expand Down
19 changes: 9 additions & 10 deletions src/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,14 @@ struct AssignState {
};

std::size_t gRecurseCount = 0;
static bool assign(const std::size_t maxRecurseCount, AssignState state, std::vector<ColorSet> &solution,
static bool assign(const PtContext &ctx, AssignState state, std::vector<ColorSet> &solution,
const std::vector<ColorSet> &primaryPalettes)
{
gRecurseCount++;
// TODO : this is a horrible hack avert your eyes
if (gRecurseCount > maxRecurseCount) {
// TODO : better error context
throw PtException{"too many assignment recurses"};
if (gRecurseCount > ctx.compilerConfig.maxRecurseCount) {
fatalerror_tooManyAssignmentRecurses(ctx.err, ctx.inputPaths, ctx.compilerConfig.mode,
ctx.compilerConfig.maxRecurseCount);
}

if (state.unassigned.empty()) {
Expand Down Expand Up @@ -328,7 +328,7 @@ static bool assign(const std::size_t maxRecurseCount, AssignState state, std::ve
unassignedCopy.pop_back();
AssignState updatedState = {hardwarePalettesCopy, unassignedCopy};

if (assign(maxRecurseCount, updatedState, solution, primaryPalettes)) {
if (assign(ctx, updatedState, solution, primaryPalettes)) {
return true;
}
}
Expand Down Expand Up @@ -389,7 +389,7 @@ static bool assign(const std::size_t maxRecurseCount, AssignState state, std::ve
hardwarePalettesCopy.at(i) |= toAssign;
AssignState updatedState = {hardwarePalettesCopy, unassignedCopy};

if (assign(maxRecurseCount, updatedState, solution, primaryPalettes)) {
if (assign(ctx, updatedState, solution, primaryPalettes)) {
return true;
}
}
Expand Down Expand Up @@ -773,8 +773,7 @@ std::unique_ptr<CompiledTileset> compile(PtContext &ctx, const DecompiledTileset

AssignState state = {tmpHardwarePalettes, unassignedNormPalettes};
gRecurseCount = 0;
bool assignSuccessful =
assign(ctx.compilerConfig.maxRecurseCount, state, assignedPalsSolution, primaryPaletteColorSets);
bool assignSuccessful = assign(ctx, state, assignedPalsSolution, primaryPaletteColorSets);
if (!assignSuccessful) {
// TODO : better error context
throw PtException{"failed to allocate palettes"};
Expand Down Expand Up @@ -1455,7 +1454,7 @@ TEST_CASE("assign should correctly assign all normalized palettes or fail if imp
porytiles::AssignState state = {hardwarePalettes, unassigned};

porytiles::gRecurseCount = 0;
CHECK(porytiles::assign(ctx.compilerConfig.maxRecurseCount, state, solution, {}));
CHECK(porytiles::assign(ctx, state, solution, {}));
CHECK(solution.size() == SOLUTION_SIZE);
CHECK(solution.at(0).count() == 1);
CHECK(solution.at(1).count() == 3);
Expand Down Expand Up @@ -1491,7 +1490,7 @@ TEST_CASE("assign should correctly assign all normalized palettes or fail if imp
porytiles::AssignState state = {hardwarePalettes, unassigned};

porytiles::gRecurseCount = 0;
CHECK(porytiles::assign(ctx.compilerConfig.maxRecurseCount, state, solution, {}));
CHECK(porytiles::assign(ctx, state, solution, {}));
CHECK(solution.size() == SOLUTION_SIZE);
CHECK(solution.at(0).count() == 11);
CHECK(solution.at(1).count() == 12);
Expand Down
21 changes: 16 additions & 5 deletions src/errors_warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ void error_invalidAlphaValue(ErrorsAndWarnings &err, const RGBATile &tile, std::
}
}

void fatalerror(ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode, std::string message)
void fatalerror(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode, std::string message)
{
if (err.printErrors) {
pt_fatal_err("{}", message);
}
die_compilationTerminated(err, inputs.modeBasedInputPath(mode), message);
}

void fatalerror_missingRequiredAnimFrameFile(ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
void fatalerror_missingRequiredAnimFrameFile(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
const std::string &animation, std::size_t index)
{
std::string file = std::to_string(index) + ".png";
Expand All @@ -125,7 +125,7 @@ void fatalerror_missingRequiredAnimFrameFile(ErrorsAndWarnings &err, const Input
fmt::format("animation {} missing required anim frame file {}", animation, file));
}

void fatalerror_tooManyUniqueColorsTotal(ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
void fatalerror_tooManyUniqueColorsTotal(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
std::size_t allowed, std::size_t found)
{
if (err.printErrors) {
Expand All @@ -136,7 +136,7 @@ void fatalerror_tooManyUniqueColorsTotal(ErrorsAndWarnings &err, const InputPath
die_compilationTerminated(err, inputs.modeBasedInputPath(mode), fmt::format("too many unique colors total"));
}

void fatalerror_animFrameDimensionsDoNotMatchOtherFrames(ErrorsAndWarnings &err, const InputPaths &inputs,
void fatalerror_animFrameDimensionsDoNotMatchOtherFrames(const ErrorsAndWarnings &err, const InputPaths &inputs,
CompilerMode mode, std::string animName, std::string frame,
std::string dimensionName, png::uint_32 dimension)
{
Expand All @@ -149,7 +149,7 @@ void fatalerror_animFrameDimensionsDoNotMatchOtherFrames(ErrorsAndWarnings &err,
fmt::format("anim {} frame {} dimension {} mismatch", animName, frame, dimensionName));
}

void fatalerror_tooManyUniqueTiles(ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
void fatalerror_tooManyUniqueTiles(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
std::size_t numTiles, std::size_t maxAllowedTiles)
{
if (err.printErrors) {
Expand All @@ -160,6 +160,17 @@ void fatalerror_tooManyUniqueTiles(ErrorsAndWarnings &err, const InputPaths &inp
fmt::format("too many unique tiles in {} tileset", compilerModeString(mode)));
}

void fatalerror_tooManyAssignmentRecurses(const ErrorsAndWarnings &err, const InputPaths &inputs, CompilerMode mode,
std::size_t maxRecurses)
{
if (err.printErrors) {
pt_fatal_err("palette assignment exceeded maximum depth '{}'", fmt::styled(maxRecurses, fmt::emphasis::bold));
// TODO : impl this CLI option
pt_note("you can increase this depth with the '-fmax-assign-depth' option");
}
die_compilationTerminated(err, inputs.modeBasedInputPath(mode), "too many assignment recurses");
}

void warn_colorPrecisionLoss(ErrorsAndWarnings &err)
{
// TODO : better message
Expand Down

0 comments on commit a21e1a3

Please sign in to comment.