#7160 Internal error: Unhandled char constant '\1'. Correct MathLib::toLongNumber. Create new utility function MathLib::characterLiteralToLongNumber
This commit is contained in:
parent
5f68f3ddf6
commit
714579401f
116
lib/mathlib.cpp
116
lib/mathlib.cpp
|
@ -313,6 +313,76 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MathLib::bigint MathLib::characterLiteralToLongNumber(const std::string& str)
|
||||||
|
{
|
||||||
|
if (str.size()==1)
|
||||||
|
return str[0] & 0xff;
|
||||||
|
if (str[0] != '\\')
|
||||||
|
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
|
||||||
|
|
||||||
|
if (str[1]=='x') {
|
||||||
|
return toLongNumber("0x" + str.substr(2));
|
||||||
|
}
|
||||||
|
char c;
|
||||||
|
switch (str.size()-1) {
|
||||||
|
case 1:
|
||||||
|
switch (str[1]) {
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
return str[1]-'0';
|
||||||
|
case 'a':
|
||||||
|
c = '\a';
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
c = '\b';
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
c = '\f';
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
c = '\n';
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
c = '\r';
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
c = '\t';
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
c = '\v';
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
case '\?':
|
||||||
|
case '\'':
|
||||||
|
case '\"':
|
||||||
|
c = str[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return c & 0xff;
|
||||||
|
case 2:
|
||||||
|
if (isOctalDigit(str[1]) && isOctalDigit(str[2]))
|
||||||
|
return toLongNumber("0" + str.substr(1));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (isOctalDigit(str[1]) && isOctalDigit(str[2]) && isOctalDigit(str[3]))
|
||||||
|
return toLongNumber("0" + str.substr(1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
||||||
{
|
{
|
||||||
// hexadecimal numbers:
|
// hexadecimal numbers:
|
||||||
|
@ -364,51 +434,7 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str[0] == '\'' && str.size() >= 3U && str[str.size()-1U] == '\'') {
|
if (str[0] == '\'' && str.size() >= 3U && str[str.size()-1U] == '\'') {
|
||||||
char c;
|
return characterLiteralToLongNumber(str.substr(1,str.size()-2));
|
||||||
if (str.size() == 3U)
|
|
||||||
c = str[1];
|
|
||||||
else if (str[1] == '\\' && str.size() == 4U) {
|
|
||||||
switch (str[2]) {
|
|
||||||
case '0':
|
|
||||||
c = '\0';
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
c = '\a';
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
c = '\b';
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
c = '\f';
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
c = '\n';
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
c = '\r';
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
c = '\t';
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
c = '\v';
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
case '\?':
|
|
||||||
case '\'':
|
|
||||||
case '\"':
|
|
||||||
c = str[2];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
|
|
||||||
}
|
|
||||||
} else if (str[1] == '\\' && str[2] == '0' && str.size() == 6U) {
|
|
||||||
return toLongNumber(str.substr(2,3));
|
|
||||||
} else if (str[1] == '\\' && str[2] == 'x' && str.size() == 6U) {
|
|
||||||
return toLongNumber("0" + str.substr(2,3));
|
|
||||||
} else
|
|
||||||
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
|
|
||||||
return c & 0xff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bigint ret = 0;
|
bigint ret = 0;
|
||||||
|
|
|
@ -113,6 +113,9 @@ public:
|
||||||
* @return true if given character is octal digit.
|
* @return true if given character is octal digit.
|
||||||
*/
|
*/
|
||||||
static bool isOctalDigit(char c);
|
static bool isOctalDigit(char c);
|
||||||
|
private:
|
||||||
|
static MathLib::bigint characterLiteralToLongNumber(const std::string& str);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2);
|
MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2);
|
||||||
|
|
|
@ -271,9 +271,17 @@ private:
|
||||||
|
|
||||||
// from char
|
// from char
|
||||||
ASSERT_EQUALS((int)('A'), MathLib::toLongNumber("'A'"));
|
ASSERT_EQUALS((int)('A'), MathLib::toLongNumber("'A'"));
|
||||||
|
ASSERT_EQUALS((int)('\0'), MathLib::toLongNumber("'\\0'"));
|
||||||
ASSERT_EQUALS((int)('\r'), MathLib::toLongNumber("'\\r'"));
|
ASSERT_EQUALS((int)('\r'), MathLib::toLongNumber("'\\r'"));
|
||||||
ASSERT_EQUALS((int)('\x12'), MathLib::toLongNumber("'\\x12'"));
|
ASSERT_EQUALS((int)('\x12'), MathLib::toLongNumber("'\\x12'"));
|
||||||
|
// may cause some compile problems: ASSERT_EQUALS((int)('\x123'), MathLib::toLongNumber("'\\x123'"));
|
||||||
|
// may cause some compile problems: ASSERT_EQUALS((int)('\x1234'), MathLib::toLongNumber("'\\x1234'"));
|
||||||
|
ASSERT_EQUALS((int)('\3'), MathLib::toLongNumber("'\\3'"));
|
||||||
|
ASSERT_EQUALS((int)('\34'), MathLib::toLongNumber("'\\34'"));
|
||||||
ASSERT_EQUALS((int)('\034'), MathLib::toLongNumber("'\\034'"));
|
ASSERT_EQUALS((int)('\034'), MathLib::toLongNumber("'\\034'"));
|
||||||
|
ASSERT_EQUALS((int)('\134'), MathLib::toLongNumber("'\\134'"));
|
||||||
|
ASSERT_THROW(MathLib::toLongNumber("'\\9'"), InternalError);
|
||||||
|
ASSERT_THROW(MathLib::toLongNumber("'\\934'"), InternalError);
|
||||||
|
|
||||||
ASSERT_EQUALS(-8552249625308161526, MathLib::toLongNumber("0x89504e470d0a1a0a"));
|
ASSERT_EQUALS(-8552249625308161526, MathLib::toLongNumber("0x89504e470d0a1a0a"));
|
||||||
ASSERT_EQUALS(-8481036456200365558, MathLib::toLongNumber("0x8a4d4e470d0a1a0a"));
|
ASSERT_EQUALS(-8481036456200365558, MathLib::toLongNumber("0x8a4d4e470d0a1a0a"));
|
||||||
|
|
Loading…
Reference in New Issue