]>
Commit | Line | Data |
---|---|---|
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 | ||
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 | indent_stream << std::endl; | |
41 | ||
42 | if (m_positional.options().size() > 0) { | |
43 | indent_stream.set_delimiter(" "); | |
44 | for (size_t i = 0; i < m_positional.options().size(); ++i) { | |
45 | indent_stream << "<" << m_positional.options()[i]->long_name() << "> "; | |
46 | if (m_positional.options()[i]->semantic()->max_tokens() > 1) { | |
47 | indent_stream << "[<" << m_positional.options()[i]->long_name() | |
48 | << "> ...]"; | |
49 | break; | |
50 | } | |
51 | } | |
52 | indent_stream << std::endl; | |
53 | } | |
54 | } | |
55 | ||
56 | void OptionPrinter::print_detailed(std::ostream &os) { | |
57 | std::string indent_prefix(2, ' '); | |
58 | size_t name_width = compute_name_width(indent_prefix.size()); | |
59 | ||
60 | if (m_positional.options().size() > 0) { | |
61 | std::cout << POSITIONAL_ARGUMENTS << std::endl; | |
62 | for (size_t i = 0; i < m_positional.options().size(); ++i) { | |
63 | std::stringstream ss; | |
64 | ss << indent_prefix << "<" << m_positional.options()[i]->long_name() | |
65 | << ">"; | |
66 | ||
67 | std::cout << ss.str(); | |
68 | IndentStream indent_stream(name_width, ss.str().size(), LINE_WIDTH, os); | |
69 | indent_stream << m_positional.options()[i]->description() << std::endl; | |
70 | } | |
71 | std::cout << std::endl; | |
72 | } | |
73 | ||
74 | if (m_optional.options().size() > 0) { | |
75 | std::cout << OPTIONAL_ARGUMENTS << std::endl; | |
76 | for (size_t i = 0; i < m_optional.options().size(); ++i) { | |
77 | std::stringstream ss; | |
78 | ss << indent_prefix | |
79 | << m_optional.options()[i]->format_name() << " " | |
80 | << m_optional.options()[i]->format_parameter(); | |
81 | ||
82 | std::cout << ss.str(); | |
83 | IndentStream indent_stream(name_width, ss.str().size(), LINE_WIDTH, os); | |
84 | indent_stream << m_optional.options()[i]->description() << std::endl; | |
85 | } | |
86 | std::cout << std::endl; | |
87 | } | |
88 | } | |
89 | ||
90 | size_t OptionPrinter::compute_name_width(size_t indent) { | |
91 | size_t width = MIN_NAME_WIDTH; | |
92 | std::vector<OptionsDescription> descs = {m_positional, m_optional}; | |
93 | for (size_t desc_idx = 0; desc_idx < descs.size(); ++desc_idx) { | |
94 | const OptionsDescription &desc = descs[desc_idx]; | |
95 | for (size_t opt_idx = 0; opt_idx < desc.options().size(); ++opt_idx) { | |
96 | size_t name_width = desc.options()[opt_idx]->format_name().size() + | |
97 | desc.options()[opt_idx]->format_parameter().size() | |
98 | + 1; | |
99 | width = std::max(width, name_width); | |
100 | } | |
101 | } | |
102 | width += indent; | |
103 | width = std::min(width, MAX_DESCRIPTION_OFFSET) + 1; | |
104 | return width; | |
105 | } | |
106 | ||
107 | } // namespace rbd |