summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--absl/flags/internal/parse.h14
-rw-r--r--absl/flags/parse.cc8
-rw-r--r--absl/flags/parse_test.cc17
3 files changed, 31 insertions, 8 deletions
diff --git a/absl/flags/internal/parse.h b/absl/flags/internal/parse.h
index e4352049..10c531b8 100644
--- a/absl/flags/internal/parse.h
+++ b/absl/flags/internal/parse.h
@@ -16,6 +16,8 @@
#ifndef ABSL_FLAGS_INTERNAL_PARSE_H_
#define ABSL_FLAGS_INTERNAL_PARSE_H_
+#include <iostream>
+#include <ostream>
#include <string>
#include <vector>
@@ -40,9 +42,15 @@ enum class OnUndefinedFlag {
kAbortIfUndefined
};
-std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
- UsageFlagsAction usage_flag_action,
- OnUndefinedFlag undef_flag_action);
+// This is not a public interface. This interface exists to expose the ability
+// to change help output stream in case of parsing errors. This is used by
+// internal unit tests to validate expected outputs.
+// When this was written, `EXPECT_EXIT` only supported matchers on stderr,
+// but not on stdout.
+std::vector<char*> ParseCommandLineImpl(
+ int argc, char* argv[], UsageFlagsAction usage_flag_action,
+ OnUndefinedFlag undef_flag_action,
+ std::ostream& error_help_output = std::cout);
// --------------------------------------------------------------------
// Inspect original command line
diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc
index d3609c13..172fe901 100644
--- a/absl/flags/parse.cc
+++ b/absl/flags/parse.cc
@@ -22,6 +22,7 @@
#include <cstdlib>
#include <fstream>
#include <iostream>
+#include <ostream>
#include <string>
#include <tuple>
#include <utility>
@@ -693,7 +694,8 @@ std::vector<std::string> GetMisspellingHints(const absl::string_view flag) {
std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
UsageFlagsAction usage_flag_action,
- OnUndefinedFlag undef_flag_action) {
+ OnUndefinedFlag undef_flag_action,
+ std::ostream& error_help_output) {
std::vector<char*> positional_args;
std::vector<UnrecognizedFlag> unrecognized_flags;
@@ -707,8 +709,8 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
if (undef_flag_action == OnUndefinedFlag::kAbortIfUndefined) {
if (!unrecognized_flags.empty()) {
- flags_internal::HandleUsageFlags(std::cerr, ProgramUsageMessage());
- std::exit(1);
+ flags_internal::HandleUsageFlags(error_help_output,
+ ProgramUsageMessage()); std::exit(1);
}
}
}
diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc
index f3987bb7..cd32efc8 100644
--- a/absl/flags/parse_test.cc
+++ b/absl/flags/parse_test.cc
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <fstream>
+#include <iostream>
#include <string>
#include <vector>
@@ -235,7 +236,9 @@ ABSL_RETIRED_FLAG(std::string, legacy_str, "l", "");
namespace {
namespace flags = absl::flags_internal;
+using testing::AllOf;
using testing::ElementsAreArray;
+using testing::HasSubstr;
class ParseTest : public testing::Test {
public:
@@ -271,6 +274,15 @@ void InvokeParseAbslOnly(const char* (&in_argv)[N]) {
// --------------------------------------------------------------------
template <int N>
+std::vector<char*> InvokeParseCommandLineImpl(const char* (&in_argv)[N]) {
+ return flags::ParseCommandLineImpl(
+ N, const_cast<char**>(in_argv), flags::UsageFlagsAction::kHandleUsage,
+ flags::OnUndefinedFlag::kAbortIfUndefined, std::cerr);
+}
+
+// --------------------------------------------------------------------
+
+template <int N>
std::vector<char*> InvokeParse(const char* (&in_argv)[N]) {
return absl::ParseCommandLine(N, const_cast<char**>(in_argv));
}
@@ -1066,8 +1078,9 @@ TEST_F(ParseDeathTest, ExitOnUnrecognizedFlagPrintsHelp) {
"--help=int_flag",
};
- EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args),
- "Try --helpfull to get a list of all flags");
+ EXPECT_EXIT(InvokeParseCommandLineImpl(in_args), testing::ExitedWithCode(1),
+ AllOf(HasSubstr("Unknown command line flag 'undef_flag1'"),
+ HasSubstr("Try --helpfull to get a list of all flags")));
}
// --------------------------------------------------------------------