From 7e752c190157f7916873b260186bd0e6eeb8839d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 4 Mar 2019 18:21:53 -0800 Subject: [PATCH] Make clang.excludeArgs accept glob patterns --- src/config.hh | 5 ++--- src/project.cc | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/config.hh b/src/config.hh index 9ce0cc1b..ac3a5baa 100644 --- a/src/config.hh +++ b/src/config.hh @@ -96,9 +96,8 @@ struct Config { } capabilities; struct Clang { - // Arguments that should be excluded, e.g. ["-fopenmp", "-Wall"] - // - // e.g. If your project is built by GCC and has an option thag clang does not understand. + // Arguments matching any of these glob patterns will be excluded, e.g. + // ["-fopenmp", "-m*", "-Wall"]. std::vector excludeArgs; // Additional arguments to pass to clang. diff --git a/src/project.cc b/src/project.cc index 717f81c6..d62f71dd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -30,6 +30,7 @@ limitations under the License. #include #include #include +#include #include #include @@ -81,10 +82,22 @@ enum OptionClass { struct ProjectProcessor { Project::Folder &folder; std::unordered_set command_set; - StringSet<> excludeArgs; + StringSet<> exclude_args; + std::vector exclude_globs; + ProjectProcessor(Project::Folder &folder) : folder(folder) { for (auto &arg : g_config->clang.excludeArgs) - excludeArgs.insert(arg); + if (arg.find_first_of("?*[") == std::string::npos) + exclude_args.insert(arg); + else if (Expected glob_or_err = GlobPattern::create(arg)) + exclude_globs.push_back(std::move(*glob_or_err)); + else + LOG_S(WARNING) << toString(glob_or_err.takeError()); + } + + bool ExcludesArg(StringRef arg) { + return exclude_args.count(arg) || any_of(exclude_globs, + [&](const GlobPattern &glob) { return glob.match(arg); }); } // Expand %c %cpp ... in .ccls @@ -115,7 +128,7 @@ struct ProjectProcessor { } if (ok) args.push_back(A.data()); - } else if (!excludeArgs.count(A)) { + } else if (!ExcludesArg(A)) { args.push_back(arg); } } @@ -396,7 +409,7 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { entry.args.reserve(args.size()); for (std::string &arg : args) { DoPathMapping(arg); - if (!proc.excludeArgs.count(arg)) + if (!proc.ExcludesArg(arg)) entry.args.push_back(Intern(arg)); } entry.compdb_size = entry.args.size();