Commit e73b9139 by Gennadiy Rozental Committed by Copybara-Service

Use stdout for help output even in case of errors.

PiperOrigin-RevId: 522393331
Change-Id: Ia5f4ad6a2d16c033ea97f3c7e27e8eb7ee429242
parent 0bc6509b
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#ifndef ABSL_FLAGS_INTERNAL_PARSE_H_ #ifndef ABSL_FLAGS_INTERNAL_PARSE_H_
#define ABSL_FLAGS_INTERNAL_PARSE_H_ #define ABSL_FLAGS_INTERNAL_PARSE_H_
#include <iostream>
#include <ostream>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -40,9 +42,15 @@ enum class OnUndefinedFlag { ...@@ -40,9 +42,15 @@ enum class OnUndefinedFlag {
kAbortIfUndefined kAbortIfUndefined
}; };
std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], // This is not a public interface. This interface exists to expose the ability
UsageFlagsAction usage_flag_action, // to change help output stream in case of parsing errors. This is used by
OnUndefinedFlag undef_flag_action); // 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 // Inspect original command line
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <ostream>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
...@@ -693,7 +694,8 @@ std::vector<std::string> GetMisspellingHints(const absl::string_view flag) { ...@@ -693,7 +694,8 @@ std::vector<std::string> GetMisspellingHints(const absl::string_view flag) {
std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
UsageFlagsAction usage_flag_action, UsageFlagsAction usage_flag_action,
OnUndefinedFlag undef_flag_action) { OnUndefinedFlag undef_flag_action,
std::ostream& error_help_output) {
std::vector<char*> positional_args; std::vector<char*> positional_args;
std::vector<UnrecognizedFlag> unrecognized_flags; std::vector<UnrecognizedFlag> unrecognized_flags;
...@@ -707,8 +709,8 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], ...@@ -707,8 +709,8 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
if (undef_flag_action == OnUndefinedFlag::kAbortIfUndefined) { if (undef_flag_action == OnUndefinedFlag::kAbortIfUndefined) {
if (!unrecognized_flags.empty()) { if (!unrecognized_flags.empty()) {
flags_internal::HandleUsageFlags(std::cerr, ProgramUsageMessage()); flags_internal::HandleUsageFlags(error_help_output,
std::exit(1); ProgramUsageMessage()); std::exit(1);
} }
} }
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <fstream> #include <fstream>
#include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -235,7 +236,9 @@ ABSL_RETIRED_FLAG(std::string, legacy_str, "l", ""); ...@@ -235,7 +236,9 @@ ABSL_RETIRED_FLAG(std::string, legacy_str, "l", "");
namespace { namespace {
namespace flags = absl::flags_internal; namespace flags = absl::flags_internal;
using testing::AllOf;
using testing::ElementsAreArray; using testing::ElementsAreArray;
using testing::HasSubstr;
class ParseTest : public testing::Test { class ParseTest : public testing::Test {
public: public:
...@@ -271,6 +274,15 @@ void InvokeParseAbslOnly(const char* (&in_argv)[N]) { ...@@ -271,6 +274,15 @@ void InvokeParseAbslOnly(const char* (&in_argv)[N]) {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
template <int 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]) { std::vector<char*> InvokeParse(const char* (&in_argv)[N]) {
return absl::ParseCommandLine(N, const_cast<char**>(in_argv)); return absl::ParseCommandLine(N, const_cast<char**>(in_argv));
} }
...@@ -1066,8 +1078,9 @@ TEST_F(ParseDeathTest, ExitOnUnrecognizedFlagPrintsHelp) { ...@@ -1066,8 +1078,9 @@ TEST_F(ParseDeathTest, ExitOnUnrecognizedFlagPrintsHelp) {
"--help=int_flag", "--help=int_flag",
}; };
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args), EXPECT_EXIT(InvokeParseCommandLineImpl(in_args), testing::ExitedWithCode(1),
"Try --helpfull to get a list of all flags"); AllOf(HasSubstr("Unknown command line flag 'undef_flag1'"),
HasSubstr("Try --helpfull to get a list of all flags")));
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment