Use a special name for stdin/stdout in diagnostics

This commit is contained in:
ISSOtm
2022-11-12 12:29:28 +01:00
committed by Eldred Habert
parent 6902387991
commit 3e5cd8ce1a
5 changed files with 41 additions and 21 deletions

View File

@@ -78,6 +78,7 @@ public:
// See the `operator*` equivalent. // See the `operator*` equivalent.
return const_cast<File *>(this)->operator->(); return const_cast<File *>(this)->operator->();
} }
File *close() { File *close() {
return std::visit(Visitor{[this](std::filebuf &file) { return std::visit(Visitor{[this](std::filebuf &file) {
// This is called by the destructor, and an explicit `close` // This is called by the destructor, and an explicit `close`
@@ -90,6 +91,14 @@ public:
? this ? this
: nullptr; : 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() ? "<stdin>" : "<stdout>";
}},
_file);
}
}; };
#endif // RGBDS_FILE_HPP #endif // RGBDS_FILE_HPP

View File

@@ -257,7 +257,7 @@ static void registerInput(char const *arg) {
static std::vector<size_t> readAtFile(std::string const &path, std::vector<char> &argPool) { static std::vector<size_t> readAtFile(std::string const &path, std::vector<char> &argPool) {
File file; File file;
if (!file.open(path, std::ios_base::in)) { 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! // We only filter out `EOF`, but calling `isblank()` on anything else is UB!

View File

@@ -94,13 +94,13 @@ class Png {
[[noreturn]] static void handleError(png_structp png, char const *msg) { [[noreturn]] static void handleError(png_structp png, char const *msg) {
Png *self = reinterpret_cast<Png *>(png_get_error_ptr(png)); Png *self = reinterpret_cast<Png *>(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) { static void handleWarning(png_structp png, char const *msg) {
Png *self = reinterpret_cast<Png *>(png_get_error_ptr(png)); Png *self = reinterpret_cast<Png *>(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) { static void readData(png_structp png, png_bytep data, size_t length) {
@@ -112,7 +112,7 @@ class Png {
if (nbBytesRead != expectedLen) { if (nbBytesRead != expectedLen) {
fatal("Error reading input image (\"%s\"): file too short (expected at least %zd more " fatal("Error reading input image (\"%s\"): file too short (expected at least %zd more "
"bytes after reading %lld)", "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)); self->file->pubseekoff(0, std::ios_base::cur));
} }
} }
@@ -177,7 +177,7 @@ public:
*/ */
explicit Png(std::string const &filePath) : path(filePath), colors() { explicit Png(std::string const &filePath) : path(filePath), colors() {
if (file.open(path, std::ios_base::in | std::ios_base::binary) == nullptr) { 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"); options.verbosePrint(Options::VERB_LOG_ACT, "Opened input file\n");
@@ -187,7 +187,7 @@ public:
if (file->sgetn(reinterpret_cast<char *>(pngHeader.data()), pngHeader.size()) if (file->sgetn(reinterpret_cast<char *>(pngHeader.data()), pngHeader.size())
!= static_cast<std::streamsize>(pngHeader.size()) // Not enough bytes? != static_cast<std::streamsize>(pngHeader.size()) // Not enough bytes?
|| png_sig_cmp(pngHeader.data(), 0, pngHeader.size()) != 0) { || 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"); options.verbosePrint(Options::VERB_INTERM, "PNG header signature is OK\n");
@@ -628,7 +628,7 @@ static std::tuple<DefaultInitVec<size_t>, std::vector<Palette>>
static void outputPalettes(std::vector<Palette> const &palettes) { static void outputPalettes(std::vector<Palette> const &palettes) {
File output; File output;
if (!output.open(options.palettes, std::ios_base::out | std::ios_base::binary)) { 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) { for (Palette const &palette : palettes) {
@@ -756,7 +756,7 @@ static void outputTileData(Png const &png, DefaultInitVec<AttrmapEntry> const &a
DefaultInitVec<size_t> const &mappings) { DefaultInitVec<size_t> const &mappings) {
File output; File output;
if (!output.open(options.output, std::ios_base::out | std::ios_base::binary)) { 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); uint64_t remainingTiles = (png.getWidth() / 8) * (png.getHeight() / 8);
@@ -790,19 +790,22 @@ static void outputMaps(DefaultInitVec<AttrmapEntry> const &attrmap,
if (!options.tilemap.empty()) { if (!options.tilemap.empty()) {
tilemapOutput.emplace(); tilemapOutput.emplace();
if (!tilemapOutput->open(options.tilemap, std::ios_base::out | std::ios_base::binary)) { 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()) { if (!options.attrmap.empty()) {
attrmapOutput.emplace(); attrmapOutput.emplace();
if (!attrmapOutput->open(options.attrmap, std::ios_base::out | std::ios_base::binary)) { 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()) { if (!options.palmap.empty()) {
palmapOutput.emplace(); palmapOutput.emplace();
if (!palmapOutput->open(options.palmap, std::ios_base::out | std::ios_base::binary)) { 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<AttrmapEntry> &attr
static void outputTileData(UniqueTiles const &tiles) { static void outputTileData(UniqueTiles const &tiles) {
File output; File output;
if (!output.open(options.output, std::ios_base::out | std::ios_base::binary)) { 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; uint16_t tileID = 0;
@@ -915,7 +918,7 @@ static void outputTileData(UniqueTiles const &tiles) {
static void outputTilemap(DefaultInitVec<AttrmapEntry> const &attrmap) { static void outputTilemap(DefaultInitVec<AttrmapEntry> const &attrmap) {
File output; File output;
if (!output.open(options.tilemap, std::ios_base::out | std::ios_base::binary)) { 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) { for (AttrmapEntry const &entry : attrmap) {
@@ -927,7 +930,7 @@ static void outputAttrmap(DefaultInitVec<AttrmapEntry> const &attrmap,
DefaultInitVec<size_t> const &mappings) { DefaultInitVec<size_t> const &mappings) {
File output; File output;
if (!output.open(options.attrmap, std::ios_base::out | std::ios_base::binary)) { 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) { for (AttrmapEntry const &entry : attrmap) {
@@ -942,7 +945,7 @@ static void outputPalmap(DefaultInitVec<AttrmapEntry> const &attrmap,
DefaultInitVec<size_t> const &mappings) { DefaultInitVec<size_t> const &mappings) {
File output; File output;
if (!output.open(options.attrmap, std::ios_base::out | std::ios_base::binary)) { 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) { for (AttrmapEntry const &entry : attrmap) {

View File

@@ -30,7 +30,7 @@
static DefaultInitVec<uint8_t> readInto(std::string path) { static DefaultInitVec<uint8_t> readInto(std::string path) {
File file; File file;
if (!file.open(path, std::ios::in | std::ios::binary)) { 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<uint8_t> data(128 * 16); // Begin with some room pre-allocated DefaultInitVec<uint8_t> data(128 * 16); // Begin with some room pre-allocated
@@ -149,7 +149,7 @@ void reverse() {
if (!options.palettes.empty()) { if (!options.palettes.empty()) {
File file; File file;
if (!file.open(options.palettes, std::ios::in | std::ios::binary)) { 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(); palettes.clear();
@@ -236,11 +236,11 @@ void reverse() {
options.verbosePrint(Options::VERB_LOG_ACT, "Writing image...\n"); options.verbosePrint(Options::VERB_LOG_ACT, "Writing image...\n");
File pngFile; File pngFile;
if (!pngFile.open(options.input, std::ios::out | std::ios::binary)) { 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_structp png = png_create_write_struct(
PNG_LIBPNG_VER_STRING, PNG_LIBPNG_VER_STRING,
const_cast<png_voidp>(static_cast<void const *>(options.input.c_str())), pngError, const_cast<png_voidp>(static_cast<void const *>(pngFile.c_str(options.input))), pngError,
pngWarning); pngWarning);
if (!png) { if (!png) {
fatal("Couldn't create PNG write struct: %s", strerror(errno)); fatal("Couldn't create PNG write struct: %s", strerror(errno));

View File

@@ -16,7 +16,7 @@ RGBGFX=../../rgbgfx
rc=0 rc=0
new_test() { new_test() {
cmdline="${*@Q}" cmdline="$*"
echo "$bold${green}Testing: $cmdline$rescolors$resbold" >&2 echo "$bold${green}Testing: $cmdline$rescolors$resbold" >&2
} }
test() { test() {
@@ -44,14 +44,22 @@ rm -f out*.png result.png
for f in *.png; do for f in *.png; do
flags="$([[ -e "${f%.png}.flags" ]] && echo "@${f%.png}.flags")" 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 if [[ -e "${f%.png}.err" ]]; then
test 2>"$errtmp" test 2>"$errtmp"
diff -u --strip-trailing-cr "${f%.png}.err" "$errtmp" || fail diff -u --strip-trailing-cr "${f%.png}.err" "$errtmp" || fail
else else
test || fail $? test || fail $?
fi fi
new_test "$RGBGFX" $flags - "<$f"
if [[ -e "${f%.png}.err" ]]; then
test 2>"$errtmp"
diff -u --strip-trailing-cr <(sed "s/$f/<stdin>/g" "${f%.png}.err") "$errtmp" || fail
else
test || fail $?
fi
done done
exit $rc exit $rc