diff --git a/syntax_checkers/cpp/check.py b/syntax_checkers/cpp/check.py index 25951ae..60f21f9 100755 --- a/syntax_checkers/cpp/check.py +++ b/syntax_checkers/cpp/check.py @@ -99,32 +99,23 @@ def find_compile_commands_json(source_filename): return None -def get_compile_options(command, filename): - """Return compile options for syntax checking.""" - options = [] +def option(directory): + return lambda x: x.group(0) if x.group(1) != 'I' else '-I' + os.path.join(directory, x.group(2)) - index = 1 - while True: - try: - item = command[index] - except IndexError: - break - index += 1 +def command(input): + import re + return lambda e: re.finditer(e, input) - try: - if os.path.samefile(item, filename): - continue - except OSError: - pass - if item == '-o': - index += 1 - continue +def arguments(input): + return command(' '.join(input)) - options.append(item) - return options +def get_compile_options(entry): + input = arguments(entry['arguments']) if 'arguments' in entry else command(entry['command']) + filter_expr = r'-(W|D|I|include|isystem|isysroot|imacros|std)\s*([^\s]+)|-nostdinc\+{0,2}' + return shlex.split(' '.join(map(option(entry['directory']), input(filter_expr)))) def read_compile_commands_json(source_filename): @@ -153,15 +144,13 @@ def read_compile_commands_json(source_filename): for entry in compile_commands: try: if os.path.samefile(entry['file'], source_filename): - command = entry['command'].split() - return get_compile_options(command, source_filename) + return get_compile_options(entry) except OSError: pass return None - def is_header_file(filename): """Return True if "filename" is a header file. @@ -190,19 +179,15 @@ def check(configuration_filename, command, filename, verbose_file=None): if options is None: return [] - if is_header_file(filename): - # Avoid generating precompiled headers. - options += ['-c', os.devnull] - + # Avoid generating precompiled headers. + options += ['-c', os.devnull] if is_header_file(filename) else ['-c'] full_command = command + ['-fsyntax-only'] + options + [filename] if verbose_file: verbose_file.write(' '.join(full_command) + '\n') - process = subprocess.Popen(command + ['-fsyntax-only'] + - options + [filename], - stderr=subprocess.PIPE) + process = subprocess.Popen(full_command, stderr=subprocess.PIPE) errors = process.communicate()[1] if sys.version_info[0] > 2: diff --git a/test/bear_compile_commands/bad.cpp b/test/bear_compile_commands/bad.cpp new file mode 100644 index 0000000..6e90511 --- /dev/null +++ b/test/bear_compile_commands/bad.cpp @@ -0,0 +1,3 @@ +#include "some_header.h" + +1 / diff --git a/test/bear_compile_commands/build/compile_commands.json b/test/bear_compile_commands/build/compile_commands.json new file mode 100644 index 0000000..f253f6f --- /dev/null +++ b/test/bear_compile_commands/build/compile_commands.json @@ -0,0 +1,36 @@ +[ +{ + "directory": "/Users/myint/projects/perceptualdiff/build", + "arguments": [ + "c++", + "-Werror", + "-DDEFINED", + "-DCONFIG_VALUE=42", + "-isystem", + "test/bear_compile_commands/header_directory", + "-nostdinc++", + "-o", + "ignore_this.o", + "-c", + "test/bear_compile_commands/good.cpp" + ], + "file": "test/bear_compile_commands/good.cpp" +}, +{ + "directory": "/Users/myint/projects/perceptualdiff/build", + "arguments": [ + "c++", + "-Werror", + "-DDEFINED", + "-DCONFIG_VALUE=42", + "-isystem", + "test/bear_compile_commands/header_directory", + "-nostdinc++", + "-o", + "ignore_this.o", + "-c", + "test/bear_compile_commands/bad.cpp" + ], + "file": "test/bear_compile_commands/bad.cpp" +} +] diff --git a/test/bear_compile_commands/good.cpp b/test/bear_compile_commands/good.cpp new file mode 100644 index 0000000..f74b14f --- /dev/null +++ b/test/bear_compile_commands/good.cpp @@ -0,0 +1 @@ +#include "some_header.h" diff --git a/test/bear_compile_commands/header_directory/some_header.h b/test/bear_compile_commands/header_directory/some_header.h new file mode 100644 index 0000000..e69de29 diff --git a/test/compile_commands/build/compile_commands.json b/test/compile_commands/build/compile_commands.json index 9ba8a13..355bd60 100644 --- a/test/compile_commands/build/compile_commands.json +++ b/test/compile_commands/build/compile_commands.json @@ -1,12 +1,12 @@ [ { "directory": "/Users/myint/projects/perceptualdiff/build", - "command": "c++ -isystem test/compile_commands/header_directory -o ignore_this.o -c test/compile_commands/good.cpp", + "command": "c++ -Werror -DDEFINED -DCONFIG_VALUE=42 -isystem test/compile_commands/header_directory -nostdinc++ -o ignore_this.o -c test/compile_commands/good.cpp", "file": "test/compile_commands/good.cpp" }, { "directory": "/Users/myint/projects/perceptualdiff/build", - "command": "c++ -isystem test/compile_commands/header_directory -o ignore_this.o -c test/compile_commands/bad.cpp", + "command": "c++ -Werror -DDEFINED -DCONFIG_VALUE=42 -isystem test/compile_commands/header_directory -nostdinc++ -o ignore_this.o -c test/compile_commands/bad.cpp", "file": "test/compile_commands/bad.cpp" } ] diff --git a/test/test.bash b/test/test.bash index c59c813..043f546 100755 --- a/test/test.bash +++ b/test/test.bash @@ -88,6 +88,10 @@ python ./syntax_checkers/cpp/test.py test/compile_commands/good.cpp python ./syntax_checkers/cpp/test.py test/compile_commands/bad.cpp 2>&1 \ | grep 'test/compile_commands/bad.cpp:3' > /dev/null +python ./syntax_checkers/cpp/test.py test/bear_compile_commands/good.cpp +python ./syntax_checkers/cpp/test.py test/bear_compile_commands/bad.cpp 2>&1 \ + | grep 'test/bear_compile_commands/bad.cpp:3' > /dev/null + # With `CC` or `CXX` composed of multiple arguments. CC='echo hello world' \ "$PYTHON" ./syntax_checkers/cpp/test.py test/syntastic_config/good.c \