Skip to content

Commit a4fdfe9

Browse files
authored
fixed #9992 - output --debug --xml completely in XML format (#7281)
1 parent 2d9f673 commit a4fdfe9

File tree

5 files changed

+186
-4
lines changed

5 files changed

+186
-4
lines changed

Diff for: lib/templatesimplifier.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3836,7 +3836,7 @@ void TemplateSimplifier::simplifyTemplates(const std::time_t maxtime)
38363836

38373837
if (mSettings.debugtemplate && mSettings.debugnormal) {
38383838
std::string title("Template Simplifier pass " + std::to_string(passCount + 1));
3839-
mTokenList.front()->printOut(std::cout, title.c_str(), mTokenList.getFiles());
3839+
mTokenList.front()->printOut(std::cout, false, title.c_str(), mTokenList.getFiles());
38403840
}
38413841

38423842
// Copy default argument values from forward declaration to declaration

Diff for: lib/token.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -1203,11 +1203,21 @@ void Token::printOut(std::ostream& out, const char *title) const
12031203
out << stringifyList(stringifyOptions::forPrintOut(), nullptr, nullptr) << std::endl;
12041204
}
12051205

1206-
void Token::printOut(std::ostream& out, const char *title, const std::vector<std::string> &fileNames) const
1206+
void Token::printOut(std::ostream& out, bool xml, const char *title, const std::vector<std::string> &fileNames) const
12071207
{
1208+
if (xml)
1209+
{
1210+
out << "<file>" << std::endl;
1211+
out << "<![CDATA[";
1212+
}
12081213
if (title && title[0])
12091214
out << "\n### " << title << " ###\n";
12101215
out << stringifyList(stringifyOptions::forPrintOut(), &fileNames, nullptr) << std::endl;
1216+
if (xml)
1217+
{
1218+
out << "]]>" << std::endl;
1219+
out << "</file>" << std::endl;
1220+
}
12111221
}
12121222

12131223
// cppcheck-suppress unusedFunction - used for debugging

Diff for: lib/token.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -992,12 +992,13 @@ class CPPCHECKLIB Token {
992992

993993
/**
994994
* For debugging purposes, prints token and all tokens followed by it.
995+
* @param xml print in XML format
995996
* @param title Title for the printout or use default parameter or 0
996997
* for no title.
997998
* @param fileNames Prints out file name instead of file index.
998999
* File index should match the index of the string in this vector.
9991000
*/
1000-
void printOut(std::ostream& out, const char *title, const std::vector<std::string> &fileNames) const;
1001+
void printOut(std::ostream& out, bool xml, const char *title, const std::vector<std::string> &fileNames) const;
10011002

10021003
/**
10031004
* print out tokens - used for debugging

Diff for: lib/tokenize.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -5930,10 +5930,14 @@ void Tokenizer::printDebugOutput(int simplification, std::ostream &out) const
59305930
(simplification != 2U && mSettings.debugnormal);
59315931

59325932
if (debug && list.front()) {
5933-
list.front()->printOut(out, nullptr, list.getFiles());
5933+
if (!mSettings.xml)
5934+
list.front()->printOut(out, mSettings.xml, nullptr, list.getFiles());
59345935

59355936
if (mSettings.xml)
5937+
{
59365938
out << "<debug>" << std::endl;
5939+
list.front()->printOut(out, mSettings.xml, nullptr, list.getFiles());
5940+
}
59375941

59385942
if (mSymbolDatabase) {
59395943
if (mSettings.xml)

Diff for: test/cli/other_test.py

+167
Original file line numberDiff line numberDiff line change
@@ -2869,3 +2869,170 @@ def test_ctu_builddir(tmp_path): # #11883
28692869
assert stderr.splitlines() == [
28702870
'{}:2:19: error: Null pointer dereference: p [ctunullpointer]'.format(test_file)
28712871
]
2872+
2873+
2874+
def test_debug(tmp_path):
2875+
test_file = tmp_path / 'test.c'
2876+
with open(test_file, "w") as f:
2877+
f.write(
2878+
"""void f
2879+
{
2880+
(void)*((int*)0);
2881+
}
2882+
""")
2883+
2884+
args = [
2885+
'-q',
2886+
'--debug',
2887+
str(test_file)
2888+
]
2889+
2890+
exitcode, stdout, stderr = cppcheck(args)
2891+
assert exitcode == 0, stdout
2892+
assert stdout.find('##file ') != -1
2893+
assert stdout.find('##Value flow') != -1
2894+
assert stdout.find('### Symbol database ###') == -1
2895+
assert stdout.find('##AST') == -1
2896+
assert stdout.find('### Template Simplifier pass ') == -1
2897+
assert stderr.splitlines() == []
2898+
2899+
2900+
def test_debug_xml(tmp_path):
2901+
test_file = tmp_path / 'test.c'
2902+
with open(test_file, "w") as f:
2903+
f.write(
2904+
"""void f
2905+
{
2906+
(void)*((int*)0);
2907+
}
2908+
""")
2909+
2910+
args = [
2911+
'-q',
2912+
'--debug',
2913+
'--xml',
2914+
str(test_file)
2915+
]
2916+
2917+
exitcode, stdout, stderr = cppcheck(args)
2918+
assert exitcode == 0, stdout
2919+
2920+
assert stderr
2921+
assert ElementTree.fromstring(stderr) is not None
2922+
2923+
assert stdout.find('##file ') != -1 # also exists in CDATA
2924+
assert stdout.find('##Value flow') == -1
2925+
assert stdout.find('### Symbol database ###') == -1
2926+
assert stdout.find('##AST') == -1
2927+
assert stdout.find('### Template Simplifier pass ') == -1
2928+
2929+
debug_xml = ElementTree.fromstring(stdout)
2930+
assert debug_xml is not None
2931+
assert debug_xml.tag == 'debug'
2932+
file_elem = debug_xml.findall('file')
2933+
assert len(file_elem) == 1
2934+
valueflow_elem = debug_xml.findall('valueflow')
2935+
assert len(valueflow_elem) == 1
2936+
scopes_elem = debug_xml.findall('scopes')
2937+
assert len(scopes_elem) == 1
2938+
ast_elem = debug_xml.findall('ast')
2939+
assert len(ast_elem) == 0
2940+
2941+
2942+
def test_debug_verbose(tmp_path):
2943+
test_file = tmp_path / 'test.c'
2944+
with open(test_file, "w") as f:
2945+
f.write(
2946+
"""void f
2947+
{
2948+
(void)*((int*)0);
2949+
}
2950+
""")
2951+
2952+
args = [
2953+
'-q',
2954+
'--debug',
2955+
'--verbose',
2956+
str(test_file)
2957+
]
2958+
2959+
exitcode, stdout, stderr = cppcheck(args)
2960+
assert exitcode == 0, stdout
2961+
assert stdout.find('##file ') != -1
2962+
assert stdout.find('##Value flow') != -1
2963+
assert stdout.find('### Symbol database ###') != -1
2964+
assert stdout.find('##AST') != -1
2965+
assert stdout.find('### Template Simplifier pass ') == -1
2966+
assert stderr.splitlines() == []
2967+
2968+
2969+
def test_debug_verbose_xml(tmp_path):
2970+
test_file = tmp_path / 'test.c'
2971+
with open(test_file, "w") as f:
2972+
f.write(
2973+
"""void f
2974+
{
2975+
(void)*((int*)0);
2976+
}
2977+
""")
2978+
2979+
args = [
2980+
'-q',
2981+
'--debug',
2982+
'--verbose',
2983+
'--xml',
2984+
str(test_file)
2985+
]
2986+
2987+
exitcode, stdout, stderr = cppcheck(args)
2988+
assert exitcode == 0, stdout
2989+
2990+
assert stderr
2991+
assert ElementTree.fromstring(stderr) is not None
2992+
2993+
assert stdout.find('##file ') != -1 # also exists in CDATA
2994+
assert stdout.find('##Value flow') == -1
2995+
assert stdout.find('### Symbol database ###') == -1
2996+
assert stdout.find('##AST') == -1
2997+
assert stdout.find('### Template Simplifier pass ') == -1
2998+
2999+
debug_xml = ElementTree.fromstring(stdout)
3000+
assert debug_xml is not None
3001+
assert debug_xml.tag == 'debug'
3002+
file_elem = debug_xml.findall('file')
3003+
assert len(file_elem) == 1
3004+
valueflow_elem = debug_xml.findall('valueflow')
3005+
assert len(valueflow_elem) == 1
3006+
scopes_elem = debug_xml.findall('scopes')
3007+
assert len(scopes_elem) == 1
3008+
ast_elem = debug_xml.findall('ast')
3009+
assert len(ast_elem) == 1
3010+
3011+
3012+
# TODO: test with --xml
3013+
def test_debug_template(tmp_path):
3014+
test_file = tmp_path / 'test.cpp'
3015+
with open(test_file, "w") as f:
3016+
f.write(
3017+
"""template<class T> class TemplCl;
3018+
void f
3019+
{
3020+
(void)*((int*)0);
3021+
}
3022+
""")
3023+
3024+
args = [
3025+
'-q',
3026+
'--debug', # TODO: remove depdency on this
3027+
'--debug-template',
3028+
str(test_file)
3029+
]
3030+
3031+
exitcode, stdout, stderr = cppcheck(args)
3032+
assert exitcode == 0, stdout
3033+
assert stdout.find('##file ') != -1
3034+
assert stdout.find('##Value flow') != -1
3035+
assert stdout.find('### Symbol database ###') == -1
3036+
assert stdout.find('##AST') == -1
3037+
assert stdout.find('### Template Simplifier pass ') != -1
3038+
assert stderr.splitlines() == []

0 commit comments

Comments
 (0)