Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 47 additions & 23 deletions simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ static bool isOct(const std::string &s)
return s.size()>1 && (s[0]=='0') && (s[1] >= '0') && (s[1] < '8');
}

static bool isBin(const std::string &s)
{
return s.size()>2 && s.compare(0,2,"0b")==0;
}

static bool isStringLiteral(const std::string &s)
{
return s.size() > 1 && (s[0]=='\"') && (*s.rbegin()=='\"');
Expand Down Expand Up @@ -117,32 +122,51 @@ static std::string locstring(const simplecpp::Location &loc)
}
#endif

static long long stringToLL(const std::string &s)
{
long long ret;
const bool hex = isHex(s);
const bool oct = isOct(s);
std::istringstream istr(hex ? s.substr(2) : oct ? s.substr(1) : s);
if (hex)
istr >> std::hex;
else if (oct)
istr >> std::oct;
istr >> ret;
return ret;
static unsigned long long stringToULL(const std::string &s, std::size_t offset = 0)
{
unsigned long long base = 10;
if (isHex(s.substr(offset))) {
offset += 2;
base = 16;
} else if (isOct(s.substr(offset))) {
offset += 1;
base = 8;
} else if (isBin(s.substr(offset))) {
offset += 2;
base = 2;
}

unsigned long long result = 0;
for (std::size_t i = offset; i < s.size(); i++) {
const char c = s[i];
result *= base;

unsigned long long d;
if ('0' <= c && c <= '9') {
d = c - '0';
} else if ('a' <= c && c <= 'f') {
d = 10 + c - 'a';
} else if ('A' <= c && c <= 'F') {
d = 10 + c - 'A';
} else {
throw std::runtime_error("invalid integer literal");
}

if (d >= base) {
throw std::runtime_error("invalid integer literal");
}

result += d;
}

return result;
}

static unsigned long long stringToULL(const std::string &s)
static long long stringToLL(const std::string &s)
{
unsigned long long ret;
const bool hex = isHex(s);
const bool oct = isOct(s);
std::istringstream istr(hex ? s.substr(2) : oct ? s.substr(1) : s);
if (hex)
istr >> std::hex;
else if (oct)
istr >> std::oct;
istr >> ret;
return ret;
if (s.size() > 0 && s[0] == '-')
return -stringToULL(s, 1);
return stringToULL(s);
}

static bool endsWith(const std::string &s, const std::string &e)
Expand Down
47 changes: 47 additions & 0 deletions test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2046,6 +2046,52 @@ static void ifUndefFuncStyleMacro()
ASSERT_EQUALS("file0,1,syntax_error,failed to evaluate #if condition, undefined function-like macro invocation: A( ... )\n", toString(outputList));
}

static void testIfIntegerLiteral(const std::string &value, const std::string &literal, bool expectError)
{
const std::string code = "#define A " + value + "\n"
"#if A == " + literal + "\n"
"int x = " + literal + ";\n"
"#endif\n";

simplecpp::OutputList outputList;

std::string literalPreprocessed = literal;
if (literalPreprocessed[0] == '-')
{
literalPreprocessed = "- " + literalPreprocessed.substr(1);
}

if (expectError) {
ASSERT_EQUALS("", preprocess(code.c_str(), &outputList));
ASSERT_EQUALS("file0,2,syntax_error,failed to evaluate #if condition, invalid integer literal\n", toString(outputList));
} else {
ASSERT_EQUALS("\n\nint x = " + literalPreprocessed + " ;", preprocess(code.c_str(), &outputList));
ASSERT_EQUALS("", toString(outputList));
}
}

static void ifIntegerLiteral()
{
testIfIntegerLiteral("123", "123", false);
testIfIntegerLiteral("-123", "-123", false);

testIfIntegerLiteral("123", "0x7b", false);
testIfIntegerLiteral("-123", "-0x7b", false);

testIfIntegerLiteral("123", "0x7B", false);
testIfIntegerLiteral("-123", "-0x7B", false);

testIfIntegerLiteral("123", "0173", false);
testIfIntegerLiteral("-123", "-0173", false);

testIfIntegerLiteral("123", "0b1111011", false);
testIfIntegerLiteral("-123", "-0b1111011", false);

testIfIntegerLiteral("123", "0xGH", true);
testIfIntegerLiteral("123", "019", true);
testIfIntegerLiteral("123", "0b30", true);
}

static void location1()
{
const char *code;
Expand Down Expand Up @@ -3688,6 +3734,7 @@ int main(int argc, char **argv)
TEST_CASE(ifalt); // using "and", "or", etc
TEST_CASE(ifexpr);
TEST_CASE(ifUndefFuncStyleMacro);
TEST_CASE(ifIntegerLiteral);

TEST_CASE(location1);
TEST_CASE(location2);
Expand Down
Loading