diff --git a/include/file.hpp b/include/file.hpp index 6a24b720..cf54b9db 100644 --- a/include/file.hpp +++ b/include/file.hpp @@ -78,6 +78,7 @@ public: // See the `operator*` equivalent. return const_cast(this)->operator->(); } + File *close() { return std::visit(Visitor{[this](std::filebuf &file) { // This is called by the destructor, and an explicit `close` @@ -90,6 +91,14 @@ public: ? this : nullptr; } + + char const *c_str(std::string const &path) const { + return std::visit(Visitor{[&path](std::filebuf const &) { return path.c_str(); }, + [](std::streambuf const *buf) { + return buf == std::cin.rdbuf() ? "" : ""; + }}, + _file); + } }; #endif // RGBDS_FILE_HPP diff --git a/src/gfx/main.cpp b/src/gfx/main.cpp index 35ed7a2a..a993991c 100644 --- a/src/gfx/main.cpp +++ b/src/gfx/main.cpp @@ -257,7 +257,7 @@ static void registerInput(char const *arg) { static std::vector readAtFile(std::string const &path, std::vector &argPool) { File file; if (!file.open(path, std::ios_base::in)) { - fatal("Error reading @%s: %s", path.c_str(), strerror(errno)); + fatal("Error reading @%s: %s", file.c_str(path), strerror(errno)); } // We only filter out `EOF`, but calling `isblank()` on anything else is UB! diff --git a/src/gfx/process.cpp b/src/gfx/process.cpp index bfd97549..94b1fe1d 100644 --- a/src/gfx/process.cpp +++ b/src/gfx/process.cpp @@ -94,13 +94,13 @@ class Png { [[noreturn]] static void handleError(png_structp png, char const *msg) { Png *self = reinterpret_cast(png_get_error_ptr(png)); - fatal("Error reading input image (\"%s\"): %s", self->path.c_str(), msg); + fatal("Error reading input image (\"%s\"): %s", self->file.c_str(self->path), msg); } static void handleWarning(png_structp png, char const *msg) { Png *self = reinterpret_cast(png_get_error_ptr(png)); - warning("In input image (\"%s\"): %s", self->path.c_str(), msg); + warning("In input image (\"%s\"): %s", self->file.c_str(self->path), msg); } static void readData(png_structp png, png_bytep data, size_t length) { @@ -112,7 +112,7 @@ class Png { if (nbBytesRead != expectedLen) { fatal("Error reading input image (\"%s\"): file too short (expected at least %zd more " "bytes after reading %lld)", - self->path.c_str(), length - nbBytesRead, + self->file.c_str(self->path), length - nbBytesRead, self->file->pubseekoff(0, std::ios_base::cur)); } } @@ -177,7 +177,7 @@ public: */ explicit Png(std::string const &filePath) : path(filePath), colors() { if (file.open(path, std::ios_base::in | std::ios_base::binary) == nullptr) { - fatal("Failed to open input image (\"%s\"): %s", path.c_str(), strerror(errno)); + fatal("Failed to open input image (\"%s\"): %s", file.c_str(path), strerror(errno)); } options.verbosePrint(Options::VERB_LOG_ACT, "Opened input file\n"); @@ -187,7 +187,7 @@ public: if (file->sgetn(reinterpret_cast(pngHeader.data()), pngHeader.size()) != static_cast(pngHeader.size()) // Not enough bytes? || png_sig_cmp(pngHeader.data(), 0, pngHeader.size()) != 0) { - fatal("Input file (\"%s\") is not a PNG image!", path.c_str()); + fatal("Input file (\"%s\") is not a PNG image!", file.c_str(path)); } options.verbosePrint(Options::VERB_INTERM, "PNG header signature is OK\n"); @@ -628,7 +628,7 @@ static std::tuple, std::vector> static void outputPalettes(std::vector const &palettes) { File output; if (!output.open(options.palettes, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to open \"%s\": %s", options.palettes.c_str(), strerror(errno)); + fatal("Failed to open \"%s\": %s", output.c_str(options.palettes), strerror(errno)); } for (Palette const &palette : palettes) { @@ -756,7 +756,7 @@ static void outputTileData(Png const &png, DefaultInitVec const &a DefaultInitVec const &mappings) { File output; if (!output.open(options.output, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to open \"%s\": %s", options.output.c_str(), strerror(errno)); + fatal("Failed to open \"%s\": %s", output.c_str(options.output), strerror(errno)); } uint64_t remainingTiles = (png.getWidth() / 8) * (png.getHeight() / 8); @@ -790,19 +790,22 @@ static void outputMaps(DefaultInitVec const &attrmap, if (!options.tilemap.empty()) { tilemapOutput.emplace(); if (!tilemapOutput->open(options.tilemap, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to open \"%s\": %s", options.tilemap.c_str(), strerror(errno)); + fatal("Failed to open \"%s\": %s", tilemapOutput->c_str(options.tilemap), + strerror(errno)); } } if (!options.attrmap.empty()) { attrmapOutput.emplace(); if (!attrmapOutput->open(options.attrmap, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to open \"%s\": %s", options.attrmap.c_str(), strerror(errno)); + fatal("Failed to open \"%s\": %s", attrmapOutput->c_str(options.attrmap), + strerror(errno)); } } if (!options.palmap.empty()) { palmapOutput.emplace(); if (!palmapOutput->open(options.palmap, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to open \"%s\": %s", options.palmap.c_str(), strerror(errno)); + fatal("Failed to open \"%s\": %s", palmapOutput->c_str(options.palmap), + strerror(errno)); } } @@ -900,7 +903,7 @@ static UniqueTiles dedupTiles(Png const &png, DefaultInitVec &attr static void outputTileData(UniqueTiles const &tiles) { File output; if (!output.open(options.output, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to create \"%s\": %s", options.output.c_str(), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.c_str(options.output), strerror(errno)); } uint16_t tileID = 0; @@ -915,7 +918,7 @@ static void outputTileData(UniqueTiles const &tiles) { static void outputTilemap(DefaultInitVec const &attrmap) { File output; if (!output.open(options.tilemap, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to create \"%s\": %s", options.tilemap.c_str(), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.c_str(options.tilemap), strerror(errno)); } for (AttrmapEntry const &entry : attrmap) { @@ -927,7 +930,7 @@ static void outputAttrmap(DefaultInitVec const &attrmap, DefaultInitVec const &mappings) { File output; if (!output.open(options.attrmap, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to create \"%s\": %s", options.attrmap.c_str(), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.c_str(options.attrmap), strerror(errno)); } for (AttrmapEntry const &entry : attrmap) { @@ -942,7 +945,7 @@ static void outputPalmap(DefaultInitVec const &attrmap, DefaultInitVec const &mappings) { File output; if (!output.open(options.attrmap, std::ios_base::out | std::ios_base::binary)) { - fatal("Failed to create \"%s\": %s", options.attrmap.c_str(), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.c_str(options.attrmap), strerror(errno)); } for (AttrmapEntry const &entry : attrmap) { diff --git a/src/gfx/reverse.cpp b/src/gfx/reverse.cpp index 2db540f9..9003706a 100644 --- a/src/gfx/reverse.cpp +++ b/src/gfx/reverse.cpp @@ -30,7 +30,7 @@ static DefaultInitVec readInto(std::string path) { File file; if (!file.open(path, std::ios::in | std::ios::binary)) { - fatal("Failed to open \"%s\": %s", path.c_str(), strerror(errno)); + fatal("Failed to open \"%s\": %s", file.c_str(path), strerror(errno)); } DefaultInitVec data(128 * 16); // Begin with some room pre-allocated @@ -149,7 +149,7 @@ void reverse() { if (!options.palettes.empty()) { File file; if (!file.open(options.palettes, std::ios::in | std::ios::binary)) { - fatal("Failed to open \"%s\": %s", options.palettes.c_str(), strerror(errno)); + fatal("Failed to open \"%s\": %s", file.c_str(options.palettes), strerror(errno)); } palettes.clear(); @@ -236,11 +236,11 @@ void reverse() { options.verbosePrint(Options::VERB_LOG_ACT, "Writing image...\n"); File pngFile; if (!pngFile.open(options.input, std::ios::out | std::ios::binary)) { - fatal("Failed to create \"%s\": %s", options.input.c_str(), strerror(errno)); + fatal("Failed to create \"%s\": %s", pngFile.c_str(options.input), strerror(errno)); } png_structp png = png_create_write_struct( PNG_LIBPNG_VER_STRING, - const_cast(static_cast(options.input.c_str())), pngError, + const_cast(static_cast(pngFile.c_str(options.input))), pngError, pngWarning); if (!png) { fatal("Couldn't create PNG write struct: %s", strerror(errno)); diff --git a/test/gfx/test.sh b/test/gfx/test.sh index 5e7b79b4..bf2c0670 100755 --- a/test/gfx/test.sh +++ b/test/gfx/test.sh @@ -16,7 +16,7 @@ RGBGFX=../../rgbgfx rc=0 new_test() { - cmdline="${*@Q}" + cmdline="$*" echo "$bold${green}Testing: $cmdline$rescolors$resbold" >&2 } test() { @@ -44,14 +44,22 @@ rm -f out*.png result.png for f in *.png; do flags="$([[ -e "${f%.png}.flags" ]] && echo "@${f%.png}.flags")" - new_test "$RGBGFX" $flags "$f" + new_test "$RGBGFX" $flags "$f" if [[ -e "${f%.png}.err" ]]; then test 2>"$errtmp" diff -u --strip-trailing-cr "${f%.png}.err" "$errtmp" || fail else test || fail $? fi + + new_test "$RGBGFX" $flags - "<$f" + if [[ -e "${f%.png}.err" ]]; then + test 2>"$errtmp" + diff -u --strip-trailing-cr <(sed "s/$f//g" "${f%.png}.err") "$errtmp" || fail + else + test || fail $? + fi done exit $rc