]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd/OptionPrinter.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / 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
3
4 #include "tools/rbd/OptionPrinter.h"
5 #include "tools/rbd/IndentStream.h"
6
7 namespace rbd {
8
9 namespace po = boost::program_options;
10
11 const std::string OptionPrinter::POSITIONAL_ARGUMENTS("Positional arguments");
12 const std::string OptionPrinter::OPTIONAL_ARGUMENTS("Optional arguments");
13
14 const size_t OptionPrinter::MAX_DESCRIPTION_OFFSET;
15
16 OptionPrinter::OptionPrinter(const OptionsDescription &positional,
17 const OptionsDescription &optional)
18 : m_positional(positional), m_optional(optional) {
19 }
20
21 void OptionPrinter::print_short(std::ostream &os, size_t initial_offset) {
22 size_t name_width = std::min(initial_offset, MAX_DESCRIPTION_OFFSET) + 1;
23
24 IndentStream indent_stream(name_width, initial_offset, LINE_WIDTH, os);
25 indent_stream.set_delimiter("[");
26 for (size_t i = 0; i < m_optional.options().size(); ++i) {
27 bool required = m_optional.options()[i]->semantic()->is_required();
28 if (!required) {
29 indent_stream << "[";
30 }
31 indent_stream << "--" << m_optional.options()[i]->long_name();
32 if (m_optional.options()[i]->semantic()->max_tokens() != 0) {
33 indent_stream << " <" << m_optional.options()[i]->long_name() << ">";
34 }
35 if (!required) {
36 indent_stream << "]";
37 }
38 indent_stream << " ";
39 }
40
41 if (m_optional.options().size() > 0 || m_positional.options().size() == 0) {
42 indent_stream << std::endl;
43 }
44
45 if (m_positional.options().size() > 0) {
46 indent_stream.set_delimiter(" ");
47 for (size_t i = 0; i < m_positional.options().size(); ++i) {
48 indent_stream << "<" << m_positional.options()[i]->long_name() << "> ";
49 if (m_positional.options()[i]->semantic()->max_tokens() > 1) {
50 indent_stream << "[<" << m_positional.options()[i]->long_name()
51 << "> ...]";
52 break;
53 }
54 }
55 indent_stream << std::endl;
56 }
57 }
58
59 void OptionPrinter::print_detailed(std::ostream &os) {
60 std::string indent_prefix(2, ' ');
61 size_t name_width = compute_name_width(indent_prefix.size());
62
63 if (m_positional.options().size() > 0) {
64 std::cout << POSITIONAL_ARGUMENTS << std::endl;
65 for (size_t i = 0; i < m_positional.options().size(); ++i) {
66 std::stringstream ss;
67 ss << indent_prefix << "<" << m_positional.options()[i]->long_name()
68 << ">";
69
70 std::cout << ss.str();
71 IndentStream indent_stream(name_width, ss.str().size(), LINE_WIDTH, os);
72 indent_stream << m_positional.options()[i]->description() << std::endl;
73 }
74 std::cout << std::endl;
75 }
76
77 if (m_optional.options().size() > 0) {
78 std::cout << OPTIONAL_ARGUMENTS << std::endl;
79 for (size_t i = 0; i < m_optional.options().size(); ++i) {
80 std::stringstream ss;
81 ss << indent_prefix
82 << m_optional.options()[i]->format_name() << " "
83 << m_optional.options()[i]->format_parameter();
84
85 std::cout << ss.str();
86 IndentStream indent_stream(name_width, ss.str().size(), LINE_WIDTH, os);
87 indent_stream << m_optional.options()[i]->description() << std::endl;
88 }
89 std::cout << std::endl;
90 }
91 }
92
93 size_t OptionPrinter::compute_name_width(size_t indent) {
94 size_t width = MIN_NAME_WIDTH;
95 std::vector<OptionsDescription> descs = {m_positional, m_optional};
96 for (size_t desc_idx = 0; desc_idx < descs.size(); ++desc_idx) {
97 const OptionsDescription &desc = descs[desc_idx];
98 for (size_t opt_idx = 0; opt_idx < desc.options().size(); ++opt_idx) {
99 size_t name_width = desc.options()[opt_idx]->format_name().size() +
100 desc.options()[opt_idx]->format_parameter().size()
101 + 1;
102 width = std::max(width, name_width);
103 }
104 }
105 width += indent;
106 width = std::min(width, MAX_DESCRIPTION_OFFSET) + 1;
107 return width;
108 }
109
110 } // namespace rbd