From 8a549e492bd7e6a92858f224a53919574ac199f4 Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Wed, 30 Sep 2026 17:42:10 -0700 Subject: [PATCH 01/10] .cppcheck_suppress: fix exclusion of fmt headers in cppcheck analysis --- .cppcheck_suppress | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cppcheck_suppress b/.cppcheck_suppress index fc80470..40c9e86 100644 --- a/.cppcheck_suppress +++ b/.cppcheck_suppress @@ -35,7 +35,7 @@ missingInclude *:*CLI11.hpp *:*json.hpp *:*boost_unordered.hpp -*:fmt/*.h +*:*fmt/*.h # Problem caused by external files toomanyconfigs # More problems caused by external files -- with too many ifdefs From bd69d5d053cb773b6f6cbd40bab40fea5a326537 Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Wed, 30 Sep 2026 17:42:47 -0700 Subject: [PATCH 02/10] src/contaminant_set.hcpp: updated iwyu --- src/contaminant_set.cpp | 1 - src/contaminant_set.hpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/contaminant_set.cpp b/src/contaminant_set.cpp index 64126d7..859a0e1 100644 --- a/src/contaminant_set.cpp +++ b/src/contaminant_set.cpp @@ -11,7 +11,6 @@ #include #include #include -#include // for std::get #include #include diff --git a/src/contaminant_set.hpp b/src/contaminant_set.hpp index bd38475..8da93ac 100644 --- a/src/contaminant_set.hpp +++ b/src/contaminant_set.hpp @@ -5,7 +5,6 @@ #include #include -#include // for std::pair #include #include #include From ae8a30d44453ea50bfacd148156cf4761e9a2b96 Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Wed, 30 Sep 2026 17:44:34 -0700 Subject: [PATCH 03/10] src/tile_processor.cpp src/report.cpp src/html.cpp: fixing includes --- src/html.cpp | 5 ++--- src/report.cpp | 5 +++-- src/tile_processor.cpp | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/html.cpp b/src/html.cpp index 3333cd1..b34324c 100644 --- a/src/html.cpp +++ b/src/html.cpp @@ -29,7 +29,6 @@ #include #include #include -#include // for std::get probably in fmt #include // for pair #include @@ -371,8 +370,8 @@ basic_stats_html(const file_info &info, [[nodiscard]] auto tile_html(const tile_processor::tiles_centered_t ¢ered, - const std::vector &groups, const file_grades &grades) - -> std::string { + const std::vector &groups, + const file_grades &grades) -> std::string { static constexpr auto label = "tile"; static constexpr auto n_quants = 20.0; // ADS: ??? (-10: red, 0: light blue, +10: dark blue) diff --git a/src/report.cpp b/src/report.cpp index 96149bf..438f5d1 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -209,8 +210,8 @@ basic_stats_report(const file_info &info, [[nodiscard]] auto tile_report(const tile_processor::tiles_centered_t ¢ered, - const std::vector &groups, const file_grades &grades) - -> std::string { + const std::vector &groups, + const file_grades &grades) -> std::string { static constexpr auto label = "tile"; static constexpr auto max_precision{std::numeric_limits::digits10}; static constexpr auto start_tag = ">>Per tile sequence quality\t{}\n"; diff --git a/src/tile_processor.cpp b/src/tile_processor.cpp index 995ef35..7378450 100644 --- a/src/tile_processor.cpp +++ b/src/tile_processor.cpp @@ -26,7 +26,6 @@ #include #include #include -#include // for std::get #include #include From 5d7f779e3629b324d1229e9ea3d5c309909ea20f Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Wed, 30 Sep 2026 17:44:53 -0700 Subject: [PATCH 04/10] src/falco_analyzer.cpp: iwyu --- src/falco_analyzer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/falco_analyzer.cpp b/src/falco_analyzer.cpp index 1938fac..fa66d41 100644 --- a/src/falco_analyzer.cpp +++ b/src/falco_analyzer.cpp @@ -20,7 +20,6 @@ #include #include #include -#include // for std::get (iwyu fp) #include #include #include From c21ca3a2193d574e7de1271dea508742fd080c3f Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Wed, 30 Sep 2026 18:54:15 -0700 Subject: [PATCH 05/10] src/falco.cpp: fixing some clang-tidy stuff that appears on macos --- src/falco.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/falco.cpp b/src/falco.cpp index 14fe9b3..e0a4c3f 100644 --- a/src/falco.cpp +++ b/src/falco.cpp @@ -345,17 +345,19 @@ main(int argc, char *argv[]) { argv = app.ensure_utf8(argv); app.usage( std::format("Usage: {} [options] -o OUTDIR INFILES", PROJECT_NAME)); + // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) if (argc >= 2) app.footer(std::format(description, falco::get_share_dir())); + // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks) // clang-format off // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers) app.get_formatter()->long_option_alignment_ratio(0.2); app.set_help_flag("-h,--help", "Print more detailed help"); - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) app.set_version_flag("--version", VERSION, "Print program version"); - app.add_flag("--license", [&](auto) { - std::print("{}", license_text); throw CLI::Success(); }, + app.add_flag("--license", + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) + [&](auto) { std::print("{}", license_text); throw CLI::Success(); }, "Print full license") ->callback_priority(CLI::CallbackPriority::PreRequirementsCheck); auto infiles_opt = From 908431160325ec3d83994b36a6025e38f4c43a83 Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Wed, 30 Sep 2026 19:12:45 -0700 Subject: [PATCH 06/10] .clang-tidy: allowing structs to have non-private members under broader checks --- .clang-tidy | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-tidy b/.clang-tidy index be97404..e85eff3 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -39,6 +39,7 @@ CheckOptions: cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove: 'true' cppcoreguidelines-avoid-magic-numbers.IgnoredIntegerValues: '1;2;3;4;10' cppcoreguidelines-avoid-magic-numbers.IgnoredFloatingPointValues: '1.0;2.0;10.0;100.0' + misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: true google-readability-braces-around-statements.ShortStatementLines: '1' google-readability-namespace-comments.ShortNamespaceLines: '10' google-readability-namespace-comments.SpacesBeforeComments: '2' From 858858eceedf31c65b77b9c4ba84909502505333 Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Wed, 30 Sep 2026 19:13:50 -0700 Subject: [PATCH 07/10] src/bgzf_reader.cpp: replacing dangerous std::memcpy with std::copy_n --- src/bgzf_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bgzf_reader.cpp b/src/bgzf_reader.cpp index a23f34e..eed3cc9 100644 --- a/src/bgzf_reader.cpp +++ b/src/bgzf_reader.cpp @@ -61,7 +61,7 @@ bgzf_reader::read_data() -> bool { if (at_eof()) return false; const auto unused_in = std::distance(next_in, end_in); - std::memcpy(inbuf.get(), next_in, unused_in); + std::copy_n(next_in, unused_in, inbuf.get()); next_in = inbuf.get(); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) end_in = next_in + unused_in; From 894453e5dd6713c6c71834b363f2f3da8216b231 Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Thu, 1 Oct 2026 08:41:55 -0700 Subject: [PATCH 08/10] iwyu confusing reverting --- src/bgzf_reader.cpp | 2 ++ src/contaminant_set.cpp | 2 ++ src/contaminant_set.hpp | 1 + src/falco_analyzer.cpp | 1 + src/html.cpp | 1 + src/report.cpp | 1 - src/tile_processor.cpp | 2 ++ 7 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bgzf_reader.cpp b/src/bgzf_reader.cpp index eed3cc9..c9cd571 100644 --- a/src/bgzf_reader.cpp +++ b/src/bgzf_reader.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT; Copyright 2026 Andrew D Smith #include "bgzf_reader.hpp" + #include "bgzf_block.hpp" #include @@ -14,6 +15,7 @@ #include #include #include +#include [[nodiscard]] static inline constexpr auto get_unaligned_le32(const auto p) -> std::int32_t { diff --git a/src/contaminant_set.cpp b/src/contaminant_set.cpp index 859a0e1..29b11bd 100644 --- a/src/contaminant_set.cpp +++ b/src/contaminant_set.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT; Copyright 2026 Andrew D Smith #include "contaminant_set.hpp" + #include "falco_utils.hpp" #include @@ -11,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/src/contaminant_set.hpp b/src/contaminant_set.hpp index 8da93ac..2948a81 100644 --- a/src/contaminant_set.hpp +++ b/src/contaminant_set.hpp @@ -8,6 +8,7 @@ #include #include #include +#include struct contaminant_set { static auto diff --git a/src/falco_analyzer.cpp b/src/falco_analyzer.cpp index fa66d41..4edcd87 100644 --- a/src/falco_analyzer.cpp +++ b/src/falco_analyzer.cpp @@ -23,6 +23,7 @@ #include #include #include +#include class run_mode; diff --git a/src/html.cpp b/src/html.cpp index b34324c..7bd93f0 100644 --- a/src/html.cpp +++ b/src/html.cpp @@ -31,6 +31,7 @@ #include #include // for pair #include +#include [[nodiscard]] static auto get_summary(const file_grades &grades) -> std::string { diff --git a/src/report.cpp b/src/report.cpp index 438f5d1..07d5b4d 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/src/tile_processor.cpp b/src/tile_processor.cpp index 7378450..34a485c 100644 --- a/src/tile_processor.cpp +++ b/src/tile_processor.cpp @@ -2,6 +2,7 @@ #include "tile_processor.hpp" + #include "base_groups.hpp" #include "falco_file_format.hpp" #include "falco_grade.hpp" @@ -28,6 +29,7 @@ #include #include #include +#include auto tile_processor::init(const file_info &info) -> void { From 07cba499506551bf9678e4000da826969b5a63be Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Thu, 1 Oct 2026 10:21:55 -0700 Subject: [PATCH 09/10] formatting --- src/contaminant_set.hpp | 2 +- src/falco_analyzer.cpp | 2 +- src/html.cpp | 2 +- src/tile_processor.cpp | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/contaminant_set.hpp b/src/contaminant_set.hpp index 2948a81..ef62a33 100644 --- a/src/contaminant_set.hpp +++ b/src/contaminant_set.hpp @@ -5,10 +5,10 @@ #include #include +#include #include #include #include -#include struct contaminant_set { static auto diff --git a/src/falco_analyzer.cpp b/src/falco_analyzer.cpp index 4edcd87..e17a965 100644 --- a/src/falco_analyzer.cpp +++ b/src/falco_analyzer.cpp @@ -20,10 +20,10 @@ #include #include #include +#include #include #include #include -#include class run_mode; diff --git a/src/html.cpp b/src/html.cpp index 7bd93f0..7ffd728 100644 --- a/src/html.cpp +++ b/src/html.cpp @@ -29,9 +29,9 @@ #include #include #include +#include #include // for pair #include -#include [[nodiscard]] static auto get_summary(const file_grades &grades) -> std::string { diff --git a/src/tile_processor.cpp b/src/tile_processor.cpp index 34a485c..5fe1d93 100644 --- a/src/tile_processor.cpp +++ b/src/tile_processor.cpp @@ -2,7 +2,6 @@ #include "tile_processor.hpp" - #include "base_groups.hpp" #include "falco_file_format.hpp" #include "falco_grade.hpp" @@ -27,9 +26,9 @@ #include #include #include +#include #include #include -#include auto tile_processor::init(const file_info &info) -> void { From 0e4dfbc07e6e3850a3108e121147e051f1053405 Mon Sep 17 00:00:00 2001 From: Andrew D Smith Date: Thu, 1 Oct 2026 10:22:50 -0700 Subject: [PATCH 10/10] src/bgzf_reader.hcpp: moving the gzip file header struct into the source file from the header --- src/bgzf_reader.cpp | 100 +++++++++++++++++++++++++++++++------------- src/bgzf_reader.hpp | 29 ------------- 2 files changed, 70 insertions(+), 59 deletions(-) diff --git a/src/bgzf_reader.cpp b/src/bgzf_reader.cpp index c9cd571..fcd3ceb 100644 --- a/src/bgzf_reader.cpp +++ b/src/bgzf_reader.cpp @@ -4,6 +4,8 @@ #include "bgzf_block.hpp" +#include +#include #include #include #include @@ -15,35 +17,6 @@ #include #include #include -#include - -[[nodiscard]] static inline constexpr auto -get_unaligned_le32(const auto p) -> std::int32_t { - std::int32_t value{}; - std::memcpy(std::addressof(value), p, sizeof(std::int32_t)); - if constexpr (std::endian::native == std::endian::big) - return std::byteswap(value); - else - return value; -} - -[[nodiscard]] static inline constexpr auto -get_isize(const auto data, const auto data_size) { - static constexpr decltype(data_size) isize_size = 4; - assert(data_size > isize_size); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - const auto data_isize = data + data_size - isize_size; - return data_size < isize_size ? 0 : get_unaligned_le32(data_isize); -} - -static inline auto -assign(gzip_header &hdr, const auto data) -> void { - // ADS: data from the file takes 18 bytes, the fields of the struct take 18 - // bytes, but the struct occupies 20 due to uint32_t members - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - std::memcpy(reinterpret_cast(&hdr), std::to_address(data), - gzip_header_size); -} bgzf_reader::bgzf_reader(const std::string &filename, const std::int64_t buf_size) : @@ -77,17 +50,84 @@ bgzf_reader::read_data() -> bool { return n_bytes > 0; } +namespace { + +static constexpr auto gzip_header_size = 18; + +struct gzip_header { + static constexpr auto magic1 = 0x1F; + static constexpr auto magic2 = 0x8B; + static constexpr auto size_index = 16; + + std::array data{}; + + /// internal structure + // std::uint8_t id1{}; // 0 + // std::uint8_t id2{}; // 1 + // std::uint8_t cm_eight{}; // 2 + // std::uint8_t flg{}; // 3 + // std::uint32_t mtime{}; // 7 [4] + // std::uint8_t xfl{}; // 8 + // std::uint8_t os{}; // 9 + // std::uint16_t xlen{}; // 11 [2] + // char b{}; // 12 + // char c{}; // 13 + // std::uint16_t two{}; // 14 [2] + // std::uint16_t size{}; // 16 [2] + + [[nodiscard]] auto + get_size() const -> std::uint16_t { + std::uint16_t s{}; + std::memcpy(std::addressof(s), std::addressof(data[size_index]), + sizeof(std::uint16_t)); + return s; + } + + [[nodiscard]] auto + check_magic() const -> bool { + return data[0] == magic1 && data[1] == magic2; // ADS: check b and c also? + } +}; + +[[nodiscard]] static inline constexpr auto +get_unaligned_le32(const auto p) -> std::int32_t { + std::int32_t value{}; + std::memcpy(std::addressof(value), p, sizeof(std::int32_t)); + if constexpr (std::endian::native == std::endian::big) + return std::byteswap(value); + else + return value; +} + +[[nodiscard]] static inline constexpr auto +get_isize(const auto data, const auto data_size) { + static constexpr decltype(data_size) isize_size = 4; + assert(data_size > isize_size); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + const auto data_isize = data + data_size - isize_size; + return data_size < isize_size ? 0 : get_unaligned_le32(data_isize); +} + +static inline auto +assign(gzip_header &hdr, // cppcheck-suppress constParameterReference + const auto data) -> void { + std::memcpy(std::data(hdr.data), std::to_address(data), gzip_header_size); +} + [[nodiscard]] static inline constexpr auto get_gzip_body_size(const gzip_header &gh) -> std::uint32_t { - return (static_cast(gh.size) + 1) - gzip_header_size; + return (static_cast(gh.get_size()) + 1) - gzip_header_size; } +} // namespace + [[nodiscard]] auto bgzf_reader::get_decomp_task(char *out_itr) -> bgzf_block_t { if (std::distance(next_out, end_out) < max_bgzf_block_size) return bgzf_block_t{}; if (std::distance(next_in, end_in) < gzip_header_size && !read_data()) return bgzf_block_t{}; + gzip_header gh; assign(gh, next_in); assert(gh.check_magic()); // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) diff --git a/src/bgzf_reader.hpp b/src/bgzf_reader.hpp index 8f3e629..dc148a2 100644 --- a/src/bgzf_reader.hpp +++ b/src/bgzf_reader.hpp @@ -11,34 +11,6 @@ #include #include -static constexpr auto gzip_header_size = 18; - -struct gzip_header { - static constexpr auto magic1 = 0x1F; - static constexpr auto magic2 = 0x8B; - - std::uint8_t id1{}; // 0 - std::uint8_t id2{}; // 1 - std::uint8_t cm_eight{}; // 2 - std::uint8_t flg{}; // 3 - std::uint32_t mtime{}; // 7 [4] - std::uint8_t xfl{}; // 8 - std::uint8_t os{}; // 9 - std::uint16_t xlen{}; // 11 [2] - char b{}; // 12 - char c{}; // 13 - std::uint16_t two{}; // 14 [2] - std::uint16_t size{}; // 16 [2] - // 18 - - // ADS: total size is 20 bytes because of alignment and 32-bit values - - [[nodiscard]] auto - check_magic() const -> bool { - return id1 == magic1 && id2 == magic2; // ADS: check b and c also - } -}; - // reads data and provides serialized compressed chunks for deflation class bgzf_reader { private: @@ -46,7 +18,6 @@ class bgzf_reader { std::unique_ptr fp; std::uint64_t filesize{}; - gzip_header gh; std::unique_ptr inbuf; // NOLINT(cppcoreguidelines-avoid-c-arrays) std::unique_ptr outbuf; // NOLINT(cppcoreguidelines-avoid-c-arrays) char *next_in{};