16 #include "absl/flags/internal/usage.h"
27 #include "absl/base/config.h"
28 #include "absl/flags/commandlineflag.h"
29 #include "absl/flags/flag.h"
30 #include "absl/flags/internal/flag.h"
31 #include "absl/flags/internal/path_util.h"
32 #include "absl/flags/internal/private_handle_accessor.h"
33 #include "absl/flags/internal/program_name.h"
34 #include "absl/flags/internal/registry.h"
35 #include "absl/flags/usage_config.h"
36 #include "absl/strings/str_cat.h"
37 #include "absl/strings/str_split.h"
38 #include "absl/strings/string_view.h"
52 namespace flags_internal {
58 constexpr
size_t kHrfMaxLineLength = 80;
71 const XMLElement& xml_elem) {
72 out <<
"<" << xml_elem.tag_ <<
">";
74 for (
auto c : xml_elem.txt_) {
97 return out <<
"</" << xml_elem.tag_ <<
">";
108 class FlagHelpPrettyPrinter {
112 FlagHelpPrettyPrinter(
size_t max_line_len,
size_t min_line_len,
113 size_t wrapped_line_indent, std::ostream&
out)
123 if (
str.empty())
return;
125 std::vector<absl::string_view> tokens;
128 if (!tokens.empty()) {
130 tokens.push_back(
"\n");
134 tokens.push_back(token);
138 tokens.push_back(
str);
141 for (
auto token : tokens) {
192 void FlagHelpHumanReadable(
const CommandLineFlag&
flag, std::ostream&
out) {
193 FlagHelpPrettyPrinter printer(kHrfMaxLineLength, 4, 2,
out);
207 bool is_modified = curr_val != dflt_val;
212 printer.Write(
absl::StrCat(
"default: ", dflt_val,
";"));
218 printer.Write(
absl::StrCat(
"currently: ", curr_val,
";"));
229 void FlagsHelpImpl(std::ostream&
out, PerFlagFilter filter_cb,
233 << program_usage_message <<
"\n\n";
236 out <<
"<?xml version=\"1.0\"?>\n"
237 <<
"<!-- This output should be used with care. We do not report type "
238 "names for flags with user defined types -->\n"
239 <<
"<!-- Prefer flag only_check_args for validating flag inputs -->\n"
245 << XMLElement(
"usage", program_usage_message) <<
'\n';
254 std::map<std::string, std::vector<const absl::CommandLineFlag*>>>
259 if (
flag.IsRetired())
return;
265 if (!filter_cb(
flag))
return;
276 for (
auto& package : matching_flags) {
278 out << package_separator;
279 package_separator =
"\n\n";
283 for (
auto& flags_in_file : package.second) {
285 out << file_separator <<
" Flags from " << flags_in_file.first
287 file_separator =
"\n";
292 [](
const CommandLineFlag* lhs,
const CommandLineFlag* rhs) {
293 return lhs->Name() < rhs->Name();
296 for (
const auto*
flag : flags_in_file.second) {
303 FlagHelpPrettyPrinter printer(kHrfMaxLineLength, 0, 0,
out);
305 if (filter_cb && matching_flags.empty()) {
306 printer.Write(
"No flags matched.\n",
true);
310 "Try --helpfull to get a list of all flags or --help=substring "
311 "shows help for flags which include specified substring in either "
312 "in the name, or description or path.\n",
316 out <<
"</AllFlags>\n";
320 void FlagsHelpImpl(std::ostream&
out,
326 return filename_filter_cb && filename_filter_cb(
flag.Filename());
328 format, program_usage_message);
338 flags_internal::FlagHelpHumanReadable(
flag,
out);
349 flags_internal::FlagsHelpImpl(
out, filter_cb,
format, program_usage_message);
361 flags_internal::FlagsHelpImpl(
367 flags_internal::FlagsHelpImpl(
374 program_usage_message);
378 flags_internal::FlagsHelpImpl(
386 if (substr.empty()) {
389 program_usage_message);
398 flags_internal::FlagsHelpImpl(
434 if (match_substr ==
nullptr)
return "";
435 return *match_substr;
440 if (match_substr ==
nullptr) match_substr =
new std::string;
441 match_substr->assign(substr.
data(), substr.
size());
479 if (
name ==
"match") {
491 if (
name ==
"full") {
496 if (
name ==
"short") {
501 if (
name ==
"package") {
509 if (
name ==
"version") {
514 if (
name ==
"only_check_args") {