ettlmartin: improved the MathLib::IsInt

This commit is contained in:
Daniel Marjamäki 2009-08-16 18:45:26 +02:00
parent 522f783ada
commit 52856fcbeb
3 changed files with 88 additions and 7 deletions

View File

@ -371,8 +371,9 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok)
void CheckMemoryLeakInFunction::init()
{
static const char * const white_list[] = {
"if", "for", "while", "return", "switch", "realloc", "delete"
static const char * const white_list[] =
{
"if", "for", "while", "return", "switch", "realloc", "delete"
, "strcpy", "strncpy", "strcat", "strncat", "strcmp", "strncmp"
, "strcasecmp", "stricmp", "sprintf", "strchr", "strrchr", "strstr"
, "memset", "memcpy", "memmove", "memchr", "fgets", "fgetc", "getc"

View File

@ -39,7 +39,9 @@ long MathLib::toLongNumber(const std::string &str)
{
return std::strtoul(str.c_str(), '\0', 8);
}
return std::atol(str.c_str());
return (str.find("E", 0) != std::string::npos || str.find("e", 0) != std::string::npos)
? static_cast<long>(std::atof(str.c_str()))
: std::atol(str.c_str());
}
double MathLib::toDoubleNumber(const std::string &str)
@ -59,14 +61,91 @@ std::string MathLib::toString(T d)
return result.str();
}
bool MathLib::isInt(const std::string & str)
bool MathLib::isInt(const std::string & s)
{
if (str.find(".", 0) != std::string::npos || str.find("e", 0) != std::string::npos
|| str.find("E", 0) != std::string::npos)
// perform prechecks:
// ------------------
// first check, if a point is found, it is an floating point value
if (s.find(".", 0) != std::string::npos) return false;
// check for scientific notation e.g. NumberE-Number this is obvious an floating point value
else if (s.find("E-", 0) != std::string::npos || s.find("e-", 0) != std::string::npos) return false;
// prechecking has nothing found,...
// gather information
enum Representation
{
return false;
eScientific = 0 // NumberE+Number or NumberENumber
, eOctal // starts with 0
, eHex // starts with 0x
, eDefault // Numbers with a (possible) trailing u or U or l or L for unsigned or long datatypes
};
// create an instance
Representation Mode = eDefault;
// remember position
unsigned long n = 0;
// eat up whitespace
while (isspace(s[n])) ++n;
// determine type
if (s.find("E", 0) != std::string::npos) Mode = eScientific;
else if (s.find("0x", n, 2) != std::string::npos) Mode = eHex;
else if (s.find("0", n, 1) != std::string::npos && isdigit(s[n+1])) Mode = eOctal;
// check sign
if (s[n] == '-' || s[n] == '+') ++n;
// check scientific notation
if (Mode == eScientific)
{
// check digits
while (isdigit(s[n])) ++n;
// check scientific notation
if (s[n] == 'E' || s[n] == 'e')
{
++n;
// check positive exponent
if (s[n] == '+') ++n;
// floating pointer number e.g. 124E-2
if (s[n] == '-') return false;
// check digits of the exponent
while (isdigit(s[n])) ++n;
}
}
// check hex notation
else if (Mode == eHex)
{
++n; // 0
++n; // x
while (isdigit(s[n]) || s[n] == 'A' || s[n] == 'B' || s[n] == 'C' || s[n] == 'D' || s[n] == 'E' || s[n] == 'F' ||
s[n] == 'a' || s[n] == 'b' || s[n] == 'c' || s[n] == 'd' || s[n] == 'e' || s[n] == 'f')
++n;
}
// check octal notation
else if (Mode == eOctal)
{
while (s[n] == '0' || s[n] == '1' || s[n] == '2' || s[n] == '3' || s[n] == '4' || s[n] == '5' || s[n] == '6' || s[n] == '7')
++n;
}
else if (Mode == eDefault)
{
while (isdigit(s[n])) ++n;
// unsigned or long
if (s[n] == 'u' || s[n] == 'U' || s[n] == 'l' || s[n] == 'L') ++n;
}
// eat up whitespace
while (isspace(s[n]))
++n;
// if everything goes good, we are at the end of the string and no digits/character
// is here --> return true, but if something was found eg. 12E+12AA return false
if (s[n])
return false;
return true;
}
std::string MathLib::add(const std::string & first, const std::string & second)

View File

@ -43,6 +43,7 @@ private:
ASSERT_EQUALS("-11.96", MathLib::multiply("-2.3", "5.2"));
ASSERT_EQUALS("7", MathLib::divide("21.", "3"));
ASSERT_EQUALS("1", MathLib::divide("3", "2"));
ASSERT_EQUALS("3000", MathLib::multiply("1E3", "3"));
}
void convert()