Skip to content
Draft
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
46 changes: 31 additions & 15 deletions lib/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,7 @@ bool Platform::set(Type t)
sizeof_wchar_t = sizeof(wchar_t);
sizeof_size_t = sizeof(std::size_t);
sizeof_pointer = sizeof(void *);
if (type == Type::Unspecified) {
defaultSign = '\0';
} else {
defaultSign = std::numeric_limits<char>::is_signed ? 's' : 'u';
}
defaultSign = std::numeric_limits<char>::is_signed ? 's' : 'u';
char_bit = 8;
calculateBitMembers();
return true;
Expand All @@ -73,7 +69,7 @@ bool Platform::set(Type t)
sizeof_wchar_t = 2;
sizeof_size_t = 4;
sizeof_pointer = 4;
defaultSign = '\0';
defaultSign = 's';
char_bit = 8;
calculateBitMembers();
return true;
Expand All @@ -90,7 +86,7 @@ bool Platform::set(Type t)
sizeof_wchar_t = 2;
sizeof_size_t = 8;
sizeof_pointer = 8;
defaultSign = '\0';
defaultSign = 's';
char_bit = 8;
calculateBitMembers();
return true;
Expand All @@ -107,7 +103,7 @@ bool Platform::set(Type t)
sizeof_wchar_t = 4;
sizeof_size_t = 4;
sizeof_pointer = 4;
defaultSign = '\0';
defaultSign = 's';
char_bit = 8;
calculateBitMembers();
return true;
Expand All @@ -124,7 +120,7 @@ bool Platform::set(Type t)
sizeof_wchar_t = 4;
sizeof_size_t = 8;
sizeof_pointer = 8;
defaultSign = '\0';
defaultSign = 's';
char_bit = 8;
calculateBitMembers();
return true;
Expand All @@ -151,7 +147,10 @@ bool Platform::set(const std::string& platformstr, std::string& errstr, const st
else if (platformstr == "native")
set(Type::Native);
else if (platformstr == "unspecified")
{
std::cout << "Platform 'unspecified' is deprecated and will be removed in a future version. It is also now identical to 'native' (i.e. char type signedness based on compiler instead of unknown)." << std::endl;
set(Type::Unspecified);
}
else if (paths.empty()) {
errstr = "unrecognized platform: '" + platformstr + "' (no lookup).";
return false;
Expand Down Expand Up @@ -228,7 +227,8 @@ bool Platform::loadFromFile(const std::vector<std::string>& paths, const std::st
if (err != tinyxml2::XML_SUCCESS)
return false;

return loadFromXmlDocument(&doc);
std::string errmsg; // TODO
return loadFromXmlDocument(&doc, errmsg);
}

static unsigned int xmlTextAsUInt(const tinyxml2::XMLElement* node, bool& error)
Expand All @@ -239,19 +239,30 @@ static unsigned int xmlTextAsUInt(const tinyxml2::XMLElement* node, bool& error)
return retval;
}

bool Platform::loadFromXmlDocument(const tinyxml2::XMLDocument *doc)
bool Platform::loadFromXmlDocument(const tinyxml2::XMLDocument *doc, std::string& errmsg)
{
const tinyxml2::XMLElement * const rootnode = doc->FirstChildElement();

if (!rootnode || std::strcmp(rootnode->Name(), "platform") != 0)
if (!rootnode)
{
errmsg = "no root node found";
return false;
}

bool error = false;
if (std::strcmp(rootnode->Name(), "platform") != 0)
{
errmsg = "invalid root node";
return false;
}

// TODO: improve error reporting
bool res = true;
for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
bool error = false;
const char* name = node->Name();
if (std::strcmp(name, "default-sign") == 0) {
const char* str = node->GetText();
if (str)
if (str && (*str == 'u' || *str == 's'))
defaultSign = *str;
else
error = true;
Expand Down Expand Up @@ -284,10 +295,15 @@ bool Platform::loadFromXmlDocument(const tinyxml2::XMLDocument *doc)
sizeof_wchar_t = xmlTextAsUInt(sz, error);
}
}
if (error)
{
res = false;
errmsg = std::string("'") + name + "' failed";
}
}
calculateBitMembers();
type = Type::File;
return !error;
return res;
}

std::string Platform::getLimitsDefines(bool c99) const
Expand Down
4 changes: 2 additions & 2 deletions lib/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class CPPCHECKLIB Platform {

protected:
/** load platform from xml document, primarily for testing */
bool loadFromXmlDocument(const tinyxml2::XMLDocument *doc);
bool loadFromXmlDocument(const tinyxml2::XMLDocument *doc, std::string& errmsg);
public:
Platform();

Expand Down Expand Up @@ -130,7 +130,7 @@ class CPPCHECKLIB Platform {
std::size_t sizeof_size_t;
std::size_t sizeof_pointer;

char defaultSign; // unsigned:'u', signed:'s', unknown:'\0'
char defaultSign; // unsigned:'u', signed:'s'

enum Type : std::uint8_t {
Unspecified, // No platform specified
Expand Down
6 changes: 2 additions & 4 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,10 @@ SymbolDatabase::SymbolDatabase(Tokenizer& tokenizer)
if (!mTokenizer.tokens())
return;

if (mSettings.platform.defaultSign == 's' || mSettings.platform.defaultSign == 'S')
mDefaultSignedness = ValueType::SIGNED;
else if (mSettings.platform.defaultSign == 'u' || mSettings.platform.defaultSign == 'U')
if (mSettings.platform.defaultSign == 'u')
mDefaultSignedness = ValueType::UNSIGNED;
else
mDefaultSignedness = ValueType::UNKNOWN_SIGN;
mDefaultSignedness = ValueType::SIGNED;

createSymbolDatabaseFindAllScopes();
createSymbolDatabaseClassInfo();
Expand Down
6 changes: 6 additions & 0 deletions releasenotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ GUI:
-

Changed interface:
- The "unspecified" platform has been deprecated and will be removed in a future version. It is also now identical to 'native' (i.e. char type signedness based on compiler instead of unknown).
-

Infrastructure & dependencies:
-

Other:
- The possibility of an unknown signedness of the char type in a platform definition has been removed.
- The built-in "win*" and "unix*" platforms will now default to signed char type instead of unknown signedness. If you require unsigned chars please specify "--funsigned-char"
-
85 changes: 85 additions & 0 deletions test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4119,3 +4119,88 @@ def test_active_unusedfunction_only_misra_builddir(tmp_path):
'CheckUnusedFunctions::check'
]
__test_active_checkers(tmp_path, 1, 1175, use_unusedfunction_only=True, use_misra=True, checkers_exp=checkers_exp)


def test_platform_custom(tmp_path):
test_cfg = tmp_path / 'test.cfg'
with open(test_cfg, 'wt') as f:
f.write("""
<?xml version="1.0"?>
<platform>
<char_bit>8</char_bit>
<default-sign>unsigned</default-sign>
<sizeof>
<bool>1</bool>
<short>2</short>
<int>2</int>
<long>4</long>
<long-long>8</long-long>
<float>4</float>
<double>4</double>
<long-double>4</long-double>
<pointer>2</pointer>
<size_t>2</size_t>
<wchar_t>2</wchar_t>
</sizeof>
</platform>
""")

# TODO: use a sample to make sure the file is actually used
test_file = tmp_path / 'test.c'
with open(test_file, 'wt') as f:
f.write("""""")

args = [
'--platform={}'.format(test_cfg),
str(test_file)
]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0, stdout
lines = stdout.splitlines()
assert lines == [
'Checking {} ...'.format(test_file)
]
assert stderr == ''


def test_platform_invalid_defaultsign(tmp_path):
test_cfg = tmp_path / 'test.cfg'
with open(test_cfg, 'wt') as f:
f.write("""
<?xml version="1.0"?>
<platform>
<char_bit>8</char_bit>
<default-sign>notsigned</default-sign>
<sizeof>
<bool>1</bool>
<short>2</short>
<int>2</int>
<long>4</long>
<long-long>8</long-long>
<float>4</float>
<double>4</double>
<long-double>4</long-double>
<pointer>2</pointer>
<size_t>2</size_t>
<wchar_t>2</wchar_t>
</sizeof>
</platform>
""")

test_file = tmp_path / 'test.c'
with open(test_file, 'wt') as f:
f.write("""""")

args = [
'--platform={}'.format(test_cfg),
str(test_file)
]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0, stdout
lines = stdout.splitlines()
assert lines == [
'Checking {} ...'.format(test_file)
]
assert stderr == ''
10 changes: 0 additions & 10 deletions test/testcmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1799,79 +1799,69 @@ class TestCmdlineParser : public TestFixture {
void platformWin64() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=win64", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(Platform::Type::Win64, settings->platform.type);
}

void platformWin32A() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=win32A", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(Platform::Type::Win32A, settings->platform.type);
}

void platformWin32W() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=win32W", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(Platform::Type::Win32W, settings->platform.type);
}

void platformUnix32() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=unix32", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(Platform::Type::Unix32, settings->platform.type);
}

void platformUnix32Unsigned() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=unix32-unsigned", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv));
ASSERT_EQUALS("cppcheck: error: unrecognized platform: 'unix32-unsigned'.\n", logger->str());
}

void platformUnix64() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=unix64", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(Platform::Type::Unix64, settings->platform.type);
}

void platformUnix64Unsigned() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=unix64-unsigned", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv));
ASSERT_EQUALS("cppcheck: error: unrecognized platform: 'unix64-unsigned'.\n", logger->str());
}

void platformNative() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=native", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(Platform::Type::Native, settings->platform.type);
}

void platformUnspecified() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=unspecified", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Native));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(Platform::Type::Unspecified, settings->platform.type);
}

void platformPlatformFile() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--platform=avr8", "file.cpp"};
ASSERT(settings->platform.set(Platform::Type::Unspecified));
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(Platform::Type::File, settings->platform.type);
}
Expand Down
Loading