Skip to content

Commit a242ddc

Browse files
committed
Fix off-by-one error when printing numbers in debug output
Based on the fix by @ginnyTheCat in #392.
1 parent 1a3bf15 commit a242ddc

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

include/osmium/io/detail/debug_output_format.hpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ namespace osmium {
106106

107107
}; // struct debug_output_options
108108

109+
// Space needed for printing numbers from 0 to num - 1
110+
int print_width(std::size_t num) noexcept {
111+
if (num <= 10) {
112+
return 1;
113+
}
114+
return static_cast<int>(std::log10(num - 1)) + 1;
115+
}
116+
109117
/**
110118
* Writes out one buffer with OSM data in Debug format.
111119
*/
@@ -392,7 +400,7 @@ namespace osmium {
392400
*m_out += " (open)\n";
393401
}
394402

395-
const int width = static_cast<int>(std::log10(way.nodes().size())) + 1;
403+
const int width = print_width(way.nodes().size());
396404
int n = 0;
397405
for (const auto& node_ref : way.nodes()) {
398406
write_diff();
@@ -427,7 +435,7 @@ namespace osmium {
427435
output_int(relation.members().size());
428436
*m_out += '\n';
429437

430-
const int width = static_cast<int>(std::log10(relation.members().size())) + 1;
438+
const int width = print_width(relation.members().size());
431439
int n = 0;
432440
for (const auto& member : relation.members()) {
433441
write_diff();
@@ -485,7 +493,7 @@ namespace osmium {
485493
output_int(changeset.num_comments());
486494
*m_out += '\n';
487495

488-
const int width = static_cast<int>(std::log10(changeset.num_comments())) + 1;
496+
const int width = print_width(changeset.num_comments());
489497
int n = 0;
490498
for (const auto& comment : changeset.discussion()) {
491499
write_counter(width, n++);

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ add_unit_test(io test_nocompression)
180180
add_unit_test(io test_output_utils)
181181
add_unit_test(io test_file_seek)
182182
add_unit_test(io test_string_table)
183+
add_unit_test(io test_print_width ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES})
183184

184185
add_unit_test(io test_bzip2 ENABLE_IF ${BZIP2_FOUND} LIBS ${BZIP2_LIBRARIES})
185186
add_unit_test(io test_gzip ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES})

test/t/io/test_print_width.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "catch.hpp"
2+
3+
#include <osmium/io/detail/debug_output_format.hpp>
4+
5+
TEST_CASE("Calculate width of a number") {
6+
REQUIRE(osmium::io::detail::print_width(0) == 1);
7+
REQUIRE(osmium::io::detail::print_width(1) == 1);
8+
REQUIRE(osmium::io::detail::print_width(2) == 1);
9+
REQUIRE(osmium::io::detail::print_width(9) == 1);
10+
REQUIRE(osmium::io::detail::print_width(10) == 1); // 0 .. 9
11+
REQUIRE(osmium::io::detail::print_width(11) == 2);
12+
REQUIRE(osmium::io::detail::print_width(42) == 2);
13+
REQUIRE(osmium::io::detail::print_width(99) == 2);
14+
REQUIRE(osmium::io::detail::print_width(100) == 2); // 0 .. 99
15+
REQUIRE(osmium::io::detail::print_width(101) == 3);
16+
REQUIRE(osmium::io::detail::print_width(999) == 3);
17+
REQUIRE(osmium::io::detail::print_width(1000) == 3); // 0 .. 100
18+
REQUIRE(osmium::io::detail::print_width(1001) == 4);
19+
}

0 commit comments

Comments
 (0)