diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 924009ed018..de814f05a37 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -1257,14 +1257,17 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a // --std else if (std::strncmp(argv[i], "--std=", 6) == 0) { const std::string std = argv[i] + 6; - // TODO: print error when standard is unknown + bool unknown = false; if (std::strncmp(std.c_str(), "c++", 3) == 0) { - mSettings.standards.cpp = Standards::getCPP(std); + mSettings.standards.cpp = Standards::getCPP(std, unknown); } else if (std::strncmp(std.c_str(), "c", 1) == 0) { - mSettings.standards.c = Standards::getC(std); + mSettings.standards.c = Standards::getC(std, unknown); } else { + unknown = true; + } + if (unknown) { mLogger.printError("unknown --std value '" + std + "'"); return Result::Fail; } diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 336e25744c8..4f3364ae88f 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -268,7 +268,7 @@ static std::string unescape(const std::string &in) return out; } -void ImportProject::fsParseCommand(FileSettings& fs, const std::string& command) +bool ImportProject::fsParseCommand(FileSettings& fs, const std::string& command) { std::string defs; @@ -309,8 +309,23 @@ void ImportProject::fsParseCommand(FileSettings& fs, const std::string& command) if (std::find(fs.includePaths.cbegin(), fs.includePaths.cend(), i) == fs.includePaths.cend()) fs.includePaths.push_back(std::move(i)); } else if (F=='s' && startsWith(fval,"td")) { - ++pos; - fs.standard = readUntil(command, &pos, " "); + if (command[pos] == '=') { + ++pos; + fs.standard = readUntil(command, &pos, " "); + } else { + fs.standard = fval.substr(3); + } + bool unknown_std = false; + (void)Standards::getCPP(fs.standard, unknown_std); + if (unknown_std) (void)Standards::getC(fs.standard, unknown_std); + if (unknown_std) { + const Standards::cppstd_t gnustd = Standards::getGnuCPP(fs.standard, unknown_std); + if (unknown_std) { + printError("unknown --std value '" + fs.standard + "'"); + return false; + } + fs.standard = Standards::getCPP(gnustd); + } } else if (F == 'i' && fval == "system") { ++pos; std::string isystem = readUntil(command, &pos, " "); @@ -339,6 +354,7 @@ void ImportProject::fsParseCommand(FileSettings& fs, const std::string& command) } } fsSetDefines(fs, std::move(defs)); + return true; } bool ImportProject::importCompileCommands(std::istream &istr) @@ -416,7 +432,8 @@ bool ImportProject::importCompileCommands(std::istream &istr) return false; } FileSettings fs{std::move(path)}; - fsParseCommand(fs, command); // read settings; -D, -I, -U, -std, -m*, -f* + // read settings; -D, -I, -U, -std, -m*, -f* + if (!fsParseCommand(fs, command)) return false; std::map variables; fsSetIncludePaths(fs, directory, fs.includePaths, variables); fileSettings.push_back(std::move(fs)); diff --git a/lib/importproject.h b/lib/importproject.h index 7382b56eb8d..c112a0e068a 100644 --- a/lib/importproject.h +++ b/lib/importproject.h @@ -64,7 +64,7 @@ class CPPCHECKLIB WARN_UNUSED ImportProject { CPPCHECK_GUI }; - static void fsParseCommand(FileSettings& fs, const std::string& command); + static bool fsParseCommand(FileSettings& fs, const std::string& command); static void fsSetDefines(FileSettings& fs, std::string defs); static void fsSetIncludePaths(FileSettings& fs, const std::string &basepath, const std::list &in, std::map &variables); diff --git a/lib/standards.h b/lib/standards.h index 4965e432fcd..5563e631791 100644 --- a/lib/standards.h +++ b/lib/standards.h @@ -68,6 +68,11 @@ struct Standards { return ""; } static cstd_t getC(const std::string &std) { + bool _unused; + return getC(std, _unused); + } + static cstd_t getC(const std::string &std, bool &unknown) { + unknown = false; if (std == "c89") { return Standards::C89; } @@ -83,6 +88,7 @@ struct Standards { if (std == "c23") { return Standards::C23; } + unknown = true; return Standards::CLatest; } bool setCPP(std::string str) { @@ -114,6 +120,11 @@ struct Standards { return ""; } static cppstd_t getCPP(const std::string &std) { + bool _unused; + return getCPP(std, _unused); + } + static cppstd_t getCPP(const std::string &std, bool &unknown) { + unknown = false; if (std == "c++03") { return Standards::CPP03; } @@ -135,6 +146,34 @@ struct Standards { if (std == "c++26") { return Standards::CPP26; } + unknown = true; + return Standards::CPPLatest; + } + static cppstd_t getGnuCPP(const std::string &std, bool &unknown) { + // treat gnu++XX as c++XX + unknown = false; + if (std == "gnu++03") { + return Standards::CPP03; + } + if (std == "gnu++11") { + return Standards::CPP11; + } + if (std == "gnu++14") { + return Standards::CPP14; + } + if (std == "gnu++17") { + return Standards::CPP17; + } + if (std == "gnu++20") { + return Standards::CPP20; + } + if (std == "gnu++23") { + return Standards::CPP23; + } + if (std == "gnu++26") { + return Standards::CPP26; + } + unknown = true; return Standards::CPPLatest; } }; diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 46425aa161f..b7c46dd5a6f 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -1369,8 +1369,8 @@ class TestCmdlineParser : public TestFixture { void stdunknown2() { REDIRECT; const char *const argv[] = {"cppcheck", "--std=cplusplus11", "file.cpp"}; - TODO_ASSERT_EQUALS(static_cast(CmdLineParser::Result::Fail), static_cast(CmdLineParser::Result::Success), static_cast(parser->parseFromArgs(3, argv))); - TODO_ASSERT_EQUALS("cppcheck: error: unknown --std value 'cplusplus11'\n", "", logger->str()); + ASSERT_EQUALS(static_cast(CmdLineParser::Result::Fail), static_cast(parser->parseFromArgs(3, argv))); + ASSERT_EQUALS("cppcheck: error: unknown --std value 'cplusplus11'\n", logger->str()); } void platformWin64() {