diff --git a/example/csv/main.cpp b/example/csv/main.cpp index d061fd6e..6ce81b1d 100644 --- a/example/csv/main.cpp +++ b/example/csv/main.cpp @@ -6,6 +6,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ +#include #include #include #include @@ -48,6 +49,7 @@ parse_csv(String const& src, csv_parser_settings se sprout::array_sub_t, L> result = {}; result.window(0, 1); result.back().window(0, 0); + bool same_escape = settings.quote() == settings.escape(); auto delimiters = sprout::make_string(settings.delimiter(), value_type('\r'), value_type('\n')); auto first = sprout::begin(src), last = sprout::end(src); while (first != last) { @@ -57,18 +59,26 @@ parse_csv(String const& src, csv_parser_settings se auto end_quote = sprout::find(first, last, settings.quote()); while (true) { if (end_quote == last) { - throw 0; + throw std::runtime_error("end quote not found"); } auto next = sprout::next(end_quote); + if (!same_escape && first != end_quote) { + auto prev = sprout::prev(end_quote); + if (*prev == settings.escape()) { + // escaped quote + end_quote = sprout::find(next, last, settings.quote()); + continue; + } + } if (next != last) { - if (*next == settings.escape()) { + if (*next == settings.quote()) { // escaped quote ++next; end_quote = sprout::find(next, last, settings.quote()); continue; } if (!sprout::any_of_equal(delimiters.begin(), delimiters.end(), *next)) { - throw 0; + throw std::runtime_error("invalid quote"); } if (*next == value_type('\r') && sprout::next(next) != last && *sprout::next(next) == value_type('\n')) { ++next; @@ -109,17 +119,18 @@ parse_csv(String const& src, csv_parser_settings se int main() { using namespace sprout::udl; + constexpr auto settings = csv_parser_settings(',', '\"', '\\'); constexpr auto src = R"( (no quoted),a,b,c (quoted),"d","e","f" -(escaped),"""g""","""h""","""i""" +(escaped),"""g""","\"h\"","""i""" (comma),"j,k","l,m","n,o" (new line),"p q","r s","t u" )"_sv; - constexpr auto result = parse_csv<16, 16>(src); + constexpr auto result = parse_csv<16, 16>(src, settings); for (auto const& field : result) { for (auto const& elem : field) { std::cout