diff --git a/include/ss/common.hpp b/include/ss/common.hpp index 095561c..0a4f934 100644 --- a/include/ss/common.hpp +++ b/include/ss/common.hpp @@ -12,7 +12,7 @@ using string_range = std::pair; using split_data = std::vector; constexpr inline auto default_delimiter = ","; -constexpr static auto get_line_initial_buffer_size = 128; +constexpr inline auto get_line_initial_buffer_size = 128; template inline void assert_string_error_defined() { @@ -31,7 +31,7 @@ inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) { return getline(lineptr, n, stream); } #else -// TODO set ERRNO ? + using ssize_t = int64_t; inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) { size_t pos; diff --git a/include/ss/parser.hpp b/include/ss/parser.hpp index b715e75..e11969e 100644 --- a/include/ss/parser.hpp +++ b/include/ss/parser.hpp @@ -5,6 +5,7 @@ #include "exception.hpp" #include "extract.hpp" #include "restrictions.hpp" +#include #include #include #include @@ -742,7 +743,6 @@ private: reader(const reader& other) = delete; reader& operator=(const reader& other) = delete; - // TODO set error numbers on error ssize_t get_line_buffer(char** lineptr, size_t* n, const char* const buffer, size_t csv_data_size, size_t& curr_char) { @@ -812,6 +812,9 @@ private: } if (ssize == -1) { + if (errno == ENOMEM) { + throw std::bad_alloc{}; + } return false; } diff --git a/ssp.hpp b/ssp.hpp index 9b555ec..72e4c2f 100644 --- a/ssp.hpp +++ b/ssp.hpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -625,7 +626,7 @@ using string_range = std::pair; using split_data = std::vector; constexpr inline auto default_delimiter = ","; -constexpr static auto get_line_initial_buffer_size = 128; +constexpr inline auto get_line_initial_buffer_size = 128; template inline void assert_string_error_defined() { @@ -644,6 +645,7 @@ inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) { return getline(lineptr, n, stream); } #else + using ssize_t = int64_t; inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) { size_t pos; @@ -2495,20 +2497,22 @@ public: template void try_convert_and_invoke(std::optional& value, Fun&& fun) { - if (!parser_.valid()) { - auto tuple_output = try_same(); - if (!parser_.valid()) { - return; - } - - if constexpr (!std::is_same_v) { - value = to_object(std::move(tuple_output)); - } else { - value = std::move(tuple_output); - } - - parser_.try_invoke(*value, std::forward(fun)); + if (parser_.valid()) { + return; } + + auto tuple_output = try_same(); + if (!parser_.valid()) { + return; + } + + if constexpr (!std::is_same_v) { + value = to_object(std::move(tuple_output)); + } else { + value = std::move(tuple_output); + } + + parser_.try_invoke(*value, std::forward(fun)); } template @@ -2936,6 +2940,9 @@ private: } if (ssize == -1) { + if (errno == ENOMEM) { + throw std::bad_alloc{}; + } return false; } @@ -3067,7 +3074,7 @@ private: buffer_size = first_size + second_size + 3; auto new_first = static_cast( realloc(static_cast(first), buffer_size)); - if (!first) { + if (!new_first) { throw std::bad_alloc{}; } diff --git a/test/test_parser2.hpp b/test/test_parser2.hpp index 1db140d..9d29f2a 100644 --- a/test/test_parser2.hpp +++ b/test/test_parser2.hpp @@ -258,20 +258,22 @@ std::vector generate_csv_data(const std::vector& data, [[maybe_unused]] void write_to_file(const std::vector& data, const std::string& delim, - const std::string& file_name) { + const std::string& file_name, + bool add_new_line = true) { std::ofstream out{file_name, std::ios_base::app}; std::string line; - // TODO remove new line at eof randomly for (size_t i = 0; i < data.size(); ++i) { line += data[i]; if (i != data.size() - 1) { line += delim; } - } - out << line << std::endl; + out << line; + if (add_new_line) { + out << std::endl; + } } #define CHECK_EQ_CRLF(V1, V2) \ @@ -333,7 +335,11 @@ void test_data_combinations(const std::vector& input_data, if (include_header) { auto header_data = generate_csv_data(field_header, delim); - write_to_file(header_data, delim, f.name); + if (input_data.size() == 0 && rand() % 10 == 0) { + write_to_file(header_data, delim, f.name, false); + } else { + write_to_file(header_data, delim, f.name); + } } std::vector layout; @@ -358,15 +364,12 @@ void test_data_combinations(const std::vector& input_data, expected_data.push_back(raw_data); auto data = generate_csv_data(raw_data, delim); - write_to_file(data, delim, f.name); - /* - std::cout << "[."; - for (const auto& el : data) { - std::cout << el << '.'; + if (i + 1 == n && rand() % 10 == 0) { + write_to_file(data, delim, f.name, false); + } else { + write_to_file(data, delim, f.name); } - std::cout << "]" << std::endl; - */ } auto layout_combinations = include_header && !setup::ignore_header @@ -430,7 +433,6 @@ void test_data_combinations(const std::vector& input_data, auto s0 = p.template get_next(); if (i < n) { check_error(); - // std::cout << s0 << std::endl; CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value); } else { CHECK(p.eof()); @@ -443,7 +445,6 @@ void test_data_combinations(const std::vector& input_data, p.template get_next(); if (i < n) { check_error(); - // std::cout << s0 << ' ' << s1 << std::endl; CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value); CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value); } else { @@ -458,8 +459,6 @@ void test_data_combinations(const std::vector& input_data, std::string>(); if (i < n) { check_error(); - // std::cout << s0 << ' ' << s1 << ' ' << s2 << - // std::endl; CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value); CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value); CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value); @@ -475,10 +474,6 @@ void test_data_combinations(const std::vector& input_data, std::string, std::string>(); if (i < n) { check_error(); - /* - std::cout << s0 << ' ' << s1 << ' ' << s2 << ' ' << s3 - << std::endl; - */ CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value); CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value); CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value); @@ -496,9 +491,6 @@ void test_data_combinations(const std::vector& input_data, std::string>(); if (i < n) { check_error(); - // std::cout << s0 << ' ' << s1 << ' ' << s2 << ' ' << - // s3 - // << ' ' << s4 << std::endl; CHECK_EQ_CRLF(s0, expected_data[i][layout[0]].value); CHECK_EQ_CRLF(s1, expected_data[i][layout[1]].value); CHECK_EQ_CRLF(s2, expected_data[i][layout[2]].value);