From 67b3097895cae64237be11ab3336570088014f8c Mon Sep 17 00:00:00 2001 From: Tomoki Imai Date: Sat, 14 Jun 2014 17:28:09 +0900 Subject: [PATCH 1/3] Fix line_pos_iterator's column counting bug,get_current_line bug. Add regresssion test for it. --- .../home/support/iterators/line_pos_iterator.hpp | 39 +++++++++++++------ test/support/regression_line_pos_iterator.cpp | 45 ++++++++++++++++++++++ 2 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 test/support/regression_line_pos_iterator.cpp diff --git a/include/boost/spirit/home/support/iterators/line_pos_iterator.hpp b/include/boost/spirit/home/support/iterators/line_pos_iterator.hpp index 0b2aec8ce9..10a1c5b768 100644 --- a/include/boost/spirit/home/support/iterators/line_pos_iterator.hpp +++ b/include/boost/spirit/home/support/iterators/line_pos_iterator.hpp @@ -1,6 +1,7 @@ /*============================================================================== Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2010 Bryce Lelbach + Copyright (c) 2014 Tomoki Imai Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -125,18 +126,35 @@ namespace boost { namespace spirit template inline Iterator get_line_start(Iterator lower_bound, Iterator current) { + // cover LF,CR+LF,CR,LF+RF. + // but if *current == '\r' or *current == '\n', + // result will be something worng. Iterator latest = lower_bound; - + bool prev_was_newline = false; for (Iterator i = lower_bound; i != current; ++i) { - switch (*i) { - case '\r': - case '\n': - latest = i; - } + if (prev_was_newline) { + latest = i; + } + prev_was_newline = (*i == '\r') || (*i == '\n'); + } + if (prev_was_newline) { + latest = current; } - return latest; } + + template + inline Iterator get_line_end(Iterator current, Iterator upper_bound) + { + // if current is at '\r' or '\n',may return something unexpected. + for (Iterator i = current; i != upper_bound; ++i) { + if ((*i == '\n') || (*i == '\r')) { + return i; + } + } + return upper_bound; + } + template inline iterator_range @@ -144,12 +162,9 @@ namespace boost { namespace spirit Iterator current, Iterator upper_bound) { + // if *current is '\r' or '\n', result will something unexpected. Iterator first = get_line_start(lower_bound, current); - Iterator last = get_line_start(current, upper_bound); - - if (last == current) - last = upper_bound; - + Iterator last = get_line_end(current, upper_bound); return iterator_range(first, last); } diff --git a/test/support/regression_line_pos_iterator.cpp b/test/support/regression_line_pos_iterator.cpp new file mode 100644 index 0000000000..e5355a623b --- /dev/null +++ b/test/support/regression_line_pos_iterator.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2014 Tomoki Imai +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +int main() +{ + typedef boost::spirit::line_pos_iterator + pos_iterator_t; + typedef boost::iterator_range + iterator_range; + { + std::string test = "012\n345\n678"; + pos_iterator_t begin(test.begin()), + end(test.end()); + + for (pos_iterator_t iter = begin; iter != end; ++iter) { + // ignore newline because newline's line or column is ambiguous. + if (*iter == '\n') continue; + int n = *iter - '0'; + int line = n / 3 + 1; + int column = n % 3 + 1; + + BOOST_TEST(line == get_line(iter) && + column == get_column(begin,iter)); + + iterator_range range = get_current_line(begin,iter,end); + std::string current_line(range.begin(),range.end()); + if (line == 1) { + BOOST_TEST(current_line == "012"); + } else if(line == 2) { + BOOST_TEST(current_line == "345"); + } else { + BOOST_TEST(current_line == "678"); + } + } + } + return 0; +} From e203a7c95d61d803d588066c35c2bc1f7e57370a Mon Sep 17 00:00:00 2001 From: Tomoki Imai Date: Sat, 14 Jun 2014 18:55:44 +0900 Subject: [PATCH 2/3] add line to run support/regression_line_pos_iterator.cpp --- test/Jamfile | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Jamfile b/test/Jamfile index 6da470c2b0..bdc0233831 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -312,6 +312,7 @@ path-constant LEX_DIR : $(BOOST_ROOT)/libs/spirit/test/lex ; [ compile support/regression_multi_pass_position_iterator.cpp : : support_regression_multi_pass_position_iterator ] [ compile support/regression_multi_pass_functor.cpp : : support_regression_multi_pass_functor ] [ compile support/regression_multi_pass_parse.cpp : : support_regression_multi_pass_parse ] + [ run support/regression_line_pos_iterator.cpp : : : : regression_line_pos_iterator ] [ run support/regression_multi_pass_error_handler.cpp : : : : regression_multi_pass_error_handler ] ; From f84d869ec891be4d40eb724452ad8c1129ca3358 Mon Sep 17 00:00:00 2001 From: Tomoki Imai Date: Mon, 16 Jun 2014 13:44:16 +0900 Subject: [PATCH 3/3] Change from BOOST_TEST to BOOST_TEST_EQ for better information. --- test/support/regression_line_pos_iterator.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/support/regression_line_pos_iterator.cpp b/test/support/regression_line_pos_iterator.cpp index e5355a623b..1ff4db8dce 100644 --- a/test/support/regression_line_pos_iterator.cpp +++ b/test/support/regression_line_pos_iterator.cpp @@ -27,17 +27,17 @@ int main() int line = n / 3 + 1; int column = n % 3 + 1; - BOOST_TEST(line == get_line(iter) && - column == get_column(begin,iter)); + BOOST_TEST_EQ(line,get_line(iter)); + BOOST_TEST_EQ(column,get_column(begin,iter)); iterator_range range = get_current_line(begin,iter,end); std::string current_line(range.begin(),range.end()); if (line == 1) { - BOOST_TEST(current_line == "012"); + BOOST_TEST_EQ(current_line,"012"); } else if(line == 2) { - BOOST_TEST(current_line == "345"); + BOOST_TEST_EQ(current_line,"345"); } else { - BOOST_TEST(current_line == "678"); + BOOST_TEST_EQ(current_line,"678"); } } }