diff --git a/include/verbosity.hpp b/include/verbosity.hpp index e2838769..b5a7837e 100644 --- a/include/verbosity.hpp +++ b/include/verbosity.hpp @@ -6,6 +6,9 @@ #include #include +#include "helpers.hpp" // Procedure +#include "style.hpp" + // This macro does not evaluate its arguments unless the condition is true. #define verbosePrint(level, ...) \ do { \ @@ -30,6 +33,14 @@ bool checkVerbosity(Verbosity level); [[gnu::format(printf, 1, 2)]] void printVerbosely(char const *fmt, ...); +void verboseDo(Verbosity level, Procedure<> auto callback) { + if (checkVerbosity(level)) { + style_Set(stderr, STYLE_MAGENTA, false); + callback(); + style_Reset(stderr); + } +} + void printVVVVVVerbosity(); #endif // RGBDS_VERBOSITY_HPP diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index 43a5b2d7..4951118a 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -2315,26 +2315,22 @@ yy::parser::symbol_type yylex() { return yy::parser::symbol_type(token.type, std::get(token.value)); } else if (std::holds_alternative(token.value)) { // LCOV_EXCL_START - if (checkVerbosity(VERB_TRACE)) { - style_Set(stderr, STYLE_MAGENTA, false); + verboseDo(VERB_TRACE, [&]() { fprintf(stderr, "Lexed `%s` token (", yy::parser::symbol_type(token.type).name()); verboseOutputString(std::get(token.value)); fputs(")\n", stderr); - style_Reset(stderr); - } + }); // LCOV_EXCL_STOP return yy::parser::symbol_type(token.type, std::get(token.value)); } else if (std::holds_alternative(token.value)) { // LCOV_EXCL_START - if (checkVerbosity(VERB_TRACE)) { - style_Set(stderr, STYLE_MAGENTA, false); + verboseDo(VERB_TRACE, [&]() { fprintf( stderr, "Lexed `%s` token (interned ", yy::parser::symbol_type(token.type).name() ); verboseOutputString(std::get(token.value).str()); fputs(")\n", stderr); - style_Reset(stderr); - } + }); // LCOV_EXCL_STOP return yy::parser::symbol_type(token.type, std::get(token.value)); } else { @@ -2392,13 +2388,13 @@ static Capture makeCapture(char const *name, InvocableR auto callback) } // LCOV_EXCL_START - if (checkVerbosity(VERB_TRACE) && capture.span.ptr) { - style_Set(stderr, STYLE_MAGENTA, false); - fprintf(stderr, "Captured %s (", name); - verboseOutputString(std::string_view{capture.span.ptr.get(), capture.span.size}); - fputs(")\n", stderr); - style_Reset(stderr); - } + verboseDo(VERB_TRACE, [&]() { + if (capture.span.ptr) { + fprintf(stderr, "Captured %s (", name); + verboseOutputString(std::string_view{capture.span.ptr.get(), capture.span.size}); + fputs(")\n", stderr); + } + }); // LCOV_EXCL_STOP assume(!lexerState->atLineStart); // `skipToLeadingKeyword` moves past the start of the line diff --git a/src/asm/main.cpp b/src/asm/main.cpp index bd0f0917..712d81e7 100644 --- a/src/asm/main.cpp +++ b/src/asm/main.cpp @@ -24,7 +24,7 @@ #include "helpers.hpp" #include "parser.hpp" // Generated from parser.y #include "platform.hpp" -#include "style.hpp" +#include "style.hpp" // style_Parse #include "usage.hpp" #include "util.hpp" // UpperMap #include "verbosity.hpp" @@ -373,12 +373,6 @@ static void parseArg(int ch, char *arg) { // LCOV_EXCL_START static void verboseOutputConfig() { - if (!checkVerbosity(VERB_CONFIG)) { - return; - } - - style_Set(stderr, STYLE_MAGENTA, false); - usage.printVersion(true); printVVVVVVerbosity(); @@ -490,8 +484,6 @@ static void verboseOutputConfig() { } } fputs("Ready for assembly\n", stderr); - - style_Reset(stderr); } // LCOV_EXCL_STOP @@ -519,7 +511,7 @@ int main(int argc, char *argv[]) { options.targetFileName = options.objectFileName; } - verboseOutputConfig(); + verboseDo(VERB_CONFIG, verboseOutputConfig); if (!localOptions.inputFileName) { usage.printAndExit("No input file specified (pass \"-\" to read from standard input)"); diff --git a/src/gfx/main.cpp b/src/gfx/main.cpp index 5f411d7f..45aabefb 100644 --- a/src/gfx/main.cpp +++ b/src/gfx/main.cpp @@ -19,7 +19,7 @@ #include "file.hpp" #include "helpers.hpp" #include "platform.hpp" -#include "style.hpp" +#include "style.hpp" // style_Parse #include "usage.hpp" #include "util.hpp" #include "verbosity.hpp" @@ -474,12 +474,6 @@ static void parseArg(int ch, char *arg) { // LCOV_EXCL_START static void verboseOutputConfig() { - if (!checkVerbosity(VERB_CONFIG)) { - return; - } - - style_Set(stderr, STYLE_MAGENTA, false); - usage.printVersion(true); printVVVVVVerbosity(); @@ -609,8 +603,6 @@ static void verboseOutputConfig() { fprintf(stderr, "\tReverse image width: %" PRIu16 " tiles\n", options.reversedWidth); } fputs("Ready for conversion\n", stderr); - - style_Reset(stderr); } // LCOV_EXCL_STOP @@ -684,7 +676,7 @@ int main(int argc, char *argv[]) { parseExternalPalSpec(localOptions.externalPalSpec->c_str()); } - verboseOutputConfig(); // LCOV_EXCL_LINE + verboseDo(VERB_CONFIG, verboseOutputConfig); // Do not do anything if option parsing went wrong. requireZeroErrors(); diff --git a/src/gfx/pal_packing.cpp b/src/gfx/pal_packing.cpp index ccd47d77..04d2b43b 100644 --- a/src/gfx/pal_packing.cpp +++ b/src/gfx/pal_packing.cpp @@ -18,7 +18,6 @@ #include #include "helpers.hpp" -#include "style.hpp" #include "verbosity.hpp" #include "gfx/color_set.hpp" @@ -259,22 +258,18 @@ public: static void verboseOutputAssignments( std::vector const &assignments, std::vector const &colorSets ) { - if (!checkVerbosity(VERB_INFO)) { - return; - } - - style_Set(stderr, STYLE_MAGENTA, false); - for (AssignedSets const &assignment : assignments) { - fputs("{ ", stderr); - for (ColorSetAttrs const &attrs : assignment) { - fprintf(stderr, "[%zu] ", attrs.colorSetIndex); - for (uint16_t colorIndex : colorSets[attrs.colorSetIndex]) { - fprintf(stderr, "%04" PRIx16 ", ", colorIndex); + verboseDo(VERB_INFO, [&]() { + for (AssignedSets const &assignment : assignments) { + fputs("{ ", stderr); + for (ColorSetAttrs const &attrs : assignment) { + fprintf(stderr, "[%zu] ", attrs.colorSetIndex); + for (uint16_t colorIndex : colorSets[attrs.colorSetIndex]) { + fprintf(stderr, "%04" PRIx16 ", ", colorIndex); + } } + fprintf(stderr, "} (volume = %zu)\n", assignment.volume()); } - fprintf(stderr, "} (volume = %zu)\n", assignment.volume()); - } - style_Reset(stderr); + }); } // LCOV_EXCL_STOP @@ -553,13 +548,13 @@ std::pair, size_t> overloadAndRemove(std::vector c } } - verboseOutputAssignments(assignments, colorSets); // LCOV_EXCL_LINE + verboseOutputAssignments(assignments, colorSets); // "Decant" the result decant(assignments, colorSets); // Note that the result does not contain any empty palettes - verboseOutputAssignments(assignments, colorSets); // LCOV_EXCL_LINE + verboseOutputAssignments(assignments, colorSets); std::vector mappings(colorSets.size()); for (size_t i = 0; i < assignments.size(); ++i) { diff --git a/src/gfx/png.cpp b/src/gfx/png.cpp index a48c3c28..0f41e656 100644 --- a/src/gfx/png.cpp +++ b/src/gfx/png.cpp @@ -16,7 +16,6 @@ #include "diagnostics.hpp" #include "helpers.hpp" -#include "style.hpp" #include "verbosity.hpp" #include "gfx/rgba.hpp" @@ -158,15 +157,13 @@ Png::Png(char const *filename, std::streambuf &file) { ); } - if (checkVerbosity(VERB_INFO)) { - style_Set(stderr, STYLE_MAGENTA, false); + verboseDo(VERB_INFO, [&]() { fprintf(stderr, "Embedded PNG palette has %d colors: [", nbColors); for (int i = 0; i < nbColors; ++i) { fprintf(stderr, "%s#%08x", i > 0 ? ", " : "", palette[i].toCSS()); } fprintf(stderr, "]\n"); - style_Reset(stderr); - } + }); } else { verbosePrint(VERB_INFO, "No embedded PNG palette\n"); } diff --git a/src/gfx/process.cpp b/src/gfx/process.cpp index 493728a4..9a42f7b2 100644 --- a/src/gfx/process.cpp +++ b/src/gfx/process.cpp @@ -22,7 +22,6 @@ #include "file.hpp" #include "helpers.hpp" #include "itertools.hpp" -#include "style.hpp" #include "verbosity.hpp" #include "gfx/color_set.hpp" @@ -350,16 +349,16 @@ static std::pair, std::vector> assume(mappings.size() == colorSets.size()); // LCOV_EXCL_START - if (checkVerbosity(VERB_INFO)) { - style_Set(stderr, STYLE_MAGENTA, false); + // Ideally we'd use an implicit `[&]` capture, but C++20 P0588R1 (which allows "reference to + // local binding declared in enclosing function") is not sufficiently supported by clang. + verboseDo(VERB_INFO, [&mappingsV = mappings, &nbPalettesV = nbPalettes]() { fprintf( - stderr, "Color set mappings: (%zu palette%s)\n", nbPalettes, nbPalettes != 1 ? "s" : "" + stderr, "Color set mappings: (%zu palette%s)\n", nbPalettesV, nbPalettesV != 1 ? "s" : "" ); - for (size_t i = 0; i < mappings.size(); ++i) { - fprintf(stderr, "%zu -> %zu\n", i, mappings[i]); + for (size_t i = 0; i < mappingsV.size(); ++i) { + fprintf(stderr, "%zu -> %zu\n", i, mappingsV[i]); } - style_Reset(stderr); - } + }); // LCOV_EXCL_STOP std::vector palettes(nbPalettes); @@ -455,8 +454,7 @@ static std::pair, std::vector> static void outputPalettes(std::vector const &palettes) { // LCOV_EXCL_START - if (checkVerbosity(VERB_INFO)) { - style_Set(stderr, STYLE_MAGENTA, false); + verboseDo(VERB_INFO, [&]() { for (Palette const &palette : palettes) { fputs("{ ", stderr); for (uint16_t colorIndex : palette) { @@ -464,8 +462,7 @@ static void outputPalettes(std::vector const &palettes) { } fputs("}\n", stderr); } - style_Reset(stderr); - } + }); // LCOV_EXCL_STOP if (palettes.size() > options.nbPalettes) { @@ -950,8 +947,7 @@ void process() { Image image(options.input); // This also sets `hasTransparentPixels` as a side effect // LCOV_EXCL_START - if (checkVerbosity(VERB_INFO)) { - style_Set(stderr, STYLE_MAGENTA, false); + verboseDo(VERB_INFO, [&]() { fputs("Image colors: [ ", stderr); for (std::optional const &slot : image.colors) { if (!slot.has_value()) { @@ -960,8 +956,7 @@ void process() { fprintf(stderr, "#%08x, ", slot->toCSS()); } fputs("]\n", stderr); - style_Reset(stderr); - } + }); // LCOV_EXCL_STOP if (options.palSpecType == Options::DMG) { @@ -1050,8 +1045,7 @@ void process() { case ColorSet::STRICT_SUPERSET: // Override the previous color set that this one is a strict superset of - if (checkVerbosity(VERB_DEBUG)) { - style_Set(stderr, STYLE_MAGENTA, false); + verboseDo(VERB_DEBUG, [&]() { fprintf( stderr, "- Tile (%" PRIu32 ", %" PRIu32 ") overrides color set #%zu: [", @@ -1067,8 +1061,7 @@ void process() { fprintf(stderr, "$%04x, ", color); } fputs("]\n", stderr); - style_Reset(stderr); - } + }); colorSets[n] = colorSet; // Remove any other color sets that we are also a strict superset of @@ -1116,8 +1109,7 @@ void process() { attrs.colorSetID = colorSets.size(); colorSets.push_back(colorSet); - if (checkVerbosity(VERB_DEBUG)) { - style_Set(stderr, STYLE_MAGENTA, false); + verboseDo(VERB_DEBUG, [&]() { fprintf( stderr, "- Tile (%" PRIu32 ", %" PRIu32 ") adds color set #%zu: [", @@ -1129,8 +1121,7 @@ void process() { fprintf(stderr, "$%04x, ", color); } fputs("]\n", stderr); - style_Reset(stderr); - } + }); continue_visiting_tiles:; } @@ -1142,8 +1133,7 @@ continue_visiting_tiles:; colorSets.size() != 1 ? "s" : "" ); // LCOV_EXCL_START - if (checkVerbosity(VERB_INFO)) { - style_Set(stderr, STYLE_MAGENTA, false); + verboseDo(VERB_INFO, [&]() { for (ColorSet const &colorSet : colorSets) { fputs("[ ", stderr); for (uint16_t color : colorSet) { @@ -1151,8 +1141,7 @@ continue_visiting_tiles:; } fputs("]\n", stderr); } - style_Reset(stderr); - } + }); // LCOV_EXCL_STOP if (colorSets.empty()) { diff --git a/src/link/main.cpp b/src/link/main.cpp index d9db7055..42157b6c 100644 --- a/src/link/main.cpp +++ b/src/link/main.cpp @@ -17,7 +17,7 @@ #include "diagnostics.hpp" #include "linkdefs.hpp" #include "script.hpp" // Generated from script.y -#include "style.hpp" +#include "style.hpp" // style_Parse #include "usage.hpp" #include "util.hpp" // UpperMap, printChar #include "verbosity.hpp" @@ -329,12 +329,6 @@ static void parseArg(int ch, char *arg) { // LCOV_EXCL_START static void verboseOutputConfig() { - if (!checkVerbosity(VERB_CONFIG)) { - return; - } - - style_Set(stderr, STYLE_MAGENTA, false); - usage.printVersion(true); printVVVVVVerbosity(); @@ -414,15 +408,13 @@ static void verboseOutputConfig() { // -n/--sym printPath("Output sym file", options.symFileName); fputs("Ready for linking\n", stderr); - - style_Reset(stderr); } // LCOV_EXCL_STOP int main(int argc, char *argv[]) { cli_ParseArgs(argc, argv, optstring, longopts, parseArg, usage); - verboseOutputConfig(); + verboseDo(VERB_CONFIG, verboseOutputConfig); if (localOptions.inputFileNames.empty()) { usage.printAndExit("No input file specified (pass \"-\" to read from standard input)");