add -W<warning>/-Werror CLI options
-Weverything: enable all diagnotics
-Wfoo: enable "foo"
-Wno-foo: disable "foo"
-Werror: turn diagnostic warnings into errors
-Wno-error=foo: turn "foo" into a warning
For now, only -Winterface-name is available, which checks if interface
names start with "I".
Bug: 168028537
Test: aidl_unittests
Change-Id: I31516b337dd80b9833205bf769af40e49f88d15d
diff --git a/options.cpp b/options.cpp
index 601a06b..8ffdb04 100644
--- a/options.cpp
+++ b/options.cpp
@@ -124,6 +124,19 @@
<< " --log" << endl
<< " Information about the transaction, e.g., method name, argument" << endl
<< " values, execution time, etc., is provided via callback." << endl
+ << " -Werror" << endl
+ << " Turn warnings into errors." << endl
+ << " -Wno-error=<warning>" << endl
+ << " Turn the specified warning into a warning even if -Werror is specified."
+ << endl
+ << " -W<warning>" << endl
+ << " Enable the specified warning." << endl
+ << " -Wno-<warning>" << endl
+ << " Disable the specified warning." << endl
+ << " -w" << endl
+ << " Disable all diagnostics. -w wins -Weverything" << endl
+ << " -Weverything" << endl
+ << " Enable all diagnostics." << endl
<< " --help" << endl
<< " Show this help." << endl
<< endl
@@ -188,8 +201,12 @@
return Options(argc, argv, lang);
}
-Options::Options(int argc, const char* const argv[], Options::Language default_lang)
- : myname_(argv[0]), language_(default_lang) {
+Options::Options(int argc, const char* const raw_argv[], Options::Language default_lang)
+ : myname_(raw_argv[0]), language_(default_lang) {
+ std::vector<const char*> argv = warning_options_.Parse(argc, raw_argv, error_message_);
+ if (!Ok()) return;
+ argc = argv.size();
+
bool lang_option_found = false;
optind = 0;
while (true) {
@@ -218,7 +235,7 @@
{"help", no_argument, 0, 'e'},
{0, 0, 0, 0},
};
- const int c = getopt_long(argc, const_cast<char* const*>(argv),
+ const int c = getopt_long(argc, const_cast<char* const*>(argv.data()),
"I:m:p:d:o:h:abtv:", long_options, nullptr);
if (c == -1) {
// no more options
@@ -505,5 +522,62 @@
output_header_dir_);
}
+std::vector<const char*> WarningOptions::Parse(int argc, const char* const raw_argv[],
+ ErrorMessage& error_message) {
+ std::vector<const char*> remains;
+ for (int i = 0; i < argc; i++) {
+ auto arg = raw_argv[i];
+ if (strcmp(arg, "-Weverything") == 0) {
+ enable_all_ = true;
+ } else if (strcmp(arg, "-Werror") == 0) {
+ as_errors_ = true;
+ } else if (strcmp(arg, "-w") == 0) {
+ disable_all_ = true;
+ } else if (base::StartsWith(arg, "-Wno-error=")) {
+ no_errors_.insert(arg + strlen("-Wno-error="));
+ } else if (base::StartsWith(arg, "-Wno-")) {
+ disabled_.insert(arg + strlen("-Wno-"));
+ } else if (base::StartsWith(arg, "-W")) {
+ enabled_.insert(arg + strlen("-W"));
+ } else {
+ remains.push_back(arg);
+ }
+ }
+
+ for (const auto& names : {no_errors_, disabled_, enabled_}) {
+ for (const auto& name : names) {
+ if (kAllDiagnostics.count(name) == 0) {
+ error_message << "unknown warning: " << name << "\n";
+ return {};
+ }
+ }
+ }
+
+ for (const auto& [_, d] : kAllDiagnostics) {
+ bool enabled = d.default_enabled;
+ if (enable_all_ || enabled_.find(d.name) != enabled_.end()) {
+ enabled = true;
+ }
+ if (disable_all_ || disabled_.find(d.name) != disabled_.end()) {
+ enabled = false;
+ }
+
+ DiagnosticSeverity severity = DiagnosticSeverity::DISABLED;
+ if (enabled) {
+ severity = DiagnosticSeverity::WARNING;
+ if (as_errors_ && no_errors_.find(d.name) == no_errors_.end()) {
+ severity = DiagnosticSeverity::ERROR;
+ }
+ }
+ mapping_.emplace(d.id, Mapping{d.name, severity});
+ }
+
+ return remains;
+}
+
+DiagnosticSeverity WarningOptions::Severity(DiagnosticID id) const {
+ return mapping_.at(id).severity;
+}
+
} // namespace aidl
} // namespace android