Add an optional extended description…
This commit is contained in:
parent
3916cd628e
commit
3095f47a7b
|
@ -1249,6 +1249,42 @@ bool MathLib::isOctalDigit(char c)
|
||||||
return (c >= '0' && c <= '7');
|
return (c >= '0' && c <= '7');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MathLib::isDigitSeparator(const std::string& iCode, std::string::size_type iPos) {
|
||||||
|
if (iPos == 0 || iPos >= iCode.size() || iCode[iPos] != '\'')
|
||||||
|
return false;
|
||||||
|
std::string::size_type i = iPos - 1;
|
||||||
|
while (std::isxdigit(iCode[i])) {
|
||||||
|
if (i == 0)
|
||||||
|
return true; // Only xdigits before '
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
if (i == iPos - 1) { // No xdigit before '
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
switch(iCode[i]) {
|
||||||
|
case ' ':
|
||||||
|
case '.':
|
||||||
|
case ',':
|
||||||
|
case 'x':
|
||||||
|
case '(':
|
||||||
|
case '{':
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '*':
|
||||||
|
case '%':
|
||||||
|
case '/':
|
||||||
|
case '&':
|
||||||
|
case '|':
|
||||||
|
case '^':
|
||||||
|
case '~':
|
||||||
|
case '=':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2)
|
MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2)
|
||||||
{
|
{
|
||||||
return MathLib::value::calc('+',v1,v2);
|
return MathLib::value::calc('+',v1,v2);
|
||||||
|
|
|
@ -122,6 +122,13 @@ public:
|
||||||
* */
|
* */
|
||||||
static MathLib::bigint characterLiteralToLongNumber(const std::string& str);
|
static MathLib::bigint characterLiteralToLongNumber(const std::string& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param iCode Code being considered
|
||||||
|
* \param iPos A posision within iCode
|
||||||
|
* \return Whether iCode[iPos] is a C++14 digit separator
|
||||||
|
*/
|
||||||
|
static bool isDigitSeparator(const std::string& iCode, std::string::size_type iPos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
* \param iLiteral A character literal
|
* \param iLiteral A character literal
|
||||||
|
|
|
@ -697,7 +697,7 @@ std::string Preprocessor::removeComments(const std::string &str, const std::stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++14 digit separators
|
// C++14 digit separators
|
||||||
if (ch == '\'' && std::isxdigit(previous))
|
if (MathLib::isDigitSeparator(str, i))
|
||||||
; // Just skip it.
|
; // Just skip it.
|
||||||
|
|
||||||
// String or char constants..
|
// String or char constants..
|
||||||
|
|
|
@ -59,6 +59,7 @@ private:
|
||||||
TEST_CASE(abs);
|
TEST_CASE(abs);
|
||||||
TEST_CASE(toString);
|
TEST_CASE(toString);
|
||||||
TEST_CASE(characterLiteralsNormalization);
|
TEST_CASE(characterLiteralsNormalization);
|
||||||
|
TEST_CASE(CPP14DigitSeparators);
|
||||||
}
|
}
|
||||||
|
|
||||||
void isGreater() const {
|
void isGreater() const {
|
||||||
|
@ -1143,6 +1144,23 @@ private:
|
||||||
// Unsupported single escape sequence
|
// Unsupported single escape sequence
|
||||||
ASSERT_THROW(MathLib::normalizeCharacterLiteral("\\c"), InternalError);
|
ASSERT_THROW(MathLib::normalizeCharacterLiteral("\\c"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPP14DigitSeparators() { // Ticket #7137
|
||||||
|
ASSERT(MathLib::isDigitSeparator("'", 0) == false);
|
||||||
|
ASSERT(MathLib::isDigitSeparator("123'0;", 3));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("foo(1'2);", 5));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("foo(1,1'2);", 7));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 7));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 13));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 16) == false);
|
||||||
|
ASSERT(MathLib::isDigitSeparator("int b=1+9'8;", 9));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("if (1'2) { char c = 'c'; }", 5));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 9));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("if (120&1'2) { char c = 'c'; }", 9));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("if (120|1'2) { char c = 'c'; }", 9));
|
||||||
|
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 24) == false);
|
||||||
|
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 26) == false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestMathLib)
|
REGISTER_TEST(TestMathLib)
|
||||||
|
|
|
@ -352,6 +352,11 @@ private:
|
||||||
|
|
||||||
ASSERT_EQUALS("int i = 0x0F0FFFFF;", preprocessorRead("int i = 0x0F0F'FFFF;"));
|
ASSERT_EQUALS("int i = 0x0F0FFFFF;", preprocessorRead("int i = 0x0F0F'FFFF;"));
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// Ticket #7137
|
||||||
|
const char code[] = "void t(char c) { switch (c) { case'M': break; } }";
|
||||||
|
ASSERT_EQUALS(code, preprocessorRead(code));
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue