Skip to content

refs #13618 - cleaned up --debug handling and dependencies #7592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
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
13 changes: 11 additions & 2 deletions cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a

bool def = false;
bool maxconfigs = false;
bool debug = false;

ImportProject::Type projectType = ImportProject::Type::NONE;
ImportProject project;
Expand Down Expand Up @@ -636,7 +637,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
// Show --debug output after the first simplifications
else if (std::strcmp(argv[i], "--debug") == 0 ||
std::strcmp(argv[i], "--debug-normal") == 0)
mSettings.debugnormal = true;
debug = true;

// Show debug warnings for lookup for configuration files
else if (std::strcmp(argv[i], "--debug-lookup") == 0)
Expand Down Expand Up @@ -1591,10 +1592,18 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a

if (mSettings.force)
mSettings.maxConfigs = INT_MAX;

else if ((def || mSettings.preprocessOnly) && !maxconfigs)
mSettings.maxConfigs = 1U;

if (debug) {
mSettings.debugnormal = true;
mSettings.debugvalueflow = true;
if (mSettings.verbose) {
mSettings.debugast = true;
mSettings.debugsymdb = true;
}
}

if (mSettings.jobs > 1 && mSettings.buildDir.empty()) {
// TODO: bail out instead?
if (mSettings.checks.isEnabled(Checks::unusedFunction))
Expand Down
6 changes: 2 additions & 4 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,7 @@ static void astStringXml(const Token *tok, nonneg int indent, std::ostream &out)
}
}

void Token::printAst(bool verbose, bool xml, const std::vector<std::string> &fileNames, std::ostream &out) const
void Token::printAst(bool xml, const std::vector<std::string> &fileNames, std::ostream &out) const
{
if (!xml)
out << "\n\n##AST" << std::endl;
Expand All @@ -1672,10 +1672,8 @@ void Token::printAst(bool verbose, bool xml, const std::vector<std::string> &fil
<< "\" column=\"" << tok->column() << "\">" << std::endl;
astStringXml(tok, 2U, out);
out << "</ast>" << std::endl;
} else if (verbose)
} else
out << "[" << fileNames[tok->fileIndex()] << ":" << tok->linenr() << "]" << std::endl << tok->astStringVerbose() << std::endl;
else
out << tok->astString(" ") << std::endl;
if (tok->str() == "(")
tok = tok->link();
}
Expand Down
3 changes: 2 additions & 1 deletion lib/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -1544,6 +1544,7 @@ class CPPCHECKLIB Token {
mImpl->mValues = nullptr;
}

// cppcheck-suppress unusedFunction - used in tests only
std::string astString(const char *sep = "") const {
std::string ret;
if (mImpl->mAstOperand1)
Expand All @@ -1559,7 +1560,7 @@ class CPPCHECKLIB Token {

std::string expressionString() const;

void printAst(bool verbose, bool xml, const std::vector<std::string> &fileNames, std::ostream &out) const;
void printAst(bool xml, const std::vector<std::string> &fileNames, std::ostream &out) const;

void printValueFlow(const std::vector<std::string>& files, bool xml, std::ostream &out) const;

Expand Down
9 changes: 4 additions & 5 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5941,7 +5941,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
}
//---------------------------------------------------------------------------

// TODO: do not depend on --verbose
void Tokenizer::printDebugOutput(std::ostream &out) const
{
if (!list.front())
Expand All @@ -5962,14 +5961,14 @@ void Tokenizer::printDebugOutput(std::ostream &out) const
if (mSymbolDatabase) {
if (xml)
mSymbolDatabase->printXml(out);
else if (mSettings.debugsymdb || (mSettings.debugnormal && mSettings.verbose))
else if (mSettings.debugsymdb)
mSymbolDatabase->printOut("Symbol database");
}

if (mSettings.debugast || (mSettings.debugnormal && mSettings.verbose))
list.front()->printAst(mSettings.verbose, xml, list.getFiles(), out);
if (mSettings.debugast)
list.front()->printAst(xml, list.getFiles(), out);

if (mSettings.debugnormal || mSettings.debugvalueflow)
if (mSettings.debugvalueflow)
list.front()->printValueFlow(list.getFiles(), xml, out);

if (xml)
Expand Down
45 changes: 36 additions & 9 deletions test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2701,8 +2701,9 @@ def test_debug_verbose_xml(tmp_path):
assert len(ast_elem) == 1


# TODO: remove interaction with --debug?
# TODO: test with --xml
def __test_debug_template(tmp_path, verbose):
def __test_debug_template(tmp_path, verbose=False, debug=False):
test_file = tmp_path / 'test.cpp'
with open(test_file, "w") as f:
f.write(
Expand All @@ -2722,27 +2723,54 @@ def __test_debug_template(tmp_path, verbose):

if verbose:
args += ['--verbose']
if debug:
args += ['--debug']

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0, stdout
assert stdout.find('##file ') == -1
assert stdout.find('##Value flow') == -1
assert stdout.find('### Symbol database ###') == -1
assert stdout.find('##AST') == -1
assert stdout.find('### Template Simplifier pass ') != -1
if debug:
assert stdout.find('##file ') != -1
else:
assert stdout.find('##file ') == -1
if debug:
assert stdout.find('##Value flow') != -1
else:
assert stdout.find('##Value flow') == -1
if debug and verbose:
assert stdout.find('### Symbol database ###') != -1
else:
assert stdout.find('### Symbol database ###') == -1
if debug and verbose:
assert stdout.find('##AST') != -1
else:
assert stdout.find('##AST') == -1
if debug:
assert stdout.count('### Template Simplifier pass ') == 2
else:
assert stdout.count('### Template Simplifier pass ') == 1
assert stderr.splitlines() == [
'{}:4:13: error: Null pointer dereference: (int*)nullptr [nullPointer]'.format(test_file)
]
return stdout


def test_debug_template(tmp_path):
__test_debug_template(tmp_path, False)
__test_debug_template(tmp_path, verbose=False)


def test_debug_template_verbose_nodiff(tmp_path):
# make sure --verbose does not change the output
assert __test_debug_template(tmp_path, False) == __test_debug_template(tmp_path, True)
assert __test_debug_template(tmp_path, verbose=False) == __test_debug_template(tmp_path, verbose=True)


def test_debug_template_debug(tmp_path):
__test_debug_template(tmp_path, debug=True)


@pytest.mark.xfail(strict=True) # TODO: remove dependency on --verbose
def test_debug_template_debug_verbose_nodiff(tmp_path):
# make sure --verbose does not change the output
assert __test_debug_template(tmp_path, debug=True, verbose=False) == __test_debug_template(tmp_path, debug=True, verbose=True)


def test_file_ignore_2(tmp_path): # #13570
Expand Down Expand Up @@ -3467,7 +3495,6 @@ def test_debug_ast(tmp_path):
__test_debug_ast(tmp_path, False)


@pytest.mark.xfail(strict=True) # TODO: remove dependency on --verbose
def test_debug_ast_verbose_nodiff(tmp_path):
# make sure --verbose does not change the output
assert __test_debug_ast(tmp_path, False) == __test_debug_ast(tmp_path, True)
Expand Down
48 changes: 48 additions & 0 deletions test/testcmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,10 @@ class TestCmdlineParser : public TestFixture {
TEST_CASE(debugSymdb);
TEST_CASE(debugAst);
TEST_CASE(debugValueflow);
TEST_CASE(debugNormal);
TEST_CASE(debugNormalVerbose);
TEST_CASE(debug);
TEST_CASE(debugVerbose);

TEST_CASE(ignorepaths1);
TEST_CASE(ignorepaths2);
Expand Down Expand Up @@ -3179,6 +3183,50 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS(true, settings->debugvalueflow);
}

void debugNormal() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--debug-normal", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(true, settings->debugnormal);
ASSERT_EQUALS(false, settings->debugSimplified);
ASSERT_EQUALS(true, settings->debugvalueflow);
ASSERT_EQUALS(false, settings->debugast);
ASSERT_EQUALS(false, settings->debugsymdb);
}

void debugNormalVerbose() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--debug-normal", "--verbose", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(true, settings->debugnormal);
ASSERT_EQUALS(false, settings->debugSimplified);
ASSERT_EQUALS(true, settings->debugvalueflow);
ASSERT_EQUALS(true, settings->debugast);
ASSERT_EQUALS(true, settings->debugsymdb);
}

void debug() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--debug", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(true, settings->debugnormal);
ASSERT_EQUALS(false, settings->debugSimplified);
ASSERT_EQUALS(true, settings->debugvalueflow);
ASSERT_EQUALS(false, settings->debugast);
ASSERT_EQUALS(false, settings->debugsymdb);
}

void debugVerbose() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--debug", "--verbose", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
ASSERT_EQUALS(true, settings->debugnormal);
ASSERT_EQUALS(false, settings->debugSimplified);
ASSERT_EQUALS(true, settings->debugvalueflow);
ASSERT_EQUALS(true, settings->debugast);
ASSERT_EQUALS(true, settings->debugsymdb);
}

void ignorepaths1() {
REDIRECT;
const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"};
Expand Down
Loading