Merge pull request #258 from orbitcowboy/master

MathLib::isBin(): fix missing detection of U and L suffix combinations. ...
This commit is contained in:
Daniel Marjamäki 2014-03-11 06:36:31 +01:00
commit af0cf9bbc1
2 changed files with 127 additions and 3 deletions

View File

@ -214,10 +214,93 @@ bool MathLib::isHex(const std::string& str)
return (str.compare(sign?1:0, 2, "0x") == 0 || str.compare(sign?1:0, 2, "0X") == 0); return (str.compare(sign?1:0, 2, "0x") == 0 || str.compare(sign?1:0, 2, "0X") == 0);
} }
bool MathLib::isBin(const std::string& str) /*! \brief Does the string represent a binary 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 binary number is provided and false otherwise.
**/
bool MathLib::isBin(const std::string& s)
{ {
const bool sign = str[0]=='-' || str[0]=='+'; enum {START, PLUSMINUS, GNU_BIN_PREFIX, DIGIT, DIGITS, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU} state = START;
return ((str.compare(sign?1:0, 2, "0b") == 0 || str.compare(sign?1:0, 2, "0B") == 0) && str.find_first_not_of("10bB", 1) == std::string::npos); 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 = GNU_BIN_PREFIX;
else
return false;
break;
case PLUSMINUS:
if (*it == '0')
state = GNU_BIN_PREFIX;
else
return false;
break;
case GNU_BIN_PREFIX:
if (*it == 'b' || *it == 'B')
state = DIGIT;
else
return false;
break;
case DIGIT:
if (*it == '0' || *it == '1')
state = DIGITS;
else
return false;
break;
case DIGITS:
if (*it == '0' || *it == '1')
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::isInt(const std::string & s) bool MathLib::isInt(const std::string & s)

View File

@ -33,6 +33,7 @@ private:
TEST_CASE(calculate1); TEST_CASE(calculate1);
TEST_CASE(convert); TEST_CASE(convert);
TEST_CASE(isint); TEST_CASE(isint);
TEST_CASE(isbin);
TEST_CASE(isnegative); TEST_CASE(isnegative);
TEST_CASE(ispositive); TEST_CASE(ispositive);
TEST_CASE(isfloat); TEST_CASE(isfloat);
@ -316,6 +317,46 @@ private:
ASSERT_EQUALS(false, MathLib::isInt(".E2")); ASSERT_EQUALS(false, MathLib::isInt(".E2"));
} }
void isbin() {
// positive testing
ASSERT_EQUALS(true, MathLib::isBin("0b0"));
ASSERT_EQUALS(true, MathLib::isBin("0b1"));
ASSERT_EQUALS(true, MathLib::isBin("+0b1"));
ASSERT_EQUALS(true, MathLib::isBin("-0b1"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111"));
ASSERT_EQUALS(true, MathLib::isBin("-0b11010111"));
ASSERT_EQUALS(true, MathLib::isBin("0B11010111"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111u"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111ul"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111ull"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111l"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111ll"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111llu"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111l"));
ASSERT_EQUALS(true, MathLib::isBin("0b11010111lu"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lul")); // Suffix LUL not allowed
// negative testing
ASSERT_EQUALS(false, MathLib::isBin("100101bx"));
ASSERT_EQUALS(false, MathLib::isBin("0"));
ASSERT_EQUALS(false, MathLib::isBin("0B"));
ASSERT_EQUALS(false, MathLib::isBin("0C"));
ASSERT_EQUALS(false, MathLib::isBin("+0B"));
ASSERT_EQUALS(false, MathLib::isBin("-0B"));
ASSERT_EQUALS(false, MathLib::isBin("-0Bx"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111x"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111ux"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lx"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lux"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111ulx"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lulx"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111ullx"));
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lll"));
// test empty string
ASSERT_EQUALS(false, MathLib::isBin(""));
}
void isnegative() const { void isnegative() const {
ASSERT_EQUALS(true , MathLib::isNegative("-1")); ASSERT_EQUALS(true , MathLib::isNegative("-1"));
ASSERT_EQUALS(true , MathLib::isNegative("-1.")); ASSERT_EQUALS(true , MathLib::isNegative("-1."));