diff --git a/tools/compare_ast.py b/tools/compare_ast.py deleted file mode 100644 index ebe9adca0..000000000 --- a/tools/compare_ast.py +++ /dev/null @@ -1,59 +0,0 @@ -# Example usage: -# python3 compare_ast.py lib/token.cpp -# python3 compare_ast.py "--project=compile_commands.json --file-filter=*/lib/somefile.c" - -import glob -import os -import re -import sys -import subprocess - -CPPCHECK = os.path.expanduser('~/cppcheck/cppcheck') - -def run_cppcheck(cppcheck_parameters:str, clang:str): - cmd = f'{CPPCHECK} {cppcheck_parameters} {clang} --debug --verbose' - print(cmd) - p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) - comm = p.communicate() - return comm[0].decode('utf-8', 'ignore') - - -def get_ast(debug): - debug = re.sub(r' f:0x[0-9a-fA-F]+', '', debug) - debug = re.sub(r" '[a-zA-Z0-9: *]+'", '', debug) - - pos1 = debug.rfind('\n##AST\n') - if pos1 < 0: - return '' - pos1 = debug.find('\n', pos1) + 1 - assert pos1 > 0 - pos2 = debug.find("\n##", pos1) - if pos2 < 0: - return debug[pos1:] - return debug[pos1:pos2-1] - - -def compare_ast(cppcheck_parameters: str): - ast1 = get_ast(run_cppcheck(cppcheck_parameters, '')) - ast2 = get_ast(run_cppcheck(cppcheck_parameters, '--clang')) - if ast1 == ast2: - print(f"ast is the same for file {cppcheck_parameters}") - print('ast size:%i' % len(ast1)) - else: - print(f"ast is not the same for file {cppcheck_parameters}") - print('saving cppcheck ast in file ast1 and clang ast in file ast2') - - f = open('ast1', 'wt') - f.write(ast1) - f.close() - - f = open('ast2', 'wt') - f.write(ast2) - f.close() - - sys.exit(1) - - -for arg in sys.argv[1:]: - compare_ast(arg) - diff --git a/tools/compare_ast_symdb.py b/tools/compare_ast_symdb.py new file mode 100644 index 000000000..5712062f4 --- /dev/null +++ b/tools/compare_ast_symdb.py @@ -0,0 +1,102 @@ +# Example usage: +# python3 compare_ast.py lib/token.cpp +# python3 compare_ast.py "--project=compile_commands.json --file-filter=*/lib/somefile.c" +# check all files in a compile_commands.json: +# grep '"file":' compile_commands.json | grep -v test | sed 's|.*/curl/|"--project=compile_commands.json --file-filter=*|' | xargs python3 ~/cppcheck/tools/compare_ast.py + +import glob +import os +import re +import sys +import subprocess + +CPPCHECK = os.path.expanduser('~/cppcheck/cppcheck') + +def run_cppcheck(cppcheck_parameters:str, clang:str): + cmd = f'{CPPCHECK} {cppcheck_parameters} {clang} --debug --verbose' + #print(cmd) + p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) + comm = p.communicate() + return comm[0].decode('utf-8', 'ignore') + + +def get_ast(debug): + debug = re.sub(r' f:0x[0-9a-fA-F]+', '', debug) + debug = re.sub(r" '[a-zA-Z0-9: *]+'", '', debug) + + pos1 = debug.rfind('\n##AST\n') + if pos1 < 0: + return '' + pos1 = debug.find('\n', pos1) + 1 + assert pos1 > 0 + pos2 = debug.find("\n##", pos1) + if pos2 < 0: + return debug[pos1:] + return debug[pos1:pos2-1] + + +def get_symdb(debug): + debug = re.sub(r'0x[0-9a-fA-F]+', '0x12345678', debug) + debug = re.sub(r'nestedIn: Struct', 'nestedIn: Class', debug) + debug = re.sub(r'classDef: struct', 'classDef: class', debug) + debug = re.sub(r'isInline: [a-z]+', 'isInline: ---', debug) + debug = re.sub(r'definedType: .*', 'definedType: ---', debug) + debug = re.sub(r'needInitialization: .*', 'needInitialization: ---', debug) + debug = re.sub(r'functionOf: .*', 'functionOf: ---', debug) + debug = re.sub(r'0x12345678 Struct', '0x12345678 Class', debug) + + pos1 = debug.rfind('\n### Symbol database ###\n') + if pos1 < 0: + return '' + pos1 = debug.find('\n', pos1) + 1 + assert pos1 > 0 + pos2 = debug.find("\n##", pos1) + if pos2 < 0: + return debug[pos1:] + return debug[pos1:pos2-1] + + +def compare_ast_symdb(cppcheck_parameters: str): + same = True + debug1 = run_cppcheck(cppcheck_parameters, '') + debug2 = run_cppcheck(cppcheck_parameters, 'clang') + + ast1 = get_ast(debug1) + ast2 = get_ast(debug2) + if ast1 != ast2: + print(f"ast is not the same: {cppcheck_parameters}") + print('saving file cppcheck.ast and clang.ast') + + f = open('cppcheck.ast', 'wt') + f.write(ast1) + f.close() + + f = open('clang.ast', 'wt') + f.write(ast2) + f.close() + + same = False + + symdb1 = get_symdb(debug1) + symdb2 = get_symdb(debug2) + if symdb1 != symdb2: + print(f"symdb is not the same: {cppcheck_parameters}") + print('saving file cppcheck.symdb and clang.symdb') + + f = open('cppcheck.symdb', 'wt') + f.write(symdb1) + f.close() + + f = open('clang.symdb', 'wt') + f.write(symdb2) + f.close() + + same = False + + if not same: + sys.exit(1) + +for arg in sys.argv[1:]: + print(arg) + compare_ast_symdb(arg) +