Skip to content

Commit 5b4ece4

Browse files
committed
MathLib::isBin(): fix missing detection of U and L suffix combinations. Added missing test cases.
1 parent 6ca7dae commit 5b4ece4

File tree

2 files changed

+127
-3
lines changed

2 files changed

+127
-3
lines changed

lib/mathlib.cpp

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,93 @@ bool MathLib::isHex(const std::string& str)
138138
return (str.compare(sign?1:0, 2, "0x") == 0 || str.compare(sign?1:0, 2, "0X") == 0);
139139
}
140140

141-
bool MathLib::isBin(const std::string& str)
141+
/*! \brief Does the string represent a binary number?
142+
* In case leading or trailing white space is provided, the function
143+
* returns false.
144+
* Additional information can be found here:
145+
* http://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html
146+
*
147+
* \param[in] s The string to check. In case the string is empty, the function returns false.
148+
* \return Return true in case a binary number is provided and false otherwise.
149+
**/
150+
bool MathLib::isBin(const std::string& s)
142151
{
143-
const bool sign = str[0]=='-' || str[0]=='+';
144-
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);
152+
enum {START, PLUSMINUS, GNU_BIN_PREFIX, DIGIT, DIGITS, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU} state = START;
153+
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
154+
switch (state) {
155+
case START:
156+
if (*it == '+' || *it == '-')
157+
state = PLUSMINUS;
158+
else if (*it == '0')
159+
state = GNU_BIN_PREFIX;
160+
else
161+
return false;
162+
break;
163+
case PLUSMINUS:
164+
if (*it == '0')
165+
state = GNU_BIN_PREFIX;
166+
else
167+
return false;
168+
break;
169+
case GNU_BIN_PREFIX:
170+
if (*it == 'b' || *it == 'B')
171+
state = DIGIT;
172+
else
173+
return false;
174+
break;
175+
case DIGIT:
176+
if (*it == '0' || *it == '1')
177+
state = DIGITS;
178+
else
179+
return false;
180+
break;
181+
case DIGITS:
182+
if (*it == '0' || *it == '1')
183+
state = DIGITS;
184+
else if (*it == 'u' || *it == 'U')
185+
state = SUFFIX_U;
186+
else if (*it == 'l' || *it == 'L')
187+
state = SUFFIX_L;
188+
else
189+
return false;
190+
break;
191+
case SUFFIX_U:
192+
if (*it == 'l' || *it == 'L')
193+
state = SUFFIX_UL; // UL
194+
else
195+
return false;
196+
break;
197+
case SUFFIX_UL:
198+
if (*it == 'l' || *it == 'L')
199+
state = SUFFIX_ULL; // ULL
200+
else
201+
return false;
202+
break;
203+
case SUFFIX_L:
204+
if (*it == 'u' || *it == 'U')
205+
state = SUFFIX_LU; // LU
206+
else if (*it == 'l' || *it == 'L')
207+
state = SUFFIX_LL; // LL
208+
else
209+
return false;
210+
break;
211+
case SUFFIX_LU:
212+
return false;
213+
break;
214+
case SUFFIX_LL:
215+
if (*it == 'u' || *it == 'U')
216+
state = SUFFIX_LLU; // LLU
217+
else
218+
return false;
219+
break;
220+
default:
221+
return false;
222+
}
223+
}
224+
return (state == DIGITS)
225+
|| (state == SUFFIX_U) || (state == SUFFIX_L)
226+
|| (state == SUFFIX_UL) || (state == SUFFIX_LU) || (state == SUFFIX_LL)
227+
|| (state == SUFFIX_ULL) || (state == SUFFIX_LLU);
145228
}
146229

147230
bool MathLib::isInt(const std::string & s)

test/testmathlib.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class TestMathLib : public TestFixture {
3333
TEST_CASE(calculate1);
3434
TEST_CASE(convert);
3535
TEST_CASE(isint);
36+
TEST_CASE(isbin);
3637
TEST_CASE(isnegative);
3738
TEST_CASE(ispositive);
3839
TEST_CASE(isfloat);
@@ -312,6 +313,46 @@ class TestMathLib : public TestFixture {
312313
ASSERT_EQUALS(false, MathLib::isInt("LL"));
313314
}
314315

316+
void isbin() {
317+
// positive testing
318+
ASSERT_EQUALS(true, MathLib::isBin("0b0"));
319+
ASSERT_EQUALS(true, MathLib::isBin("0b1"));
320+
ASSERT_EQUALS(true, MathLib::isBin("+0b1"));
321+
ASSERT_EQUALS(true, MathLib::isBin("-0b1"));
322+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111"));
323+
ASSERT_EQUALS(true, MathLib::isBin("-0b11010111"));
324+
ASSERT_EQUALS(true, MathLib::isBin("0B11010111"));
325+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111u"));
326+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111ul"));
327+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111ull"));
328+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111l"));
329+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111ll"));
330+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111llu"));
331+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111l"));
332+
ASSERT_EQUALS(true, MathLib::isBin("0b11010111lu"));
333+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lul")); // Suffix LUL not allowed
334+
335+
// negative testing
336+
ASSERT_EQUALS(false, MathLib::isBin("100101bx"));
337+
ASSERT_EQUALS(false, MathLib::isBin("0"));
338+
ASSERT_EQUALS(false, MathLib::isBin("0B"));
339+
ASSERT_EQUALS(false, MathLib::isBin("0C"));
340+
ASSERT_EQUALS(false, MathLib::isBin("+0B"));
341+
ASSERT_EQUALS(false, MathLib::isBin("-0B"));
342+
ASSERT_EQUALS(false, MathLib::isBin("-0Bx"));
343+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111x"));
344+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111ux"));
345+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lx"));
346+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lux"));
347+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111ulx"));
348+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lulx"));
349+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111ullx"));
350+
ASSERT_EQUALS(false, MathLib::isBin("0b11010111lll"));
351+
352+
// test empty string
353+
ASSERT_EQUALS(false, MathLib::isBin(""));
354+
}
355+
315356
void isnegative() const {
316357
ASSERT_EQUALS(true , MathLib::isNegative("-1"));
317358
ASSERT_EQUALS(true , MathLib::isNegative("-1."));

0 commit comments

Comments
 (0)