sequence parsing and parseArguments fixes
This commit is contained in:
parent
dca7f59dbc
commit
a88b1e4ce0
@ -39,7 +39,7 @@ template <typename InputIterator>
|
|||||||
class JsonParser {
|
class JsonParser {
|
||||||
public:
|
public:
|
||||||
JsonParser(JsonStream& stream)
|
JsonParser(JsonStream& stream)
|
||||||
: m_line(0), m_column(0), m_stream(stream) {}
|
: m_line(0), m_column(0), m_stream(stream), m_error(nullptr) {}
|
||||||
virtual ~JsonParser() {}
|
virtual ~JsonParser() {}
|
||||||
|
|
||||||
// Does not throw. On error, returned iterator will not be equal to end, and
|
// Does not throw. On error, returned iterator will not be equal to end, and
|
||||||
@ -65,10 +65,7 @@ public:
|
|||||||
|
|
||||||
// Human readable parsing error, does not include line or column info.
|
// Human readable parsing error, does not include line or column info.
|
||||||
char const* error() const {
|
char const* error() const {
|
||||||
if (m_error.empty())
|
return m_error;
|
||||||
return nullptr;
|
|
||||||
else
|
|
||||||
return m_error.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t line() const {
|
size_t line() const {
|
||||||
@ -216,31 +213,42 @@ private:
|
|||||||
break;
|
break;
|
||||||
else {
|
else {
|
||||||
auto begin = m_current;
|
auto begin = m_current;
|
||||||
|
auto b_char = m_char;
|
||||||
if (m_char >= '0' && m_char <= '9') {
|
if (m_char >= '0' && m_char <= '9') {
|
||||||
number();
|
try {
|
||||||
if (m_error.empty()) {
|
number(true);
|
||||||
|
}
|
||||||
|
catch (ParsingException const&) {
|
||||||
|
m_current = begin;
|
||||||
|
m_char = b_char;
|
||||||
|
}
|
||||||
|
if (m_error == nullptr) {
|
||||||
next();
|
next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_error.clear();
|
m_error = nullptr;
|
||||||
m_current = begin;
|
|
||||||
if (m_char == 't' || m_char == 'f' || m_char == 'n') {
|
if (m_char == 't' || m_char == 'f' || m_char == 'n') {
|
||||||
word();
|
try {
|
||||||
if (m_error.empty()) {
|
word(true);
|
||||||
|
}
|
||||||
|
catch (ParsingException const&) {
|
||||||
|
m_current = begin;
|
||||||
|
m_char = b_char;
|
||||||
|
}
|
||||||
|
if (m_error == nullptr) {
|
||||||
next();
|
next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_error.clear();
|
m_error = nullptr;
|
||||||
m_current = begin;
|
|
||||||
// well, shit. do a simple string parse until we hit whitespace
|
// well, shit. do a simple string parse until we hit whitespace
|
||||||
// no fancy things like \n, do a proper string if you want that
|
// no fancy things like \n, do a proper string if you want that
|
||||||
CharArray str;
|
CharArray str;
|
||||||
do {
|
do {
|
||||||
str += m_char;
|
str += m_char;
|
||||||
next();
|
next();
|
||||||
} while (m_char && !isSpace(m_char));
|
} while (m_char != 0 && !isSpace(m_char));
|
||||||
m_stream.putString(str.c_str(), str.length());
|
m_stream.putString(str.c_str(), str.length());
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
@ -253,7 +261,7 @@ private:
|
|||||||
m_stream.putString(s.c_str(), s.length());
|
m_stream.putString(s.c_str(), s.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
void number() {
|
void number(bool seq = false) {
|
||||||
std::basic_string<char32_t> buffer;
|
std::basic_string<char32_t> buffer;
|
||||||
bool isDouble = false;
|
bool isDouble = false;
|
||||||
|
|
||||||
@ -297,30 +305,35 @@ private:
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seq && m_char != 0 && !isSpace(m_char))
|
||||||
|
error("unexpected character after number");
|
||||||
|
|
||||||
if (isDouble) {
|
if (isDouble) {
|
||||||
try {
|
try {
|
||||||
m_stream.putDouble(buffer.c_str(), buffer.length());
|
m_stream.putDouble(buffer.c_str(), buffer.length());
|
||||||
} catch (std::exception const& e) {
|
} catch (std::exception const& e) {
|
||||||
error(std::string("Bad double: ") + e.what());
|
error("bad double");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
m_stream.putInteger(buffer.c_str(), buffer.length());
|
m_stream.putInteger(buffer.c_str(), buffer.length());
|
||||||
} catch (std::exception const& e) {
|
} catch (std::exception const& e) {
|
||||||
error(std::string("Bad integer: ") + e.what());
|
error("bad integer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// true, false, or null
|
// true, false, or null
|
||||||
void word() {
|
void word(bool seq = false) {
|
||||||
switch (m_char) {
|
switch (m_char) {
|
||||||
case 't':
|
case 't':
|
||||||
next();
|
next();
|
||||||
check('r');
|
check('r');
|
||||||
check('u');
|
check('u');
|
||||||
check('e');
|
check('e');
|
||||||
|
if (seq && m_char != 0 && !isSpace(m_char))
|
||||||
|
error("unexpected character after word");
|
||||||
m_stream.putBoolean(true);
|
m_stream.putBoolean(true);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
@ -329,6 +342,8 @@ private:
|
|||||||
check('l');
|
check('l');
|
||||||
check('s');
|
check('s');
|
||||||
check('e');
|
check('e');
|
||||||
|
if (seq && m_char != 0 && !isSpace(m_char))
|
||||||
|
error("unexpected character after word");
|
||||||
m_stream.putBoolean(false);
|
m_stream.putBoolean(false);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
@ -336,6 +351,8 @@ private:
|
|||||||
check('u');
|
check('u');
|
||||||
check('l');
|
check('l');
|
||||||
check('l');
|
check('l');
|
||||||
|
if (seq && m_char != 0 && !isSpace(m_char))
|
||||||
|
error("unexpected character after word");
|
||||||
m_stream.putNull();
|
m_stream.putNull();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -502,34 +519,32 @@ private:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The only allowed characters following / in whitespace are / and *
|
// The only allowed characters following / in whitespace are / and *
|
||||||
error("/ character in whitespace is not follwed by '/' or '*', invalid comment");
|
error("/ character in whitespace is not followed by '/' or '*', invalid comment");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (isSpace(m_char)) {
|
} else if (isSpace(m_char)) {
|
||||||
buffer += m_char;
|
buffer += m_char;
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
if (buffer.size() != 0)
|
break;
|
||||||
m_stream.putWhitespace(buffer.c_str(), buffer.length());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buffer.size() != 0)
|
if (buffer.size() != 0)
|
||||||
m_stream.putWhitespace(buffer.c_str(), buffer.length());
|
m_stream.putWhitespace(buffer.c_str(), buffer.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
void error(std::string msg) {
|
void error(const char* msg) {
|
||||||
m_error = std::move(msg);
|
m_error = msg;
|
||||||
throw ParsingException();
|
throw ParsingException();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSpace(char32_t c) {
|
bool isSpace(char32_t c) {
|
||||||
// Only whitespace allowed by JSON
|
// Only whitespace allowed by JSON
|
||||||
return c == 0x20 || // space
|
return c == 0x20 || // space
|
||||||
c == 0x09 || // horizontal tab
|
c == 0x09 || // horizontal tab
|
||||||
c == 0x0a || // newline
|
c == 0x0a || // newline
|
||||||
c == 0x0d || // carriage return
|
c == 0x0d || // carriage return
|
||||||
c == 0xfeff; // BOM or ZWNBSP
|
c == 0xfeff; // BOM or ZWNBSP
|
||||||
}
|
}
|
||||||
|
|
||||||
char32_t m_char;
|
char32_t m_char;
|
||||||
@ -537,7 +552,7 @@ private:
|
|||||||
InputIterator m_end;
|
InputIterator m_end;
|
||||||
size_t m_line;
|
size_t m_line;
|
||||||
size_t m_column;
|
size_t m_column;
|
||||||
std::string m_error;
|
const char* m_error;
|
||||||
JsonStream& m_stream;
|
JsonStream& m_stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ LuaCallbacks LuaBindings::makeChatCallbacks(MainInterface* mainInterface, Univer
|
|||||||
});
|
});
|
||||||
|
|
||||||
// just for SE compat - this shoulda been a utility callback :moyai:
|
// just for SE compat - this shoulda been a utility callback :moyai:
|
||||||
callbacks.registerCallback("parseArguments", [](String const& args) {
|
callbacks.registerCallback("parseArguments", [](String const& args) -> LuaVariadic<Json> {
|
||||||
return Json::parseSequence(args);
|
return Json::parseSequence(args).toArray();
|
||||||
});
|
});
|
||||||
|
|
||||||
callbacks.registerCallback("command", [mainInterface](String const& command) -> StringList {
|
callbacks.registerCallback("command", [mainInterface](String const& command) -> StringList {
|
||||||
|
Loading…
Reference in New Issue
Block a user