]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/rbd/OptionPrinter.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / tools / rbd / OptionPrinter.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "tools/rbd/OptionPrinter.h"
5#include "tools/rbd/IndentStream.h"
6
7namespace rbd {
8
9namespace po = boost::program_options;
10
11const std::string OptionPrinter::POSITIONAL_ARGUMENTS("Positional arguments");
12const std::string OptionPrinter::OPTIONAL_ARGUMENTS("Optional arguments");
13
14const size_t OptionPrinter::MAX_DESCRIPTION_OFFSET;
15
16OptionPrinter::OptionPrinter(const OptionsDescription &positional,
17 const OptionsDescription &optional)
18 : m_positional(positional), m_optional(optional) {
19}
20
21void OptionPrinter::print_short(std::ostream &os, size_t initial_offset) {
f67539c2
TL
22 size_t max_option_width = 0;
23 std::vector<std::string> optionals;
7c673cae 24 for (size_t i = 0; i < m_optional.options().size(); ++i) {
f67539c2
TL
25 std::stringstream option;
26
7c673cae
FG
27 bool required = m_optional.options()[i]->semantic()->is_required();
28 if (!required) {
f67539c2 29 option << "[";
7c673cae 30 }
f67539c2 31 option << "--" << m_optional.options()[i]->long_name();
7c673cae 32 if (m_optional.options()[i]->semantic()->max_tokens() != 0) {
f67539c2 33 option << " <" << m_optional.options()[i]->long_name() << ">";
7c673cae
FG
34 }
35 if (!required) {
f67539c2
TL
36 option << "]";
37 }
38 max_option_width = std::max(max_option_width, option.str().size());
39 optionals.emplace_back(option.str());
40 }
41
42 std::vector<std::string> positionals;
43 for (size_t i = 0; i < m_positional.options().size(); ++i) {
44 std::stringstream option;
45
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() << "> ...]";
7c673cae 49 }
f67539c2
TL
50
51 max_option_width = std::max(max_option_width, option.str().size());
52 positionals.emplace_back(option.str());
53
54 if (m_positional.options()[i]->semantic()->max_tokens() > 1) {
55 break;
56 }
57 }
58
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;
63 }
64
65 IndentStream indent_stream(indent, initial_offset, LINE_WIDTH, os);
66 indent_stream.set_delimiter("[");
67 for (auto& option : optionals) {
68 indent_stream << option << " ";
7c673cae 69 }
11fdf7f2 70
f67539c2 71 if (optionals.size() > 0 || positionals.size() == 0) {
11fdf7f2
TL
72 indent_stream << std::endl;
73 }
7c673cae 74
f67539c2 75 if (positionals.size() > 0) {
7c673cae 76 indent_stream.set_delimiter(" ");
f67539c2
TL
77 for (auto& option : positionals) {
78 indent_stream << option << " ";
7c673cae
FG
79 }
80 indent_stream << std::endl;
81 }
82}
83
f67539c2
TL
84void OptionPrinter::print_optional(const OptionsDescription &global_opts,
85 size_t &name_width, std::ostream &os) {
86 std::string indent2(2, ' ');
87
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()) {
92 continue;
93 }
94 std::stringstream ss;
95 ss << indent2
96 << global_opts.options()[i]->format_name() << " "
97 << global_opts.options()[i]->format_parameter();
98
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;
102 }
103
104}
105
7c673cae
FG
106void OptionPrinter::print_detailed(std::ostream &os) {
107 std::string indent_prefix(2, ' ');
108 size_t name_width = compute_name_width(indent_prefix.size());
109
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()
115 << ">";
116
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;
120 }
121 std::cout << std::endl;
122 }
123
124 if (m_optional.options().size() > 0) {
125 std::cout << OPTIONAL_ARGUMENTS << std::endl;
f67539c2 126 print_optional(m_optional, name_width, os);
7c673cae
FG
127 std::cout << std::endl;
128 }
129}
130
131size_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()
139 + 1;
140 width = std::max(width, name_width);
141 }
142 }
143 width += indent;
144 width = std::min(width, MAX_DESCRIPTION_OFFSET) + 1;
145 return width;
146}
147
148} // namespace rbd