[aapt2] Allow --flag=value command line options

+ fix a wrong return value for a missing argument

Flag: EXEMPT tiny tool feature
Test: unit tests
Change-Id: I845f673081ec3b3c395bbe0355ced07fa45a5586
diff --git a/tools/aapt2/cmd/Command.cpp b/tools/aapt2/cmd/Command.cpp
index 514651e..449d93d 100644
--- a/tools/aapt2/cmd/Command.cpp
+++ b/tools/aapt2/cmd/Command.cpp
@@ -213,15 +213,28 @@
 
     bool match = false;
     for (Flag& flag : flags_) {
-      if (arg == flag.name) {
+      // Allow both "--arg value" and "--arg=value" syntax.
+      if (arg.starts_with(flag.name) &&
+          (arg.size() == flag.name.size() || (flag.num_args > 0 && arg[flag.name.size()] == '='))) {
         if (flag.num_args > 0) {
-          i++;
-          if (i >= args.size()) {
-            *out_error << flag.name << " missing argument.\n\n";
-            Usage(out_error);
-            return false;
+          if (arg.size() == flag.name.size()) {
+            i++;
+            if (i >= args.size()) {
+              *out_error << flag.name << " missing argument.\n\n";
+              Usage(out_error);
+              return 1;
+            }
+            arg = args[i];
+          } else {
+            arg.remove_prefix(flag.name.size() + 1);
+            // Disallow empty arguments after '='.
+            if (arg.empty()) {
+              *out_error << flag.name << " has empty argument.\n\n";
+              Usage(out_error);
+              return 1;
+            }
           }
-          flag.action(args[i]);
+          flag.action(arg);
         } else {
           flag.action({});
         }
diff --git a/tools/aapt2/cmd/Command_test.cpp b/tools/aapt2/cmd/Command_test.cpp
index 7aa1aa01..20d87e0 100644
--- a/tools/aapt2/cmd/Command_test.cpp
+++ b/tools/aapt2/cmd/Command_test.cpp
@@ -19,6 +19,7 @@
 #include "test/Test.h"
 
 using ::testing::Eq;
+using namespace std::literals;
 
 namespace aapt {
 
@@ -94,4 +95,27 @@
 }
 #endif
 
+TEST(CommandTest, OptionsWithValues) {
+  TestCommand command;
+  std::string flag;
+  command.AddRequiredFlag("--flag", "", &flag);
+
+  ASSERT_EQ(0, command.Execute({"--flag"s, "1"s}, &std::cerr));
+  EXPECT_STREQ("1", flag.c_str());
+
+  ASSERT_EQ(0, command.Execute({"--flag=1"s}, &std::cerr));
+  EXPECT_STREQ("1", flag.c_str());
+
+  ASSERT_EQ(0, command.Execute({"--flag"s, "=2"s}, &std::cerr));
+  EXPECT_STREQ("=2", flag.c_str());
+
+  ASSERT_EQ(0, command.Execute({"--flag"s, "--flag"s}, &std::cerr));
+  EXPECT_STREQ("--flag", flag.c_str());
+
+  EXPECT_NE(0, command.Execute({"--flag"s}, &std::cerr));
+  EXPECT_NE(0, command.Execute({"--flag="s}, &std::cerr));
+  EXPECT_NE(0, command.Execute({"--flag1=2"s}, &std::cerr));
+  EXPECT_NE(0, command.Execute({"--flag1"s, "2"s}, &std::cerr));
+}
+
 }  // namespace aapt
\ No newline at end of file