poafloc

Parser Of Arguments For Lines Of Commands
git clone git://git.dimitrijedobrota.com/poafloc.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

help.cpp (3541B)


0 #include <algorithm>
1 #include <format>
2 #include <iostream>
4 #include "based/algorithms/max.hpp"
5 #include "poafloc/poafloc.hpp"
7 namespace poafloc::detail
8 {
10 namespace
11 {
13 std::string format_option_long(const option& option)
14 {
15 const auto& opt = option.opt_long();
16 switch (option.get_type()) {
17 case option::type::boolean:
18 return std::format("--{}", opt);
19 case option::type::list:
20 return std::format("--{}={}...", opt, option.name());
21 default:
22 return std::format("--{}={}", opt, option.name());
23 }
24 }
26 std::string format_option_short(const option& option)
27 {
28 const auto& opt = option.opt_short();
29 switch (option.get_type()) {
30 case option::type::boolean:
31 return std::format("-{}", opt);
32 case option::type::list:
33 return std::format("-{} {}...", opt, option.name());
34 default:
35 return std::format("-{} {}", opt, option.name());
36 }
37 }
39 } // namespace
41 void parser_base::help_usage(std::string_view program) const
42 {
43 std::cerr << "Usage: ";
44 std::cerr << program;
45 std::cerr << " [OPTIONS]";
46 for (const auto& pos : m_pos) {
47 std::cerr << std::format(" {}", pos.name());
48 }
49 if (m_pos.is_list()) {
50 std::cerr << "...";
51 }
52 std::cerr << '\n';
53 }
55 bool parser_base::help_long(std::string_view program) const
56 {
57 help_usage(program);
59 auto idx = size_type(0_u);
60 for (const auto& [end_idx, name] : m_groups) {
61 std::cerr << std::format("\n{}:\n", name);
62 while (idx < end_idx) {
63 const auto& opt = m_options[idx++];
64 std::string line;
66 line += " ";
67 if (opt.has_opt_short()) {
68 line += std::format(" -{},", opt.opt_short());
69 } else {
70 line += std::string(4, ' ');
71 }
72 if (opt.has_opt_long()) {
73 line += " ";
74 line += format_option_long(opt);
75 }
77 static constexpr const auto zero = std::size_t {0};
78 static constexpr const auto mid = std::size_t {30};
79 line += std::string(based::max(zero, mid - std::size(line)), ' ');
81 std::cerr << line << opt.message() << '\n';
82 }
83 }
85 std::cerr << '\n';
86 return true;
87 }
89 bool parser_base::help_short(std::string_view program) const
90 {
91 std::vector<std::string> opts_short;
92 std::vector<std::string> opts_long;
93 std::string flags;
95 for (const auto& opt : m_options) {
96 if (opt.has_opt_short()) {
97 if (opt.get_type() == option::type::boolean) {
98 flags += opt.opt_short().chr();
99 } else {
100 opts_short.emplace_back(format_option_short(opt));
104 if (opt.has_opt_long()) {
105 opts_long.emplace_back(format_option_long(opt));
109 std::ranges::sort(opts_short);
110 std::ranges::sort(opts_long);
111 std::ranges::sort(flags);
113 static const std::string_view usage = "Usage:";
114 std::cerr << usage << ' ';
116 std::string line;
117 const auto print = [&line](std::string_view data)
119 static constexpr const auto lim = std::size_t {60};
120 if (std::size(line) + std::size(data) > lim) {
121 std::cerr << line << '\n';
122 line = std::string(std::size(usage), ' ');
124 line += " ";
125 line += data;
126 };
128 line += program;
129 if (!flags.empty()) {
130 print(std::format("[-{}]", flags));
133 for (const auto& opt : opts_short) {
134 print(std::format("[{}]", opt));
137 for (const auto& opt : opts_long) {
138 print(std::format("[{}]", opt));
141 for (const auto& pos : m_pos) {
142 print(pos.name());
145 std::cerr << line;
146 if (m_pos.is_list()) {
147 std::cerr << "...";
149 std::cerr << '\n' << '\n';
150 return true;
153 } // namespace poafloc::detail