Allow --gtest_print_time without a value.

Small clean up of other unit tests.

Test: Ran new unit tests.
Change-Id: If7b871f742c73236e276a8c411bc61754dd6e5a0
diff --git a/Options.cpp b/Options.cpp
index 4b203af..59acb48 100644
--- a/Options.cpp
+++ b/Options.cpp
@@ -41,25 +41,25 @@
 constexpr uint64_t kDefaultSlowThresholdMs = 2000;
 
 const std::unordered_map<std::string, Options::ArgInfo> Options::kArgs = {
-    {"deadline_threshold_ms", {FLAG_TAKES_VALUE, &Options::SetThreshold}},
-    {"slow_threshold_ms", {FLAG_TAKES_VALUE, &Options::SetThreshold}},
+    {"deadline_threshold_ms", {FLAG_REQUIRES_VALUE, &Options::SetThreshold}},
+    {"slow_threshold_ms", {FLAG_REQUIRES_VALUE, &Options::SetThreshold}},
     {"gtest_format", {FLAG_NONE, &Options::SetBool}},
     {"gtest_list_tests", {FLAG_NONE, &Options::SetBool}},
-    {"gtest_filter", {FLAG_ENVIRONMENT_VARIABLE | FLAG_TAKES_VALUE, &Options::SetString}},
+    {"gtest_filter", {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE, &Options::SetString}},
     {
         "gtest_repeat",
-        {FLAG_ENVIRONMENT_VARIABLE | FLAG_TAKES_VALUE, &Options::SetIterations},
+        {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE, &Options::SetIterations},
     },
-    {"gtest_output", {FLAG_ENVIRONMENT_VARIABLE | FLAG_TAKES_VALUE, &Options::SetXmlFile}},
-    {"gtest_print_time", {FLAG_ENVIRONMENT_VARIABLE | FLAG_TAKES_VALUE, &Options::SetPrintTime}},
+    {"gtest_output", {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE, &Options::SetXmlFile}},
+    {"gtest_print_time", {FLAG_ENVIRONMENT_VARIABLE | FLAG_OPTIONAL_VALUE, &Options::SetPrintTime}},
     {
         "gtest_also_run_disabled_tests",
         {FLAG_ENVIRONMENT_VARIABLE | FLAG_CHILD, &Options::SetBool},
     },
     {"gtest_color",
-     {FLAG_ENVIRONMENT_VARIABLE | FLAG_TAKES_VALUE | FLAG_CHILD, &Options::SetString}},
+     {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE | FLAG_CHILD, &Options::SetString}},
     {"gtest_death_test_style",
-     {FLAG_ENVIRONMENT_VARIABLE | FLAG_TAKES_VALUE | FLAG_CHILD, nullptr}},
+     {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE | FLAG_CHILD, nullptr}},
     {"gtest_break_on_failure", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
     {"gtest_catch_exceptions", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
     {"gtest_random_seed", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
@@ -96,7 +96,7 @@
 }
 
 bool Options::SetPrintTime(const std::string&, const std::string& value, bool) {
-  if (strtol(value.c_str(), nullptr, 10) == 0) {
+  if (!value.empty() && strtol(value.c_str(), nullptr, 10) == 0) {
     bools_.find("gtest_print_time")->second = false;
   }
   return true;
@@ -171,7 +171,7 @@
   }
 
   if (info.flags & FLAG_TAKES_VALUE) {
-    if (value.empty()) {
+    if ((info.flags & FLAG_REQUIRES_VALUE) && value.empty()) {
       PrintError(arg, "requires an argument.", from_env);
       return false;
     }
diff --git a/Options.h b/Options.h
index 8a57eef..042ecf4 100644
--- a/Options.h
+++ b/Options.h
@@ -62,8 +62,10 @@
     FLAG_CHILD = 0x1,                 // Argument preserved for forked child call.
     FLAG_INCOMPATIBLE = 0x2,          // Not compatible with isolation mode.
     FLAG_ENVIRONMENT_VARIABLE = 0x4,  // Can be an environment variable.
-    FLAG_TAKES_VALUE = 0x8,           // Flag requires a non-empty value.
+    FLAG_REQUIRES_VALUE = 0x8,        // Flag requires a non-empty value.
+    FLAG_OPTIONAL_VALUE = 0x10,       // Flag takes an optional value.
   };
+  static constexpr uint32_t FLAG_TAKES_VALUE = FLAG_REQUIRES_VALUE | FLAG_OPTIONAL_VALUE;
 
   struct ArgInfo {
     uint32_t flags;
diff --git a/tests/OptionsTest.cpp b/tests/OptionsTest.cpp
index 0a8f487..973a2fc 100644
--- a/tests/OptionsTest.cpp
+++ b/tests/OptionsTest.cpp
@@ -326,9 +326,7 @@
   EXPECT_EQ(10, options.num_iterations());
   EXPECT_EQ(std::vector<const char*>{"ignore"}, child_args);
 
-  cur_args.clear();
-  cur_args.push_back("ignore");
-  cur_args.push_back("--gtest_repeat=-1");
+  cur_args = std::vector<const char*>{"ignore", "--gtest_repeat=-1"};
   ASSERT_TRUE(options.Process(cur_args, &child_args));
   EXPECT_EQ(-1, options.num_iterations());
   EXPECT_EQ(std::vector<const char*>{"ignore"}, child_args);
@@ -357,24 +355,27 @@
 
   capture.Reset();
   capture.Start();
-  std::vector<const char*> cur_args2{"ignore", "--gtest_repeat=-2147483747"};
-  parsed = options.Process(cur_args2, &child_args);
+  cur_args = std::vector<const char*>{"ignore", "--gtest_repeat=-2147483747"};
+  parsed = options.Process(cur_args, &child_args);
   capture.Stop();
   ASSERT_FALSE(parsed) << "Process did not fail properly.";
   EXPECT_EQ("--gtest_repeat value overflows (-2147483747)\n", capture.str());
 }
 
 TEST(OptionsTest, gtest_print_time) {
-  std::vector<const char*> cur_args{"ignore", "--gtest_print_time=0"};
+  std::vector<const char*> cur_args{"ignore", "--gtest_print_time"};
   std::vector<const char*> child_args;
   Options options;
   ASSERT_TRUE(options.Process(cur_args, &child_args));
+  EXPECT_TRUE(options.print_time());
+  EXPECT_EQ(std::vector<const char*>{"ignore"}, child_args);
+
+  cur_args = std::vector<const char*>{"ignore", "--gtest_print_time=0"};
+  ASSERT_TRUE(options.Process(cur_args, &child_args));
   EXPECT_FALSE(options.print_time());
   EXPECT_EQ(std::vector<const char*>{"ignore"}, child_args);
 
-  cur_args.clear();
-  cur_args.push_back("ignore");
-  cur_args.push_back("--gtest_print_time=1");
+  cur_args = std::vector<const char*>{"ignore", "--gtest_print_time=1"};
   ASSERT_TRUE(options.Process(cur_args, &child_args));
   EXPECT_TRUE(options.print_time());
   EXPECT_EQ(std::vector<const char*>{"ignore"}, child_args);
@@ -388,16 +389,12 @@
   EXPECT_EQ("/file.xml", options.xml_file());
   EXPECT_EQ(std::vector<const char*>{"ignore"}, child_args);
 
-  cur_args.clear();
-  cur_args.push_back("ignore");
-  cur_args.push_back("--gtest_output=xml:/directory/");
+  cur_args = std::vector<const char*>{"ignore", "--gtest_output=xml:/directory/"};
   ASSERT_TRUE(options.Process(cur_args, &child_args));
   EXPECT_EQ("/directory/test_details.xml", options.xml_file());
   EXPECT_EQ(std::vector<const char*>{"ignore"}, child_args);
 
-  cur_args.clear();
-  cur_args.push_back("ignore");
-  cur_args.push_back("--gtest_output=xml:cwd.xml");
+  cur_args = std::vector<const char*>{"ignore", "--gtest_output=xml:cwd.xml"};
   ASSERT_TRUE(options.Process(cur_args, &child_args));
   char* cwd = getcwd(nullptr, 0);
   std::string expected_file(cwd);
@@ -430,8 +427,8 @@
 
   capture.Reset();
   capture.Start();
-  std::vector<const char*> cur_args2{"ignore", "--gtest_output=not_xml"};
-  parsed = options.Process(cur_args2, &child_args);
+  cur_args = std::vector<const char*>{"ignore", "--gtest_output=not_xml"};
+  parsed = options.Process(cur_args, &child_args);
   capture.Stop();
   ASSERT_FALSE(parsed) << "Process did not fail properly.";
   EXPECT_EQ("--gtest_output only supports an xml output file.\n", capture.str());
@@ -653,6 +650,19 @@
   ASSERT_NE(-1, unsetenv("GTEST_PRINT_TIME"));
 }
 
+TEST(OptionsTest, gtest_print_time_no_value_from_env) {
+  ASSERT_NE(-1, setenv("GTEST_PRINT_TIME", "", 1));
+
+  std::vector<const char*> cur_args{"ignore"};
+  std::vector<const char*> child_args;
+  Options options;
+  ASSERT_TRUE(options.Process(cur_args, &child_args));
+  EXPECT_TRUE(options.print_time());
+  EXPECT_EQ(std::vector<const char*>{"ignore"}, child_args);
+
+  ASSERT_NE(-1, unsetenv("GTEST_PRINT_TIME"));
+}
+
 TEST(OptionsTest, gtest_output_from_env) {
   ASSERT_NE(-1, setenv("GTEST_OUTPUT", "xml:/file.xml", 1));