From 726ac9d961ec104d73177fd6f1c859b7c1d1d038 Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Fri, 17 May 2024 15:00:48 -0700 Subject: [PATCH 1/9] Adding `derive_configuration` to allow for config file overrides to come from environment variables --- include/orc/str.hpp | 2 + src/main.cpp | 215 ++++++++++++++++++++++++++------------------ src/str.cpp | 9 ++ 3 files changed, 137 insertions(+), 89 deletions(-) diff --git a/include/orc/str.hpp b/include/orc/str.hpp index 2590e4c..3cafa91 100644 --- a/include/orc/str.hpp +++ b/include/orc/str.hpp @@ -33,4 +33,6 @@ inline std::string format_pct(float x, float total) { return format_pct(x / total); } +std::string toupper(std::string&& s); + /**************************************************************************************************/ diff --git a/src/main.cpp b/src/main.cpp index 207bd99..8dc3c6d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,7 +84,42 @@ void open_output_file(const std::string& a, const std::string& b) { /**************************************************************************************************/ -void process_orc_config_file(const char* bin_path_string) { +template +T parse_enval(std::string&&) = delete; + +template <> +std::string parse_enval(std::string&& x) { + assert(!x.empty()); + return x; +} + +template <> +bool parse_enval(std::string&& x) { + assert(!x.empty()); + return x != "0" && toupper(std::move(x)) != "FALSE"; +} + +template <> +std::size_t parse_enval(std::string&& x) { + assert(!x.empty()); + return std::max(std::atoi(x.c_str()), 0); +} + +template +T derive_configuration(const char* key, + const toml::parse_result& settings, + T&& fallback) { + T result = settings[key].value_or(fallback); + std::string envar = toupper(std::string("ORC_") + key); + if (const char* enval = std::getenv(envar.c_str())) { + result = parse_enval(enval); + } + return result; +} + +/**************************************************************************************************/ + +void process_orc_configuration(const char* bin_path_string) { std::filesystem::path pwd(std::filesystem::current_path()); std::filesystem::path bin_path(pwd / bin_path_string); std::filesystem::path config_path; @@ -114,104 +149,106 @@ void process_orc_config_file(const char* bin_path_string) { bin_path = parent; } + toml::parse_result settings; + if (exists(config_path)) { try { - auto settings = toml::parse_file(config_path.string()); - auto& app_settings = settings::instance(); - - app_settings._graceful_exit = settings["graceful_exit"].value_or(false); - app_settings._max_violation_count = settings["max_error_count"].value_or(0); - app_settings._forward_to_linker = settings["forward_to_linker"].value_or(true); - app_settings._standalone_mode = settings["standalone_mode"].value_or(false); - app_settings._dylib_scan_mode = settings["dylib_scan_mode"].value_or(false); - app_settings._parallel_processing = settings["parallel_processing"].value_or(true); - app_settings._filter_redundant = settings["filter_redundant"].value_or(true); - app_settings._print_object_file_list = settings["print_object_file_list"].value_or(false); - app_settings._relative_output_file = settings["relative_output_file"].value_or(""); - - if (settings["output_file"]) { - std::string fn = *settings["output_file"].value(); - open_output_file("", fn); - } + settings = toml::parse_file(config_path.string()); + } catch (const toml::parse_error& err) { + cerr_safe([&](auto& s) { s << "Parsing failed:\n" << err << "\n"; }); + throw std::runtime_error("configuration parsing error"); + } + } else { + cerr_safe([&](auto& s) { s << "ORC config file: not found\n"; }); + } - if (auto log_level = settings["log_level"].value()) { - const auto& level = *log_level; - if (level == "silent") { - app_settings._log_level = settings::log_level::silent; - } else if (level == "warning") { - app_settings._log_level = settings::log_level::warning; - } else if (level == "info") { - app_settings._log_level = settings::log_level::info; - } else if (level == "verbose") { - app_settings._log_level = settings::log_level::verbose; - } else { - // not a known value. Switch to verbose! - app_settings._log_level = settings::log_level::verbose; - cout_safe( - [&](auto& s) { s << "warning: Unknown log level (using verbose)\n"; }); - } - } + auto& app_settings = settings::instance(); + + app_settings._graceful_exit = derive_configuration("graceful_exit", settings, false); + app_settings._max_violation_count = derive_configuration("max_error_count", settings, std::size_t(0)); + app_settings._forward_to_linker = derive_configuration("forward_to_linker", settings, true); + app_settings._standalone_mode = derive_configuration("standalone_mode", settings, false); + app_settings._dylib_scan_mode = derive_configuration("dylib_scan_mode", settings, false); + app_settings._parallel_processing = derive_configuration("parallel_processing", settings, true); + app_settings._filter_redundant = derive_configuration("filter_redundant", settings, true); + app_settings._print_object_file_list = derive_configuration("print_object_file_list", settings, false); + app_settings._relative_output_file = derive_configuration("relative_output_file", settings, std::string()); + + const std::string log_level = derive_configuration("log_level", settings, std::string("warning")); + const std::string output_file = derive_configuration("output_file", settings, std::string()); + const std::string output_file_mode = derive_configuration("output_file_mode", settings, std::string("text")); + + // Do this early so we can log the ensuing output if it happens. + if (!output_file.empty()) { + open_output_file(std::string(), output_file); + } - if (app_settings._standalone_mode && app_settings._dylib_scan_mode) { - throw std::logic_error( - "Both standalone and dylib scanning mode are enabled. Pick one."); - } + // Do this early, too, so we can _suppress_ the output if we need to. + if (output_file_mode == "text") { + app_settings._output_file_mode = settings::output_file_mode::text; + } else if (output_file_mode == "json") { + app_settings._output_file_mode = settings::output_file_mode::json; + } else if (log_level_at_least(settings::log_level::warning)) { + cout_safe([&](auto& s) { + s << "warning: unknown output_file_mode '" << output_file_mode << "'; using text\n"; + }); + } - if (app_settings._dylib_scan_mode) { - app_settings._forward_to_linker = false; - } + if (log_level == "silent") { + app_settings._log_level = settings::log_level::silent; + } else if (log_level == "warning") { + app_settings._log_level = settings::log_level::warning; + } else if (log_level == "info") { + app_settings._log_level = settings::log_level::info; + } else if (log_level == "verbose") { + app_settings._log_level = settings::log_level::verbose; + } else { + // not a known value. Switch to verbose! + app_settings._log_level = settings::log_level::verbose; + cout_safe( + [&](auto& s) { s << "warning: unknown log_level '" << log_level << "'; using verbose\n"; }); + } - auto read_string_list = [&_settings = settings](const char* name) { - std::vector result; - if (auto* array = _settings.get_as(name)) { - for (const auto& entry : *array) { - if (auto symbol = entry.value()) { - result.push_back(*symbol); - } - } - } - std::sort(result.begin(), result.end()); - return result; - }; - - app_settings._symbol_ignore = read_string_list("symbol_ignore"); - app_settings._violation_report = read_string_list("violation_report"); - app_settings._violation_ignore = read_string_list("violation_ignore"); - - if (!app_settings._violation_report.empty() && - !app_settings._violation_ignore.empty()) { - if (log_level_at_least(settings::log_level::warning)) { - cout_safe([&](auto& s) { - s << "warning: Both `violation_report` and `violation_ignore` lists found\n"; - s << "warning: `violation_report` will be ignored in favor of `violation_ignore`\n"; - }); - } - } + if (app_settings._standalone_mode && app_settings._dylib_scan_mode) { + throw std::logic_error( + "Both standalone and dylib scanning mode are enabled. Pick one."); + } - if (settings["output_file_mode"]) { - const std::string mode = *settings["output_file_mode"].value(); - if (mode == "text") { - app_settings._output_file_mode = settings::output_file_mode::text; - } else if (mode == "json") { - app_settings._output_file_mode = settings::output_file_mode::json; - } else if (log_level_at_least(settings::log_level::warning)) { - cout_safe([&](auto& s) { - s << "warning: unknown `output_file_mode`: " << mode << "\n"; - }); + if (app_settings._dylib_scan_mode) { + app_settings._forward_to_linker = false; + } + + auto read_string_list = [&_settings = settings](const char* name) { + std::vector result; + if (auto* array = _settings.get_as(name)) { + for (const auto& entry : *array) { + if (auto symbol = entry.value()) { + result.push_back(*symbol); } } + } + std::sort(result.begin(), result.end()); + return result; + }; - if (log_level_at_least(settings::log_level::info)) { - cout_safe([&](auto& s) { - s << "info: ORC config file: " << config_path.string() << "\n"; - }); - } - } catch (const toml::parse_error& err) { - cerr_safe([&](auto& s) { s << "Parsing failed:\n" << err << "\n"; }); - throw std::runtime_error("configuration parsing error"); + app_settings._symbol_ignore = read_string_list("symbol_ignore"); + app_settings._violation_report = read_string_list("violation_report"); + app_settings._violation_ignore = read_string_list("violation_ignore"); + + if (!app_settings._violation_report.empty() && + !app_settings._violation_ignore.empty()) { + if (log_level_at_least(settings::log_level::warning)) { + cout_safe([&](auto& s) { + s << "warning: Both `violation_report` and `violation_ignore` lists found\n"; + s << "warning: `violation_report` will be ignored in favor of `violation_ignore`\n"; + }); } - } else { - cerr_safe([&](auto& s) { s << "ORC config file: not found\n"; }); + } + + if (log_level_at_least(settings::log_level::info)) { + cout_safe([&](auto& s) { + s << "info: ORC config file: " << config_path.string() << "\n"; + }); } } @@ -483,7 +520,7 @@ int main(int argc, char** argv) try { signal(SIGINT, interrupt_callback_handler); - process_orc_config_file(argv[0]); + process_orc_configuration(argv[0]); cmdline_results cmdline = process_command_line(argc, argv); diff --git a/src/str.cpp b/src/str.cpp index 93b7f48..2ede470 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -90,3 +90,12 @@ std::string format_pct(float x) { } /**************************************************************************************************/ + +std::string toupper(std::string&& s) { + std::transform(s.begin(), s.end(), s.begin(), [](auto c){ + return std::toupper(c); + }); + return s; +} + +/**************************************************************************************************/ From ecbccc7695c34907c43821d310c22b7978728fa5 Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Fri, 17 May 2024 15:16:48 -0700 Subject: [PATCH 2/9] adding new tests to dogfood --- .github/workflows/build-and-test.yml | 7 ++++++- include/orc/str.hpp | 2 +- src/orc.cpp | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index a2d757c..0d872c6 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -32,7 +32,12 @@ jobs: id: build-orc-orc_dogfood continue-on-error: true run: | - xcodebuild -project ./build/orc.xcodeproj -scheme orc_dogfood -configuration Debug + ORC_OUTPUT_FILE=./output.json ORC_OUTPUT_FILE_MODE=json xcodebuild -project ./build/orc.xcodeproj -scheme orc_dogfood -configuration Debug + test `cat output.json | jq '.["synopsis"]["violations"]'` == 0 + test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 + test `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 + test `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 + test `cat output.json | jq '.["synopsis"]["object_files_scanned"]'` != 0 - name: 🛠️ orc release id: build-orc-release continue-on-error: true diff --git a/include/orc/str.hpp b/include/orc/str.hpp index 3cafa91..ba6303e 100644 --- a/include/orc/str.hpp +++ b/include/orc/str.hpp @@ -30,7 +30,7 @@ std::string format_size(std::size_t x, format_mode mode = format_mode::binary); std::string format_pct(float x); inline std::string format_pct(float x, float total) { - return format_pct(x / total); + return format_pct(total ? x / total : 0); } std::string toupper(std::string&& s); diff --git a/src/orc.cpp b/src/orc.cpp index 98a5239..c050627 100644 --- a/src/orc.cpp +++ b/src/orc.cpp @@ -644,7 +644,7 @@ std::string to_json(const std::vector& reports) { constexpr auto spaces_k = 0; // no pretty-printing in release builds #endif - nlohmann::json violations; + nlohmann::json violations = nlohmann::json::object_t(); for (const auto& report : reports) { assert(violations.count(report._symbol) == 0); @@ -657,7 +657,7 @@ std::string to_json(const std::vector& reports) { synopsis["object_files_scanned"] = g._object_file_count.load(); synopsis["dies_processed"] = g._die_processed_count.load(); synopsis["dies_skipped"] = g._die_skipped_count.load(); - synopsis["dies_skipped_pct"] = g._die_skipped_count * 100. / g._die_processed_count; + synopsis["dies_skipped_pct"] = g._die_processed_count ? (g._die_skipped_count * 100. / g._die_processed_count) : 0; synopsis["unique_symbols"] = g._unique_symbol_count.load(); nlohmann::json result = nlohmann::json::object_t { From d1bf6a73491b58e491cc2c709bebb5f537ff34fe Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Fri, 17 May 2024 15:28:01 -0700 Subject: [PATCH 3/9] testing a failure --- .github/workflows/build-and-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 0d872c6..aa1af9e 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -32,8 +32,8 @@ jobs: id: build-orc-orc_dogfood continue-on-error: true run: | - ORC_OUTPUT_FILE=./output.json ORC_OUTPUT_FILE_MODE=json xcodebuild -project ./build/orc.xcodeproj -scheme orc_dogfood -configuration Debug - test `cat output.json | jq '.["synopsis"]["violations"]'` == 0 + ORC_OUTPUT_FILE=./output.json ORC_OUTPUT_FILE_MODE=json xcodebuild -json -project ./build/orc.xcodeproj -scheme orc_dogfood -configuration Debug -hideShellScriptEnvironment + test `cat output.json | jq '.["synopsis"]["violations"]'` == 42 test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 test `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 test `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 From d266e60aaba23e04a2de1583a1968a2b43f3fe1d Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Fri, 17 May 2024 15:43:15 -0700 Subject: [PATCH 4/9] better test reporting --- .github/workflows/build-and-test.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index aa1af9e..a55a828 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -33,11 +33,10 @@ jobs: continue-on-error: true run: | ORC_OUTPUT_FILE=./output.json ORC_OUTPUT_FILE_MODE=json xcodebuild -json -project ./build/orc.xcodeproj -scheme orc_dogfood -configuration Debug -hideShellScriptEnvironment - test `cat output.json | jq '.["synopsis"]["violations"]'` == 42 - test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 - test `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 - test `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 - test `cat output.json | jq '.["synopsis"]["object_files_scanned"]'` != 0 + if [ `cat output.json | jq '.["synopsis"]["violations"]'` == 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 + if [ `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 + if [ `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 + if [ `cat output.json | jq '.["synopsis"]["object_files_scanned"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 - name: 🛠️ orc release id: build-orc-release continue-on-error: true From 84ca0b3acfe9fd56c330d4e1421889f3d6f28b3d Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Fri, 17 May 2024 20:55:17 -0700 Subject: [PATCH 5/9] tweak --- .github/workflows/build-and-test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index a55a828..ab96aed 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -33,10 +33,10 @@ jobs: continue-on-error: true run: | ORC_OUTPUT_FILE=./output.json ORC_OUTPUT_FILE_MODE=json xcodebuild -json -project ./build/orc.xcodeproj -scheme orc_dogfood -configuration Debug -hideShellScriptEnvironment - if [ `cat output.json | jq '.["synopsis"]["violations"]'` == 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 - if [ `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 - if [ `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 - if [ `cat output.json | jq '.["synopsis"]["object_files_scanned"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi test `cat output.json | jq '.["synopsis"]["dies_processed"]'` != 0 + if [ `cat output.json | jq '.["synopsis"]["violations"]'` == 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi + if [ `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi + if [ `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi + if [ `cat output.json | jq '.["synopsis"]["object_files_scanned"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi - name: 🛠️ orc release id: build-orc-release continue-on-error: true From f3f1828db894ce1df14f77837bd9b66ed782cdf4 Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Fri, 17 May 2024 20:58:56 -0700 Subject: [PATCH 6/9] tweak --- .github/workflows/build-and-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index ab96aed..b106e7c 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -33,6 +33,7 @@ jobs: continue-on-error: true run: | ORC_OUTPUT_FILE=./output.json ORC_OUTPUT_FILE_MODE=json xcodebuild -json -project ./build/orc.xcodeproj -scheme orc_dogfood -configuration Debug -hideShellScriptEnvironment + cat output.json if [ `cat output.json | jq '.["synopsis"]["violations"]'` == 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi if [ `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi if [ `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi From c3a15b6d2ee1b3f8cdbb98cf25a9005ffe4ba43b Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Mon, 20 May 2024 11:03:26 -0700 Subject: [PATCH 7/9] tweak --- .github/workflows/build-and-test.yml | 9 +++++---- src/orc.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index b106e7c..98eb9b9 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -34,10 +34,11 @@ jobs: run: | ORC_OUTPUT_FILE=./output.json ORC_OUTPUT_FILE_MODE=json xcodebuild -json -project ./build/orc.xcodeproj -scheme orc_dogfood -configuration Debug -hideShellScriptEnvironment cat output.json - if [ `cat output.json | jq '.["synopsis"]["violations"]'` == 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi - if [ `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi - if [ `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi - if [ `cat output.json | jq '.["synopsis"]["object_files_scanned"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi + echo # newline + if [ `cat output.json | jq '.["synopsis"]["violations"]'` == 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi + if [ `cat output.json | jq '.["synopsis"]["dies_skipped"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi + if [ `cat output.json | jq '.["synopsis"]["unique_symbols"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi + if [ `cat output.json | jq '.["synopsis"]["object_files_scanned"]'` != 0 ]; then echo "SUCCESS"; else echo "FAILURE"; exit 1; fi - name: 🛠️ orc release id: build-orc-release continue-on-error: true diff --git a/src/orc.cpp b/src/orc.cpp index c050627..bd42074 100644 --- a/src/orc.cpp +++ b/src/orc.cpp @@ -554,7 +554,7 @@ void to_json(nlohmann::json& j, const odrv_report::conflict_details& c) { for (std::size_t i = 0; i < ancestry._count; ++i) { const std::string key = ancestry._ancestors[i].allocate_string(); if (i == (ancestry._count - 1)) { - node->push_back(key); + (*node)["objects"].push_back(key); } else { node = &(*node)[key]; } From 20baa98501a30ab5de6f7013b4527eab36912c36 Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Mon, 20 May 2024 11:25:35 -0700 Subject: [PATCH 8/9] tweak --- src/orc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orc.cpp b/src/orc.cpp index bd42074..06993c6 100644 --- a/src/orc.cpp +++ b/src/orc.cpp @@ -554,7 +554,7 @@ void to_json(nlohmann::json& j, const odrv_report::conflict_details& c) { for (std::size_t i = 0; i < ancestry._count; ++i) { const std::string key = ancestry._ancestors[i].allocate_string(); if (i == (ancestry._count - 1)) { - (*node)["objects"].push_back(key); + (*node)["object_files"].push_back(key); } else { node = &(*node)[key]; } From b7669a03146b188f019b5601ce890ac187a8ee72 Mon Sep 17 00:00:00 2001 From: Foster Brereton Date: Mon, 20 May 2024 11:36:46 -0700 Subject: [PATCH 9/9] improvements to graceful exit logic --- src/main.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8dc3c6d..bc725fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -444,11 +444,13 @@ auto epilogue(bool exception) { }); } - if (exception || g._odrv_count != 0) { - return settings::instance()._graceful_exit ? EXIT_SUCCESS : EXIT_FAILURE; + if (exception) { + return EXIT_FAILURE; + } else if (settings::instance()._graceful_exit) { + return EXIT_SUCCESS; } - return EXIT_SUCCESS; + return g._odrv_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } /**************************************************************************************************/ @@ -584,7 +586,7 @@ int main(int argc, char** argv) try { return epilogue(true); } catch (...) { cerr_safe([&](auto& s) { s << "Fatal error: unknown\n"; }); - return epilogue(false); + return epilogue(true); } /**************************************************************************************************/