Skip to content

Commit ab2f8bf

Browse files
committed
Tidy up MathLib::isInt() - using a state machine approach
1 parent b10fce3 commit ab2f8bf

2 files changed

Lines changed: 35 additions & 41 deletions

File tree

lib/mathlib.cpp

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,6 @@ bool MathLib::isOct(const std::string& s)
251251

252252
bool MathLib::isHex(const std::string& s)
253253
{
254-
// return false, in case an empty string is provided
255-
if (s.empty())
256-
return false;
257-
258254
enum {START, PLUSMINUS, HEX_PREFIX, DIGIT, DIGITS} state = START;
259255
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
260256
switch (state) {
@@ -403,45 +399,39 @@ bool MathLib::isBin(const std::string& s)
403399

404400
bool MathLib::isInt(const std::string & s)
405401
{
406-
// perform prechecks:
407-
// ------------------
408-
// first check, if a point is found, it is an floating point value
409-
const std::string charsToIndicateAFloat=".eE";
410-
if (s.find_last_of(charsToIndicateAFloat) != std::string::npos)
411-
return false;
412-
413-
// remember position
414-
unsigned long n = 0;
415-
// eat up whitespace
416-
while (std::isspace(s[n])) ++n;
417-
418-
// determine type
402+
// check for two known types: hexadecimal and octal
419403
if (isHex(s) || isOct(s)) {
420404
return true;
421405
}
422406

423-
// check sign
424-
if (s[n] == '-' || s[n] == '+') ++n;
425-
426-
// starts with digit
427-
bool bStartsWithDigit=false;
428-
while (std::isdigit(s[n])) {
429-
bStartsWithDigit=true;
430-
++n;
407+
enum {START, PLUSMINUS, DIGIT, SUFFIX} state = START;
408+
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
409+
switch (state) {
410+
case START:
411+
if (*it == '+' || *it == '-')
412+
state = PLUSMINUS;
413+
else if (isdigit(*it))
414+
state = DIGIT;
415+
else
416+
return false;
417+
break;
418+
case PLUSMINUS:
419+
if (isdigit(*it))
420+
state = DIGIT;
421+
else
422+
return false;
423+
break;
424+
case DIGIT:
425+
if (isdigit(*it))
426+
state = DIGIT;
427+
else
428+
return isValidSuffix(it,s.end());
429+
break;
430+
case SUFFIX:
431+
break;
432+
}
431433
}
432-
433-
while (std::tolower(s[n]) == 'u' || std::tolower(s[n]) == 'l') ++n; // unsigned or long (long)
434-
435-
if (!bStartsWithDigit)
436-
return false;
437-
438-
// eat up whitespace
439-
while (std::isspace(s[n]))
440-
++n;
441-
442-
// if everything goes good, we are at the end of the string and no digits/character
443-
// is here --> return true, but if something was found e.g. 12E+12AA return false
444-
return (n >= s.length());
434+
return state == DIGIT;
445435
}
446436

447437
std::string MathLib::add(const std::string & first, const std::string & second)

test/testmathlib.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ class TestMathLib : public TestFixture {
2929
private:
3030

3131
void run() {
32-
TEST_CASE(calculate);
33-
TEST_CASE(calculate1);
34-
TEST_CASE(convert);
3532
TEST_CASE(isint);
3633
TEST_CASE(isbin);
3734
TEST_CASE(isoct);
@@ -45,6 +42,9 @@ class TestMathLib : public TestFixture {
4542
TEST_CASE(isNotEqual)
4643
TEST_CASE(isLess)
4744
TEST_CASE(isLessEqual)
45+
TEST_CASE(calculate);
46+
TEST_CASE(calculate1);
47+
TEST_CASE(convert);
4848
TEST_CASE(naninf)
4949
}
5050

@@ -440,6 +440,7 @@ class TestMathLib : public TestFixture {
440440
ASSERT_EQUALS(false, MathLib::isOct("-042ULL "));
441441
// front and trailing white space
442442
ASSERT_EQUALS(false, MathLib::isOct(" -042ULL "));
443+
ASSERT_EQUALS(false, MathLib::isOct("+042LUL+0"));
443444
}
444445

445446
void ishex() const {
@@ -496,6 +497,9 @@ class TestMathLib : public TestFixture {
496497
ASSERT_EQUALS(false, MathLib::isHex("-0x0ULLz"));
497498
ASSERT_EQUALS(false, MathLib::isHex("+0x0LLUz"));
498499
ASSERT_EQUALS(false, MathLib::isHex("-0x0LLUz"));
500+
ASSERT_EQUALS(false, MathLib::isHex("0x0+0"));
501+
ASSERT_EQUALS(false, MathLib::isHex("e2"));
502+
ASSERT_EQUALS(false, MathLib::isHex("+E2"));
499503

500504
// test empty string
501505
ASSERT_EQUALS(false, MathLib::isHex(""));

0 commit comments

Comments
 (0)