MathLib::isOct() fix missing detection of U and L suffix combinations and unittests.

This commit is contained in:
Martin Ettl 2014-03-09 21:14:14 +01:00
parent 5b4ece4f9c
commit 0360840753
2 changed files with 143 additions and 3 deletions

View File

@ -126,10 +126,88 @@ bool MathLib::isPositive(const std::string &s)
return !MathLib::isNegative(s);
}
bool MathLib::isOct(const std::string& str)
/*! \brief Does the string represent an octal number?
* In case leading or trailing white space is provided, the function
* returns false.
* Additional information can be found here:
* http://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html
*
* \param[in] s The string to check. In case the string is empty, the function returns false.
* \return Return true in case a octal number is provided and false otherwise.
**/
bool MathLib::isOct(const std::string& s)
{
const bool sign = str[0]=='-' || str[0]=='+';
return (str[sign?1:0] == '0' && (str.size() == 1 || isOctalDigit(str[sign?2:1])) && !isFloat(str));
enum {START, PLUSMINUS, OCTAL_PREFIX, DIGITS, UNSIGNED_SUFFIX, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU} state = START;
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
switch (state) {
case START:
if (*it == '+' || *it == '-')
state = PLUSMINUS;
else if (*it == '0')
state = OCTAL_PREFIX;
else
return false;
break;
case PLUSMINUS:
if (*it == '0')
state = OCTAL_PREFIX;
else
return false;
break;
case OCTAL_PREFIX:
if (isOctalDigit(*it))
state = DIGITS;
else
return false;
break;
case DIGITS:
if (isOctalDigit(*it))
state = DIGITS;
else if (*it == 'u' || *it == 'U')
state = SUFFIX_U;
else if (*it == 'l' || *it == 'L')
state = SUFFIX_L;
else
return false;
break;
case SUFFIX_U:
if (*it == 'l' || *it == 'L')
state = SUFFIX_UL; // UL
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;
break;
case SUFFIX_LL:
if (*it == 'u' || *it == 'U')
state = SUFFIX_LLU; // LLU
else
return false;
break;
default:
return false;
}
}
return (state == DIGITS)
|| (state == SUFFIX_U) || (state == SUFFIX_L)
|| (state == SUFFIX_UL) || (state == SUFFIX_LU) || (state == SUFFIX_LL)
|| (state == SUFFIX_ULL) || (state == SUFFIX_LLU);
}
bool MathLib::isHex(const std::string& str)

View File

@ -34,6 +34,7 @@ private:
TEST_CASE(convert);
TEST_CASE(isint);
TEST_CASE(isbin);
TEST_CASE(isoct);
TEST_CASE(isnegative);
TEST_CASE(ispositive);
TEST_CASE(isfloat);
@ -367,6 +368,67 @@ private:
ASSERT_EQUALS(false, MathLib::isNegative("+1.0E-2"));
}
void isoct() {
// octal number format: [+|-]0[0-7][suffix]
// positive testing
ASSERT_EQUALS(true, MathLib::isOct("010"));
ASSERT_EQUALS(true, MathLib::isOct("+010"));
ASSERT_EQUALS(true, MathLib::isOct("-010"));
ASSERT_EQUALS(true, MathLib::isOct("0175"));
ASSERT_EQUALS(true, MathLib::isOct("+0175"));
ASSERT_EQUALS(true, MathLib::isOct("-0175"));
ASSERT_EQUALS(true, MathLib::isOct("00"));
ASSERT_EQUALS(true, MathLib::isOct("02"));
ASSERT_EQUALS(true, MathLib::isOct("+042"));
ASSERT_EQUALS(true, MathLib::isOct("-042"));
ASSERT_EQUALS(true, MathLib::isOct("+042U"));
ASSERT_EQUALS(true, MathLib::isOct("-042U"));
ASSERT_EQUALS(true, MathLib::isOct("+042L"));
ASSERT_EQUALS(true, MathLib::isOct("-042L"));
ASSERT_EQUALS(true, MathLib::isOct("+042LU"));
ASSERT_EQUALS(true, MathLib::isOct("-042LU"));
ASSERT_EQUALS(true, MathLib::isOct("+042UL"));
ASSERT_EQUALS(true, MathLib::isOct("-042UL"));
ASSERT_EQUALS(true, MathLib::isOct("+042ULL"));
ASSERT_EQUALS(true, MathLib::isOct("-042ULL"));
ASSERT_EQUALS(true, MathLib::isOct("+042LLU"));
ASSERT_EQUALS(true, MathLib::isOct("-042LLU"));
// test empty string
ASSERT_EQUALS(false, MathLib::isOct(""));
// negative testing
ASSERT_EQUALS(false, MathLib::isOct("0"));
ASSERT_EQUALS(false, MathLib::isOct("-0x175"));
ASSERT_EQUALS(false, MathLib::isOct("-0_garbage_"));
ASSERT_EQUALS(false, MathLib::isOct(" "));
ASSERT_EQUALS(false, MathLib::isOct(" "));
ASSERT_EQUALS(false, MathLib::isOct("02."));
ASSERT_EQUALS(false, MathLib::isOct("02E2"));
ASSERT_EQUALS(false, MathLib::isOct("+042x"));
ASSERT_EQUALS(false, MathLib::isOct("-042x"));
ASSERT_EQUALS(false, MathLib::isOct("+042Ux"));
ASSERT_EQUALS(false, MathLib::isOct("-042Ux"));
ASSERT_EQUALS(false, MathLib::isOct("+042Lx"));
ASSERT_EQUALS(false, MathLib::isOct("-042Lx"));
ASSERT_EQUALS(false, MathLib::isOct("+042ULx"));
ASSERT_EQUALS(false, MathLib::isOct("-042ULx"));
ASSERT_EQUALS(false, MathLib::isOct("+042LLx"));
ASSERT_EQUALS(false, MathLib::isOct("-042LLx"));
ASSERT_EQUALS(false, MathLib::isOct("+042ULLx"));
ASSERT_EQUALS(false, MathLib::isOct("-042ULLx"));
ASSERT_EQUALS(false, MathLib::isOct("+042LLUx"));
ASSERT_EQUALS(false, MathLib::isOct("-042LLUx"));
ASSERT_EQUALS(false, MathLib::isOct("+042LUL"));
ASSERT_EQUALS(false, MathLib::isOct("-042LUL"));
// white space in front
ASSERT_EQUALS(false, MathLib::isOct(" -042ULL"));
// trailing white space
ASSERT_EQUALS(false, MathLib::isOct("-042ULL "));
// front and trailing white space
ASSERT_EQUALS(false, MathLib::isOct(" -042ULL "));
}
void ispositive() const {
ASSERT_EQUALS(false, MathLib::isPositive("-1"));
ASSERT_EQUALS(false, MathLib::isPositive("-1."));