summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2019-12-20 16:07:58 +0000
committerPhilip Withnall <philip@tecnocode.co.uk>2019-12-20 16:07:58 +0000
commit9cff7877516a42d26ba890e3c42acb24458713f4 (patch)
tree12e7eb30b048cb6f6f501b1acb9cce1923582e63
parent53dfdbe970966966b208a034c91f9fb43bf7596b (diff)
parent3c8c729c4c6d19a44e7b39c49d79dc5aafd7b9b6 (diff)
Merge branch '39-compile-commands-json' into 'master'
Add a script for processing compile_commands.json Closes #39 See merge request tartan/tartan!5
-rw-r--r--Makefile.am1
-rw-r--r--clang-plugin/plugin.cpp21
-rwxr-xr-xscripts/tartan6
-rwxr-xr-xscripts/tartan-json67
4 files changed, 87 insertions, 8 deletions
diff --git a/Makefile.am b/Makefile.am
index 764ca8c..319e3d7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -74,6 +74,7 @@ clang_plugin_libtartan_la_LDFLAGS = \
dist_bin_SCRIPTS = \
scripts/tartan \
scripts/tartan-build \
+ scripts/tartan-json \
$(NULL)
# Code coverage
diff --git a/clang-plugin/plugin.cpp b/clang-plugin/plugin.cpp
index 1a94e0f..5e49c71 100644
--- a/clang-plugin/plugin.cpp
+++ b/clang-plugin/plugin.cpp
@@ -204,15 +204,16 @@ private:
}
while ((typelib_filename = g_dir_read_name (dir)) != NULL) {
- /* Load the typelib. Ignore failure. */
-
- std::string _typelib_filename (typelib_filename);
- std::string::size_type last_dot = _typelib_filename.find_last_of (".");
- if (last_dot == std::string::npos) {
+ if (!g_str_has_suffix (typelib_filename, ".typelib")) {
/* No ‘.typelib’ suffix — ignore. */
continue;
}
+ /* Load the typelib. Ignore failure. */
+ std::string _typelib_filename (typelib_filename);
+ std::string::size_type last_dot = _typelib_filename.find_last_of (".");
+ g_assert (last_dot != std::string::npos);
+
std::string gi_namespace_and_version = _typelib_filename.substr (0, last_dot);
this->_load_typelib (CI, gi_namespace_and_version);
}
@@ -230,9 +231,6 @@ protected:
ParseArgs (const CompilerInstance &CI,
const std::vector<std::string>& args)
{
- /* Load all typelibs. */
- this->_load_gi_repositories (CI);
-
/* Enable the default set of checkers. */
for (std::vector<std::string>::const_iterator it = args.begin();
it != args.end (); ++it) {
@@ -254,9 +252,14 @@ protected:
} else if (arg == "--disable-checker") {
const std::string checker = *(++it);
this->_disabled_checkers.get ()->insert (std::string (checker));
+ } else if (arg == "--typelib-path") {
+ g_irepository_prepend_search_path ((++it)->c_str ());
}
}
+ /* Load all typelibs. */
+ this->_load_gi_repositories (CI);
+
/* Listen to the V environment variable (as standard in automake) too. */
const char *v_value = getenv ("V");
if (v_value != NULL && strcmp (v_value, "0") == 0) {
@@ -308,6 +311,8 @@ protected:
" Disable the given Tartan checker, which may be "
"‘all’. All checkers are\n"
" enabled by default.\n"
+ " --typelib-path [path]\n"
+ " Add the given path to the search path for typelibs.\n"
" --quiet\n"
" Disable all plugin output except code "
"diagnostics (remarks,\n"
diff --git a/scripts/tartan b/scripts/tartan
index 3dcf012..ba6cbcf 100755
--- a/scripts/tartan
+++ b/scripts/tartan
@@ -149,6 +149,12 @@ if [ "$escape_plugin_flags" = "1" ]; then
_add_plugin+=( "-Xanalyzer" "$arg" )
done
add_plugin=( "${_add_plugin[@]}" )
+
+ _plugin_options=()
+ for arg in "${plugin_options[@]}"; do
+ _plugin_options+=( "-Xanalyzer" "$arg" )
+ done
+ plugin_options=( "${_plugin_options[@]}")
fi
if [ "$include_plugin_flags" = "1" ]; then
diff --git a/scripts/tartan-json b/scripts/tartan-json
new file mode 100755
index 0000000..560413a
--- /dev/null
+++ b/scripts/tartan-json
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+# coding: utf8
+#
+# This file is part of Tartan.
+# Copyright © 2019 Philip Chimento
+#
+# Tartan is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Tartan is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Tartan. If not, see <http://www.gnu.org/licenses/>.
+
+# Use this script to analyze a whole project by passing it the compilation
+# database file generated by Meson or CMake. An example with Meson would be:
+#
+# $ meson _build
+# $ tartan-json _build/compile_commands.json
+
+import argparse
+import json
+import os
+import shlex
+import subprocess
+import sys
+
+parser = argparse.ArgumentParser(
+ description='''Run the Tartan analyzer on a whole compilation database, in
+the compile_commands.json format such as generated by Meson or CMake.''')
+parser.add_argument('json', type=argparse.FileType('r'), metavar='FILE',
+ help='path to compile_commands.json')
+parser.add_argument('-q', '--quiet', action='store_true',
+ help="don't print progress messages")
+parser.add_argument('tartan_options', nargs=argparse.REMAINDER, metavar='...',
+ help='extra options to pass on to Tartan')
+
+args = parser.parse_args()
+
+compile_db = json.load(args.json)
+had_error = False
+
+for index, entry in enumerate(compile_db):
+ if not args.quiet:
+ full_path = os.path.normpath(os.path.join(entry['directory'],
+ entry['file']))
+ print('[{}/{}] Processing {}'.format(index + 1, len(compile_db),
+ full_path))
+
+ new_env = dict(os.environ)
+ existing_tartan_options = new_env.get('TARTAN_OPTIONS', '')
+ new_env['TARTAN_OPTIONS'] = (existing_tartan_options + ' ' +
+ ' '.join(args.tartan_options))
+ # -Wno-unused-command-line-argument is because linker arguments will be
+ # ignored and produce a warning with --analyze.
+ invocation = (['tartan', '--analyze', '-Wno-unused-command-line-argument']
+ + shlex.split(entry['command']))
+ result = subprocess.run(invocation, cwd=entry['directory'], env=new_env)
+ if result.returncode != 0:
+ had_error = True
+
+sys.exit(1 if had_error else 0)