mirror of
https://github.com/red0124/ssp.git
synced 2025-02-02 16:51:12 +01:00
add mismatched quote error, update error handling for splitter, add unit tests, update test_helpers buffer
This commit is contained in:
parent
d887dff82a
commit
6da0cb3544
@ -127,11 +127,6 @@ public:
|
|||||||
no_void_validator_tup_t<Ts...> convert(
|
no_void_validator_tup_t<Ts...> convert(
|
||||||
line_ptr_type line, const std::string& delim = default_delimiter) {
|
line_ptr_type line, const std::string& delim = default_delimiter) {
|
||||||
input_ = split(line, delim);
|
input_ = split(line, delim);
|
||||||
if (!splitter_.valid()) {
|
|
||||||
set_error_line_not_split();
|
|
||||||
no_void_validator_tup_t<Ts...> ret{};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return convert<Ts...>(input_);
|
return convert<Ts...>(input_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +186,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void set_error_mode(error_mode mode) {
|
void set_error_mode(error_mode mode) {
|
||||||
|
splitter_.set_error_mode(mode);
|
||||||
error_mode_ = mode;
|
error_mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,10 +230,10 @@ private:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_error_line_not_split() {
|
void set_error_unterminated_quote() {
|
||||||
if (error_mode_ == error_mode::error_string) {
|
if (error_mode_ == error_mode::error_string) {
|
||||||
string_error_.clear();
|
string_error_.clear();
|
||||||
string_error_.append("line not split correctly");
|
string_error_.append(splitter_.error_msg());
|
||||||
} else {
|
} else {
|
||||||
bool_error_ = true;
|
bool_error_ = true;
|
||||||
}
|
}
|
||||||
@ -283,11 +279,19 @@ private:
|
|||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
no_void_validator_tup_t<Ts...> convert_impl(const split_input& elems) {
|
no_void_validator_tup_t<Ts...> convert_impl(const split_input& elems) {
|
||||||
clear_error();
|
clear_error();
|
||||||
|
|
||||||
|
if (!splitter_.valid()) {
|
||||||
|
set_error_unterminated_quote();
|
||||||
|
no_void_validator_tup_t<Ts...> ret{};
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (sizeof...(Ts) != elems.size()) {
|
if (sizeof...(Ts) != elems.size()) {
|
||||||
set_error_number_of_colums(sizeof...(Ts), elems.size());
|
set_error_number_of_colums(sizeof...(Ts), elems.size());
|
||||||
no_void_validator_tup_t<Ts...> ret{};
|
no_void_validator_tup_t<Ts...> ret{};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return extract_tuple<Ts...>(elems);
|
return extract_tuple<Ts...>(elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
// TODO rule of 5-3-1
|
||||||
|
// TODO threads
|
||||||
namespace ss {
|
namespace ss {
|
||||||
|
|
||||||
template <typename... Matchers>
|
template <typename... Matchers>
|
||||||
|
@ -131,7 +131,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const split_input& resplit(line_ptr_type new_line, ssize_t new_size,
|
const split_input& resplit(
|
||||||
|
line_ptr_type new_line, ssize_t new_size,
|
||||||
const std::string& delimiter = default_delimiter) {
|
const std::string& delimiter = default_delimiter) {
|
||||||
line_ = new_line;
|
line_ = new_line;
|
||||||
|
|
||||||
@ -175,6 +176,16 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_error_mismatched_quote(size_t n) {
|
||||||
|
if (error_mode_ == error_mode::error_string) {
|
||||||
|
string_error_.clear();
|
||||||
|
string_error_.append("mismatched quote at position: " +
|
||||||
|
std::to_string(n));
|
||||||
|
} else {
|
||||||
|
bool_error_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void set_error_unterminated_quote() {
|
void set_error_unterminated_quote() {
|
||||||
unterminated_quote_ = true;
|
unterminated_quote_ = true;
|
||||||
if (error_mode_ == error_mode::error_string) {
|
if (error_mode_ == error_mode::error_string) {
|
||||||
@ -186,9 +197,11 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void set_error_invalid_resplit() {
|
void set_error_invalid_resplit() {
|
||||||
|
unterminated_quote_ = false;
|
||||||
if (error_mode_ == error_mode::error_string) {
|
if (error_mode_ == error_mode::error_string) {
|
||||||
string_error_.clear();
|
string_error_.clear();
|
||||||
string_error_.append("invalid_resplit");
|
string_error_.append("invalid resplit, new line must be longer"
|
||||||
|
"than the end of the last slice");
|
||||||
} else {
|
} else {
|
||||||
bool_error_ = true;
|
bool_error_ = true;
|
||||||
}
|
}
|
||||||
@ -388,9 +401,10 @@ private:
|
|||||||
// eg no trim: ...,"hello"\0 -> hello
|
// eg no trim: ...,"hello"\0 -> hello
|
||||||
output_.emplace_back(begin_, curr_);
|
output_.emplace_back(begin_, curr_);
|
||||||
} else {
|
} else {
|
||||||
// missmatched quote
|
// mismatched quote
|
||||||
// eg: ...,"hel"lo,... -> error
|
// eg: ...,"hel"lo,... -> error
|
||||||
// or not
|
set_error_mismatched_quote(end_ - line_);
|
||||||
|
output_.emplace_back(line_, begin_);
|
||||||
}
|
}
|
||||||
state_ = state::finished;
|
state_ = state::finished;
|
||||||
break;
|
break;
|
||||||
|
@ -115,6 +115,9 @@ TEST_CASE("testing invalid conversions") {
|
|||||||
c.convert<int>("");
|
c.convert<int>("");
|
||||||
REQUIRE(!c.valid());
|
REQUIRE(!c.valid());
|
||||||
|
|
||||||
|
c.convert<int>("10", "");
|
||||||
|
REQUIRE(!c.valid());
|
||||||
|
|
||||||
c.convert<int, void>("");
|
c.convert<int, void>("");
|
||||||
REQUIRE(!c.valid());
|
REQUIRE(!c.valid());
|
||||||
|
|
||||||
@ -438,3 +441,24 @@ TEST_CASE("testing converter with quotes spacing and escaping") {
|
|||||||
CHECK(tup == std::make_tuple("ju,st", "so,me", 12.34, "str\"ings"));
|
CHECK(tup == std::make_tuple("ju,st", "so,me", 12.34, "str\"ings"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("testing invalid split conversions") {
|
||||||
|
ss::converter<ss::escape<'\\'>, ss::trim<' '>, ss::quote<'"'>> c;
|
||||||
|
c.set_error_mode(ss::error_mode::error_string);
|
||||||
|
|
||||||
|
{
|
||||||
|
// mismatched quote
|
||||||
|
auto tup = c.convert<std::string, std::string, double, char>(
|
||||||
|
buff(R"( "just , some , "12.3","a" )"));
|
||||||
|
CHECK(!c.valid());
|
||||||
|
CHECK(!c.unterminated_quote());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// unterminated quote
|
||||||
|
auto tup = c.convert<std::string, std::string, double, std::string>(
|
||||||
|
buff(R"( ju\,st , "so,me" , 12.34 , "str""ings)"));
|
||||||
|
CHECK(!c.valid());
|
||||||
|
CHECK(c.unterminated_quote());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#ifdef CMAKE_GITHUB_CI
|
#ifdef CMAKE_GITHUB_CI
|
||||||
@ -8,19 +9,35 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
class buffer {
|
class buffer {
|
||||||
constexpr static auto buff_size = 1024;
|
char* data_{nullptr};
|
||||||
char data_[buff_size];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
char* operator()(const char* data) {
|
char* operator()(const char* data) {
|
||||||
memset(data_, '\0', buff_size);
|
if (data_) {
|
||||||
|
delete[] data_;
|
||||||
|
}
|
||||||
|
data_ = new char[strlen(data) + 1];
|
||||||
strcpy(data_, data);
|
strcpy(data_, data);
|
||||||
return data_;
|
return data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* append(const char* data) {
|
char* append(const char* data) {
|
||||||
strcat(data_, data);
|
if (data_) {
|
||||||
|
char* new_data_ = new char[strlen(data_) + strlen(data) + 1];
|
||||||
|
strcpy(new_data_, data_);
|
||||||
|
strcat(new_data_, data);
|
||||||
|
delete[] data_;
|
||||||
|
data_ = new_data_;
|
||||||
return data_;
|
return data_;
|
||||||
|
} else {
|
||||||
|
return operator()(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~buffer() {
|
||||||
|
if (data_) {
|
||||||
|
delete[] data_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -668,3 +668,28 @@ TEST_CASE("testing unterminated quote") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("testing invalid splits") {
|
||||||
|
ss::splitter<ss::quote<'"'>, ss::trim<' '>, ss::escape<'\\'>> s;
|
||||||
|
|
||||||
|
// empty delimiter
|
||||||
|
s.split(buff("some,random,strings"), "");
|
||||||
|
CHECK(!s.valid());
|
||||||
|
CHECK(!s.unterminated_quote());
|
||||||
|
|
||||||
|
// mismatched delimiter
|
||||||
|
s.split(buff(R"(some,"random,"strings")"));
|
||||||
|
CHECK(!s.valid());
|
||||||
|
CHECK(!s.unterminated_quote());
|
||||||
|
|
||||||
|
// unterminated quote
|
||||||
|
s.split(buff("some,random,\"strings"));
|
||||||
|
CHECK(!s.valid());
|
||||||
|
CHECK(s.unterminated_quote());
|
||||||
|
|
||||||
|
// invalid resplit
|
||||||
|
char new_line[] = "some";
|
||||||
|
auto a = s.resplit(new_line, strlen(new_line));
|
||||||
|
CHECK(!s.valid());
|
||||||
|
CHECK(!s.unterminated_quote());
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user