#include using namespace Upp; #define CHECK_OVERFLOW(s, method, overflow) \ { \ DLOG(s << ' ' << #method); \ bool isoverflow = false; \ try { \ CParser p(s); \ DDUMP(p.method); \ } \ catch(CParser::Error e) { \ DLOG("Overflow: " << e); \ isoverflow = true; \ } \ ASSERT(isoverflow == overflow); \ } CONSOLE_APP_MAIN { StdLogSetup(LOG_FILE|LOG_COUT); { String s = "UTF8 ěščřžýá"; String txt = AsCString(s) + "\n" + AsCString(s); CParser p(txt); ASSERT(p.ReadString() == s + s); } try { CParser p("\"terminated string\""); ASSERT(p.ReadString() == "terminated string"); CParser p2("\"unterminated string\n"); p2.ReadString(); NEVER(); } catch(CParser::Error) { } { CParser p2("\"unterminated string\n"); ASSERT(p2.ReadString(false) == "unterminated string\n"); } CParser p("i if while 12345 alfa"); ASSERT(p.Id("i")); ASSERT(p.Id("if")); ASSERT(p.Id("while")); ASSERT(p.IsInt()); ASSERT(p.ReadInt() == 12345); ASSERT(p.IsId()); ASSERT(p.ReadId() == "alfa"); CHECK_OVERFLOW("2147483647", ReadInt(), false); CHECK_OVERFLOW("2147483648", ReadInt(), true); CHECK_OVERFLOW("-2147483648", ReadInt(), false); CHECK_OVERFLOW("-2147483649", ReadInt(), true); CHECK_OVERFLOW("ffffffff", ReadNumber(16), false); CHECK_OVERFLOW("100000000", ReadNumber(16), true); CHECK_OVERFLOW("9223372036854775807", ReadInt64(), false); CHECK_OVERFLOW("9223372036854775808", ReadInt64(), true); CHECK_OVERFLOW("-9223372036854775808", ReadInt64(), false); CHECK_OVERFLOW("-9223372036854775809", ReadInt64(), true); CHECK_OVERFLOW("ffffffffffffffff", ReadNumber64(16), false); CHECK_OVERFLOW("10000000000000000", ReadNumber64(16), true); DDUMP(1 * pow(10.0, 500)); CHECK_OVERFLOW("1e300", ReadDouble(), false); CHECK_OVERFLOW("1e500", ReadDouble(), true); CHECK_OVERFLOW("-1e300", ReadDouble(), false); CHECK_OVERFLOW("-1e500", ReadDouble(), true); CHECK_OVERFLOW(String('0', 500), ReadDouble(), true); { CParser p("+ /* \n */ a"); p.Char('+'); ASSERT(p.GetLine() == 2); ASSERT(p.GetColumn() == 6); ASSERT(p.ReadId() == "a"); } LOG("=========== OK"); }