feat: toml multiline string test
This commit is contained in:
parent
abe004c3d5
commit
2f7fbd57ee
@ -108,6 +108,10 @@ bool BasicParser::hasNext() {
|
|||||||
return pos < source.length();
|
return pos < source.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t BasicParser::remain() const {
|
||||||
|
return source.length() - pos;
|
||||||
|
}
|
||||||
|
|
||||||
bool BasicParser::isNext(const std::string& substring) {
|
bool BasicParser::isNext(const std::string& substring) {
|
||||||
if (source.length() - pos < substring.length()) {
|
if (source.length() - pos < substring.length()) {
|
||||||
return false;
|
return false;
|
||||||
@ -357,36 +361,16 @@ std::string BasicParser::parseString(char quote, bool closeRequired) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'n':
|
case 'n': ss << '\n'; break;
|
||||||
ss << '\n';
|
case 'r': ss << '\r'; break;
|
||||||
break;
|
case 'b': ss << '\b'; break;
|
||||||
case 'r':
|
case 't': ss << '\t'; break;
|
||||||
ss << '\r';
|
case 'f': ss << '\f'; break;
|
||||||
break;
|
case '\'': ss << '\\'; break;
|
||||||
case 'b':
|
case '"': ss << '"'; break;
|
||||||
ss << '\b';
|
case '\\': ss << '\\'; break;
|
||||||
break;
|
case '/': ss << '/'; break;
|
||||||
case 't':
|
case '\n': pos++; continue;
|
||||||
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:
|
default:
|
||||||
throw error(
|
throw error(
|
||||||
"'\\" + std::string({c}) + "' is an illegal escape"
|
"'\\" + std::string({c}) + "' is an illegal escape"
|
||||||
|
|||||||
@ -109,6 +109,7 @@ public:
|
|||||||
std::string parseName();
|
std::string parseName();
|
||||||
std::string parseXmlName();
|
std::string parseXmlName();
|
||||||
bool hasNext();
|
bool hasNext();
|
||||||
|
size_t remain() const;
|
||||||
char peek();
|
char peek();
|
||||||
char peekInLine();
|
char peekInLine();
|
||||||
char peekNoJump();
|
char peekNoJump();
|
||||||
|
|||||||
@ -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() {
|
dv::value parseValue() {
|
||||||
char c = peek();
|
char c = peek();
|
||||||
if (is_digit(c)) {
|
if (is_digit(c)) {
|
||||||
@ -53,6 +98,12 @@ class TomlReader : BasicParser {
|
|||||||
throw error("unknown keyword " + util::quote(keyword));
|
throw error("unknown keyword " + util::quote(keyword));
|
||||||
} else if (c == '"' || c == '\'') {
|
} else if (c == '"' || c == '\'') {
|
||||||
pos++;
|
pos++;
|
||||||
|
if (remain() >= 2 &&
|
||||||
|
c == '"' &&
|
||||||
|
source[pos] == '"' &&
|
||||||
|
source[pos+1] == '"') {
|
||||||
|
return parseMultilineString();
|
||||||
|
}
|
||||||
return parseString(c);
|
return parseString(c);
|
||||||
} else if (c == '[') {
|
} else if (c == '[') {
|
||||||
// parse array
|
// parse array
|
||||||
@ -125,7 +176,7 @@ class TomlReader : BasicParser {
|
|||||||
dv::value& lvalue = parseLValue(map);
|
dv::value& lvalue = parseLValue(map);
|
||||||
expect('=');
|
expect('=');
|
||||||
lvalue = parseValue();
|
lvalue = parseValue();
|
||||||
expectNewLine();
|
skipWhitespace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -7,32 +7,6 @@
|
|||||||
#include "util/Buffer.hpp"
|
#include "util/Buffer.hpp"
|
||||||
#include "coders/commons.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) {
|
TEST(TOML, EncodeDecode) {
|
||||||
const std::string name = "TOML-encoder";
|
const std::string name = "TOML-encoder";
|
||||||
const int bytesSize = 20;
|
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) {
|
TEST(TOML, ExampleCode) {
|
||||||
try {
|
try {
|
||||||
|
std::cout << SRC_EXAMPLE << std::endl;
|
||||||
auto object = toml::parse("<string>", SRC_EXAMPLE);
|
auto object = toml::parse("<string>", SRC_EXAMPLE);
|
||||||
std::cout << object << std::endl;
|
std::cout << object << std::endl;
|
||||||
} catch (const parsing_error& err) {
|
} catch (const parsing_error& err) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user