Correct detection of Microsoft extensions in MathLib::isValidIntegerSuffix. Remove public overloaded implementation which was not used outside mathlib.cpp. (#1531)

This commit is contained in:
amai2012 2018-12-20 12:20:31 +01:00 committed by GitHub
parent 0f4eac657d
commit 19e979315f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 133 additions and 161 deletions

View File

@ -740,6 +740,97 @@ bool MathLib::isPositive(const std::string &str)
return !MathLib::isNegative(str); return !MathLib::isNegative(str);
} }
static bool _isValidIntegerSuffix(std::string::const_iterator it, std::string::const_iterator end, bool supportMicrosoftExtensions=true)
{
enum { START, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU, SUFFIX_I, SUFFIX_I6, SUFFIX_I64, SUFFIX_UI, SUFFIX_UI6, SUFFIX_UI64 } state = START;
for (; it != end; ++it) {
switch (state) {
case START:
if (*it == 'u' || *it == 'U')
state = SUFFIX_U;
else if (*it == 'l' || *it == 'L')
state = SUFFIX_L;
else if (supportMicrosoftExtensions && (*it == 'i' || *it == 'I'))
state = SUFFIX_I;
else
return false;
break;
case SUFFIX_U:
if (*it == 'l' || *it == 'L')
state = SUFFIX_UL; // UL
else if (supportMicrosoftExtensions && (*it == 'i' || *it == 'I'))
state = SUFFIX_UI;
else
return false;
break;
case SUFFIX_UL:
if (*it == 'l' || *it == 'L')
state = SUFFIX_ULL; // ULL
else
return false;
break;
case SUFFIX_L:
if (*it == 'u' || *it == 'U')
state = SUFFIX_LU; // LU
else if (*it == 'l' || *it == 'L')
state = SUFFIX_LL; // LL
else
return false;
break;
case SUFFIX_LU:
return false;
case SUFFIX_LL:
if (*it == 'u' || *it == 'U')
state = SUFFIX_LLU; // LLU
else
return false;
break;
case SUFFIX_I:
if (*it == '6')
state = SUFFIX_I6;
else
return false;
break;
case SUFFIX_I6:
if (*it == '4')
state = SUFFIX_I64;
else
return false;
break;
case SUFFIX_UI:
if (*it == '6')
state = SUFFIX_UI6;
else
return false;
break;
case SUFFIX_UI6:
if (*it == '4')
state = SUFFIX_UI64;
else
return false;
break;
default:
return false;
}
}
return ((state == SUFFIX_U) ||
(state == SUFFIX_L) ||
(state == SUFFIX_UL) ||
(state == SUFFIX_LU) ||
(state == SUFFIX_LL) ||
(state == SUFFIX_ULL) ||
(state == SUFFIX_LLU) ||
(state == SUFFIX_I64) ||
(state == SUFFIX_UI64));
}
bool MathLib::isValidIntegerSuffix(const std::string& str, bool supportMicrosoftExtensions)
{
return _isValidIntegerSuffix(str.begin(), str.end(), supportMicrosoftExtensions);
}
/*! \brief Does the string represent an octal number? /*! \brief Does the string represent an octal number?
* In case leading or trailing white space is provided, the function * In case leading or trailing white space is provided, the function
* returns false. * returns false.
@ -777,7 +868,7 @@ bool MathLib::isOct(const std::string& str)
if (isOctalDigit(static_cast<unsigned char>(*it))) if (isOctalDigit(static_cast<unsigned char>(*it)))
state = DIGITS; state = DIGITS;
else else
return isValidIntegerSuffix(it,str.end()); return _isValidIntegerSuffix(it,str.end());
break; break;
} }
} }
@ -818,7 +909,7 @@ bool MathLib::isIntHex(const std::string& str)
if (isxdigit(static_cast<unsigned char>(*it))) if (isxdigit(static_cast<unsigned char>(*it)))
; // state = DIGIT; ; // state = DIGIT;
else else
return isValidIntegerSuffix(it,str.end()); return _isValidIntegerSuffix(it,str.end());
break; break;
} }
} }
@ -905,94 +996,6 @@ bool MathLib::isFloatHex(const std::string& str)
return (EXPONENT_DIGITS==state) || (EXPONENT_SUFFIX == state); return (EXPONENT_DIGITS==state) || (EXPONENT_SUFFIX == state);
} }
bool MathLib::isValidIntegerSuffix(const std::string& str)
{
return isValidIntegerSuffix(str.begin(), str.end());
}
bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::const_iterator end)
{
enum {START, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU, SUFFIX_I, SUFFIX_I6, SUFFIX_I64, SUFFIX_UI, SUFFIX_UI6, SUFFIX_UI64} state = START;
for (; it != end; ++it) {
switch (state) {
case START:
if (*it == 'u' || *it == 'U')
state = SUFFIX_U;
else if (*it == 'l' || *it == 'L')
state = SUFFIX_L;
else if (*it == 'i')
state = SUFFIX_I;
else
return false;
break;
case SUFFIX_U:
if (*it == 'l' || *it == 'L')
state = SUFFIX_UL; // UL
else if (*it == 'i')
state = SUFFIX_UI;
else
return false;
break;
case SUFFIX_UL:
if (*it == 'l' || *it == 'L')
state = SUFFIX_ULL; // ULL
else
return false;
break;
case SUFFIX_L:
if (*it == 'u' || *it == 'U')
state = SUFFIX_LU; // LU
else if (*it == 'l' || *it == 'L')
state = SUFFIX_LL; // LL
else
return false;
break;
case SUFFIX_LU:
return false;
case SUFFIX_LL:
if (*it == 'u' || *it == 'U')
state = SUFFIX_LLU; // LLU
else
return false;
break;
case SUFFIX_I:
if (*it == '6')
state = SUFFIX_I6;
else
return false;
break;
case SUFFIX_I6:
if (*it == '4')
state = SUFFIX_I64;
else
return false;
break;
case SUFFIX_UI:
if (*it == '6')
state = SUFFIX_UI6;
else
return false;
break;
case SUFFIX_UI6:
if (*it == '4')
state = SUFFIX_UI64;
else
return false;
break;
default:
return false;
}
}
return ((state == SUFFIX_U) ||
(state == SUFFIX_L) ||
(state == SUFFIX_UL) ||
(state == SUFFIX_LU) ||
(state == SUFFIX_LL) ||
(state == SUFFIX_ULL) ||
(state == SUFFIX_LLU) ||
(state == SUFFIX_I64) ||
(state == SUFFIX_UI64));
}
/*! \brief Does the string represent a binary number? /*! \brief Does the string represent a binary number?
* In case leading or trailing white space is provided, the function * In case leading or trailing white space is provided, the function
@ -1037,7 +1040,7 @@ bool MathLib::isBin(const std::string& str)
if (*it == '0' || *it == '1') if (*it == '0' || *it == '1')
; // state = DIGIT; ; // state = DIGIT;
else else
return isValidIntegerSuffix(it,str.end()); return _isValidIntegerSuffix(it,str.end());
break; break;
} }
} }
@ -1066,7 +1069,7 @@ bool MathLib::isDec(const std::string & str)
if (isdigit(static_cast<unsigned char>(*it))) if (isdigit(static_cast<unsigned char>(*it)))
state = DIGIT; state = DIGIT;
else else
return isValidIntegerSuffix(it,str.end()); return _isValidIntegerSuffix(it,str.end());
break; break;
} }
} }

View File

@ -92,8 +92,12 @@ public:
static bool isBin(const std::string& str); static bool isBin(const std::string& str);
static std::string getSuffix(const std::string& value); static std::string getSuffix(const std::string& value);
static bool isValidIntegerSuffix(const std::string& str); /**
static bool isValidIntegerSuffix(std::string::const_iterator it, std::string::const_iterator end); * \param[in] str string
* \param[in] supportMicrosoftExtensions support Microsoft extension: i64
* \return true if str is a non-empty valid integer suffix
*/
static bool isValidIntegerSuffix(const std::string& str, bool supportMicrosoftExtensions=true);
static std::string add(const std::string & first, const std::string & second); static std::string add(const std::string & first, const std::string & second);
static std::string subtract(const std::string & first, const std::string & second); static std::string subtract(const std::string & first, const std::string & second);

View File

@ -701,75 +701,40 @@ private:
void isValidIntegerSuffix(void) const { void isValidIntegerSuffix(void) const {
// negative testing // negative testing
std::string value = "ux"; ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(""));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("ux"));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("ulx"));
value = "ulx"; ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("lx"));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("lux"));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("lll"));
value = "lx"; ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("garbage"));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("llu "));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("i"));
value = "lux"; ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("iX"));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("i6X"));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("i64X"));
value = "lll"; ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("i64 "));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("i66"));
value = "garbage";
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value.clear();
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "llu ";
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "i";
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "iX";
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "i6X";
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "i64X";
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "i64 ";
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "i66";
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
// positive testing // positive testing
value = "u"; ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("u"));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("ul"));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("ull"));
value = "ul"; ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("l"));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("lu"));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("ll"));
value = "ull"; ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("llu"));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("llU"));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("LLU"));
value = "l"; // Microsoft extensions:
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("i64"));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("I64"));
value = "lu"; ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("ui64"));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix("UI64"));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("i64", false));
value = "ll"; ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("I64", false));
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("ui64", false));
ASSERT_EQUALS(false, MathLib::isValidIntegerSuffix("UI64", false));
value = "llu";
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "i64";
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "ui64";
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
} }
void ispositive() const { void ispositive() const {