feat: toml multiline string test

This commit is contained in:
MihailRis 2024-10-12 23:07:10 +03:00
parent abe004c3d5
commit 2f7fbd57ee
4 changed files with 94 additions and 57 deletions

View File

@ -108,6 +108,10 @@ bool BasicParser::hasNext() {
return pos < source.length();
}
size_t BasicParser::remain() const {
return source.length() - pos;
}
bool BasicParser::isNext(const std::string& substring) {
if (source.length() - pos < substring.length()) {
return false;
@ -357,36 +361,16 @@ std::string BasicParser::parseString(char quote, bool closeRequired) {
continue;
}
switch (c) {
case 'n':
ss << '\n';
break;
case 'r':
ss << '\r';
break;
case 'b':
ss << '\b';
break;
case 't':
ss << '\t';
break;
case 'f':
ss << '\f';
break;
case '\'':
ss << '\\';
break;
case '"':
ss << '"';
break;
case '\\':
ss << '\\';
break;
case '/':
ss << '/';
break;
case '\n':
pos++;
continue;
case 'n': ss << '\n'; break;
case 'r': ss << '\r'; break;
case 'b': ss << '\b'; break;
case 't': ss << '\t'; break;
case 'f': ss << '\f'; break;
case '\'': ss << '\\'; break;
case '"': ss << '"'; break;
case '\\': ss << '\\'; break;
case '/': ss << '/'; break;
case '\n': pos++; continue;
default:
throw error(
"'\\" + std::string({c}) + "' is an illegal escape"

View File

@ -109,6 +109,7 @@ public:
std::string parseName();
std::string parseXmlName();
bool hasNext();
size_t remain() const;
char peek();
char peekInLine();
char peekNoJump();

View File

@ -26,6 +26,51 @@ class TomlReader : BasicParser {
}
}
std::string parseMultilineString() {
pos += 2;
char next = peek();
std::stringstream ss;
while (hasNext()) {
char c = source[pos];
if (c == '"' && remain() >= 2 &&
source[pos+1] == '"' &&
source[pos+2] == '"') {
pos += 3;
return ss.str();
}
if (c == '\\') {
pos++;
c = nextChar();
if (c >= '0' && c <= '7') {
pos--;
ss << (char)parseSimpleInt(8);
continue;
}
switch (c) {
case 'n': ss << '\n'; break;
case 'r': ss << '\r'; break;
case 'b': ss << '\b'; break;
case 't': ss << '\t'; break;
case 'f': ss << '\f'; break;
case '\'': ss << '\\'; break;
case '"': ss << '"'; break;
case '\\': ss << '\\'; break;
case '/': ss << '/'; break;
case '\n': pos++; continue;
default:
throw error(
"'\\" + std::string({c}) + "' is an illegal escape"
);
}
continue;
}
ss << c;
pos++;
}
throw error("unexpected end");
}
dv::value parseValue() {
char c = peek();
if (is_digit(c)) {
@ -53,6 +98,12 @@ class TomlReader : BasicParser {
throw error("unknown keyword " + util::quote(keyword));
} else if (c == '"' || c == '\'') {
pos++;
if (remain() >= 2 &&
c == '"' &&
source[pos] == '"' &&
source[pos+1] == '"') {
return parseMultilineString();
}
return parseString(c);
} else if (c == '[') {
// parse array
@ -125,7 +176,7 @@ class TomlReader : BasicParser {
dv::value& lvalue = parseLValue(map);
expect('=');
lvalue = parseValue();
expectNewLine();
skipWhitespace();
}
}
public:

View File

@ -7,32 +7,6 @@
#include "util/Buffer.hpp"
#include "coders/commons.hpp"
// Example from toml.io
inline std::string SRC_EXAMPLE =
"# This is a TOML document\n"
"\n"
"title = \"TOML Example\"\n"
"\n"
"[owner]\n"
"name = \"Tom Preston-Werner\"\n"
// "dob = 1979-05-27T07:32:00-08:00\n"
"\n"
"[database]\n"
"enabled = true\n"
"ports = [ 8000, 8001, 8002 ]\n"
"data = [ [\"delta\", \"phi\"], [3.14] ]\n"
"temp_targets = { cpu = 79.5, case = 72.0 }\n"
"\n"
"[servers]\n"
"\n"
"[servers.alpha]\n"
"ip = \"10.0.0.1\"\n"
"role = \"frontend\"\n"
"\n"
"[servers.beta]\n"
"ip = \"10.0.0.2\"\n"
"role = \"backend\"";
TEST(TOML, EncodeDecode) {
const std::string name = "TOML-encoder";
const int bytesSize = 20;
@ -75,8 +49,35 @@ TEST(TOML, EncodeDecode) {
}
}
// Modified example from toml.io
inline std::string SRC_EXAMPLE =
"# This is a TOML document\n"
"\n"
"title = \"TOML Example\"\n"
"\n"
"[owner]\n"
"name = \"Tom Preston-Werner\"\n"
// "dob = 1979-05-27T07:32:00-08:00\n"
"\n"
"[database]\n"
"enabled = true\n"
"ports = [ 8000, 8001, 8002 ]\n"
"data = [ [\"delta\", \"phi\"], [3.14] ]\n"
"temp_targets = { cpu = 79.5, case = 72.0 }\n"
"\n"
"[servers]\n"
"\n"
"[servers.alpha]\n"
"ip = \"10.0.0.1\"\n"
"role = \"frontend\"\n"
"\n"
"[servers.beta]\n"
"ip = \"10.0.0.2\"\n"
"role = \"\"\"backend\"\"\"";
TEST(TOML, ExampleCode) {
try {
std::cout << SRC_EXAMPLE << std::endl;
auto object = toml::parse("<string>", SRC_EXAMPLE);
std::cout << object << std::endl;
} catch (const parsing_error& err) {