]>
git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd/OptionPrinter.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "tools/rbd/OptionPrinter.h"
5 #include "tools/rbd/IndentStream.h"
9 namespace po
= boost::program_options
;
11 const std::string
OptionPrinter::POSITIONAL_ARGUMENTS("Positional arguments");
12 const std::string
OptionPrinter::OPTIONAL_ARGUMENTS("Optional arguments");
14 const size_t OptionPrinter::MAX_DESCRIPTION_OFFSET
;
16 OptionPrinter::OptionPrinter(const OptionsDescription
&positional
,
17 const OptionsDescription
&optional
)
18 : m_positional(positional
), m_optional(optional
) {
21 void OptionPrinter::print_short(std::ostream
&os
, size_t initial_offset
) {
22 size_t max_option_width
= 0;
23 std::vector
<std::string
> optionals
;
24 for (size_t i
= 0; i
< m_optional
.options().size(); ++i
) {
25 std::stringstream option
;
27 bool required
= m_optional
.options()[i
]->semantic()->is_required();
31 option
<< "--" << m_optional
.options()[i
]->long_name();
32 if (m_optional
.options()[i
]->semantic()->max_tokens() != 0) {
33 option
<< " <" << m_optional
.options()[i
]->long_name() << ">";
38 max_option_width
= std::max(max_option_width
, option
.str().size());
39 optionals
.emplace_back(option
.str());
42 std::vector
<std::string
> positionals
;
43 for (size_t i
= 0; i
< m_positional
.options().size(); ++i
) {
44 std::stringstream option
;
46 option
<< "<" << m_positional
.options()[i
]->long_name() << ">";
47 if (m_positional
.options()[i
]->semantic()->max_tokens() > 1) {
48 option
<< " [<" << m_positional
.options()[i
]->long_name() << "> ...]";
51 max_option_width
= std::max(max_option_width
, option
.str().size());
52 positionals
.emplace_back(option
.str());
54 if (m_positional
.options()[i
]->semantic()->max_tokens() > 1) {
59 size_t indent
= std::min(initial_offset
, MAX_DESCRIPTION_OFFSET
) + 1;
60 if (indent
+ max_option_width
+ 2 > LINE_WIDTH
) {
61 // decrease the indent so that we don't wrap past the end of the line
62 indent
= LINE_WIDTH
- max_option_width
- 2;
65 IndentStream
indent_stream(indent
, initial_offset
, LINE_WIDTH
, os
);
66 indent_stream
.set_delimiter("[");
67 for (auto& option
: optionals
) {
68 indent_stream
<< option
<< " ";
71 if (optionals
.size() > 0 || positionals
.size() == 0) {
72 indent_stream
<< std::endl
;
75 if (positionals
.size() > 0) {
76 indent_stream
.set_delimiter(" ");
77 for (auto& option
: positionals
) {
78 indent_stream
<< option
<< " ";
80 indent_stream
<< std::endl
;
84 void OptionPrinter::print_optional(const OptionsDescription
&global_opts
,
85 size_t &name_width
, std::ostream
&os
) {
86 std::string
indent2(2, ' ');
88 for (size_t i
= 0; i
< global_opts
.options().size(); ++i
) {
89 std::string description
= global_opts
.options()[i
]->description();
90 auto result
= boost::find_first(description
, "deprecated");
91 if (!result
.empty()) {
96 << global_opts
.options()[i
]->format_name() << " "
97 << global_opts
.options()[i
]->format_parameter();
99 std::cout
<< ss
.str();
100 IndentStream
indent_stream(name_width
, ss
.str().size(), LINE_WIDTH
, std::cout
);
101 indent_stream
<< global_opts
.options()[i
]->description() << std::endl
;
106 void OptionPrinter::print_detailed(std::ostream
&os
) {
107 std::string
indent_prefix(2, ' ');
108 size_t name_width
= compute_name_width(indent_prefix
.size());
110 if (m_positional
.options().size() > 0) {
111 std::cout
<< POSITIONAL_ARGUMENTS
<< std::endl
;
112 for (size_t i
= 0; i
< m_positional
.options().size(); ++i
) {
113 std::stringstream ss
;
114 ss
<< indent_prefix
<< "<" << m_positional
.options()[i
]->long_name()
117 std::cout
<< ss
.str();
118 IndentStream
indent_stream(name_width
, ss
.str().size(), LINE_WIDTH
, os
);
119 indent_stream
<< m_positional
.options()[i
]->description() << std::endl
;
121 std::cout
<< std::endl
;
124 if (m_optional
.options().size() > 0) {
125 std::cout
<< OPTIONAL_ARGUMENTS
<< std::endl
;
126 print_optional(m_optional
, name_width
, os
);
127 std::cout
<< std::endl
;
131 size_t OptionPrinter::compute_name_width(size_t indent
) {
132 size_t width
= MIN_NAME_WIDTH
;
133 std::vector
<OptionsDescription
> descs
= {m_positional
, m_optional
};
134 for (size_t desc_idx
= 0; desc_idx
< descs
.size(); ++desc_idx
) {
135 const OptionsDescription
&desc
= descs
[desc_idx
];
136 for (size_t opt_idx
= 0; opt_idx
< desc
.options().size(); ++opt_idx
) {
137 size_t name_width
= desc
.options()[opt_idx
]->format_name().size() +
138 desc
.options()[opt_idx
]->format_parameter().size()
140 width
= std::max(width
, name_width
);
144 width
= std::min(width
, MAX_DESCRIPTION_OFFSET
) + 1;