7 Commits

3 changed files with 782 additions and 292 deletions

View File

@@ -1,11 +1,7 @@
#pragma once
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <vector>
namespace ss {
struct none {};
using string_range = std::pair<const char*, const char*>;
@@ -24,61 +20,4 @@ inline void assert_throw_on_error_not_defined() {
static_assert(!ThrowOnError, "cannot handle errors manually if "
"'throw_on_error' is enabled");
}
#if __unix__
inline ssize_t get_line(char** lineptr, size_t* n, FILE* stream) {
return getline(lineptr, n, stream);
}
#else
using ssize_t = int64_t;
inline ssize_t get_line(char** lineptr, size_t* n, FILE* stream) {
size_t pos;
int c;
if (lineptr == nullptr || stream == nullptr || n == nullptr) {
errno = EINVAL;
return -1;
}
c = getc(stream);
if (c == EOF) {
return -1;
}
if (*lineptr == nullptr) {
*lineptr = static_cast<char*>(malloc(128));
if (*lineptr == nullptr) {
return -1;
}
*n = 128;
}
pos = 0;
while (c != EOF) {
if (pos + 1 >= *n) {
size_t new_size = *n + (*n >> 2);
if (new_size < 128) {
new_size = 128;
}
char* new_ptr = static_cast<char*>(
realloc(static_cast<void*>(*lineptr), new_size));
if (new_ptr == nullptr) {
return -1;
}
*n = new_size;
*lineptr = new_ptr;
}
(*lineptr)[pos++] = c;
if (c == '\n') {
break;
}
c = getc(stream);
}
(*lineptr)[pos] = '\0';
return pos;
}
#endif
} /* ss */

File diff suppressed because it is too large Load Diff

View File

@@ -897,7 +897,7 @@ void test_multiline_restricted() {
out << "17,18,\"ju\\\n\\\n\\\n\\\\\n\nnk\"" << std::endl;
out << "19,20,just strings" << std::endl;
}
auto bad_lines = 15;
auto bad_lines = 19;
auto num_errors = 0;
ss::parser<ss::multiline_restricted<2>, ss::quote<'"'>, ss::escape<'\\'>,
@@ -1641,6 +1641,7 @@ void test_ignore_empty(const std::vector<X>& data) {
test_ignore_empty_impl<ss::throw_on_error>(data);
}
// TODO test with different initial buffer sizes
TEST_CASE("parser test various cases with empty lines") {
test_ignore_empty({{1, 2, "x"}, {3, 4, "y"}, {9, 10, "v"}, {11, 12, "w"}});
@@ -1670,13 +1671,53 @@ TEST_CASE("parser test various cases with empty lines") {
{9, 10, X::empty},
{11, 12, X::empty}});
test_ignore_empty(
{{1, 2, "x"}, {3, 4, X::empty}, {9, 10, X::empty}, {11, 12, X::empty}});
test_ignore_empty({{1, 2, X::empty},
{3, 4, X::empty},
{5, 6, X::empty},
{7, 8, X::empty},
{9, 10, X::empty},
{11, 12, X::empty},
{13, 14, X::empty},
{15, 16, X::empty},
{17, 18, X::empty}});
test_ignore_empty(
{{1, 2, X::empty}, {3, 4, X::empty}, {9, 10, X::empty}, {11, 12, "w"}});
test_ignore_empty({{1, 2, X::empty},
{3, 4, X::empty},
{5, 6, X::empty},
{7, 8, X::empty},
{9, 10, X::empty},
{11, 12, X::empty},
{13, 14, X::empty},
{15, 16, X::empty},
{17, 18, "x"}});
test_ignore_empty({{11, 12, X::empty}});
test_ignore_empty({{1, 2, "x"},
{3, 4, X::empty},
{9, 10, X::empty},
{11, 12, X::empty}});
test_ignore_empty({});
test_ignore_empty({{1, 2, "x"},
{3, 4, X::empty},
{3, 4, X::empty},
{5, 6, X::empty},
{7, 8, X::empty},
{9, 10, X::empty},
{11, 12, X::empty}});
test_ignore_empty({{1, 2, "x"},
{3, 4, X::empty},
{3, 4, X::empty},
{5, 6, X::empty},
{7, 8, X::empty},
{9, 10, X::empty},
{11, 12, "y"}});
test_ignore_empty({{1, 2, X::empty},
{3, 4, X::empty},
{9, 10, X::empty},
{11, 12, "w"}});
test_ignore_empty({{11, 12, X::empty}});
test_ignore_empty({});
}