OGS
TCLAPOutput.h
Go to the documentation of this file.
1
9#pragma once
10
11#include <tclap/CmdLine.h>
12
13#include <regex>
14
15namespace BaseLib
16{
17
18template <typename T>
19const char* type_name();
20
21template <>
23{
24 return "string";
25}
26template <>
27const char* type_name<int>()
28{
29 return "int";
30}
31template <>
32const char* type_name<double>()
33{
34 return "double";
35}
36template <>
37const char* type_name<float>()
38{
39 return "float";
40}
41template <>
42const char* type_name<bool>()
43{
44 return "bool";
45}
46template <>
47const char* type_name<size_t>()
48{
49 return "size_t";
50}
51template <>
52const char* type_name<long>()
53{
54 return "long";
55}
56template <>
58{
59 return "unsigned";
60}
61
62class TCLAPOutput : public TCLAP::StdOutput
63{
64public:
65 virtual void usage(TCLAP::CmdLineInterface& _cmd)
66 {
67 // Follows implementation from tclap
68 std::cout << std::endl << "USAGE: " << std::endl << std::endl;
69 _shortUsage(_cmd, std::cout);
70 std::cout << std::endl
71 << std::endl
72 << "Where: " << std::endl
73 << std::endl;
74
75 std::string const message = _cmd.getMessage();
76 std::list<TCLAP::ArgGroup*> argSets = _cmd.getArgGroups();
77
78 std::list<TCLAP::Arg*> unlabelled;
79 for (std::list<TCLAP::ArgGroup*>::iterator sit = argSets.begin();
80 sit != argSets.end();
81 ++sit)
82 {
83 TCLAP::ArgGroup& argGroup = **sit;
84
85 int const visible = CountVisibleArgs(argGroup);
86 bool const exclusive = visible > 1 && argGroup.isExclusive();
87 bool const forceRequired = visible == 1 && argGroup.isRequired();
88 if (exclusive)
89 {
90 spacePrint(std::cout,
91 argGroup.isRequired() ? "One of:" : "Either of:", 75,
92 3, 0);
93 }
94
95 for (TCLAP::ArgGroup::iterator it = argGroup.begin();
96 it != argGroup.end();
97 ++it)
98 {
99 TCLAP::Arg& arg = **it;
100
101 if (!arg.visibleInHelp())
102 {
103 continue;
104 }
105
106 if (!arg.hasLabel())
107 {
108 unlabelled.push_back(&arg);
109 continue;
110 }
111
112 // Added by LB:
113 std::string const shortID = arg.shortID();
114 std::smatch match;
115 bool const required = arg.isRequired() || forceRequired;
116 std::stringstream ss;
117 if (std::regex_search(shortID, match, std::regex("<([^>]+)>")))
118 {
119 std::string const identifier = match[1];
120
121 ss << identifier;
122 tryPrintValue<std::string>(*it, ss, required);
123 tryPrintValue<int>(*it, ss, required);
124 tryPrintValue<double>(*it, ss, required);
125 tryPrintValue<float>(*it, ss, required);
126 tryPrintValue<size_t>(*it, ss, required);
127 tryPrintValue<unsigned>(*it, ss, required);
128 tryPrintValue<unsigned int>(*it, ss, required);
129 ss << ": ";
130 }
131 ss << arg.getDescription(required);
132
133 if (exclusive)
134 {
135 spacePrint(std::cout, arg.longID(), 75, 6, 3);
136 spacePrint(std::cout, ss.str(), 75, 8, 0);
137 }
138 else
139 {
140 spacePrint(std::cout, arg.longID(), 75, 3, 3);
141 spacePrint(std::cout, ss.str(), 75, 5, 0);
142 }
143 std::cout << '\n';
144 }
145 }
146
147 for (TCLAP::ArgListIterator it = unlabelled.begin();
148 it != unlabelled.end();
149 ++it)
150 {
151 const TCLAP::Arg& arg = **it;
152 spacePrint(std::cout, arg.longID(), 75, 3, 3);
153 spacePrint(std::cout, arg.getDescription(), 75, 5, 0);
154 std::cout << '\n';
155 }
156
157 if (!message.empty())
158 {
159 spacePrint(std::cout, message, 75, 3, 0);
160 }
161
162 std::cout.flush();
163 }
164
165private:
166 template <typename T>
167 void tryPrintValue(TCLAP::Arg* arg, std::ostream& os, bool required)
168 {
169 if (auto val = dynamic_cast<TCLAP::ValueArg<T>*>(arg))
170 {
171 os << " (" << type_name<T>();
172 if (!required)
173 {
174 if constexpr (std::is_same_v<T, std::string>)
175 {
176 // print non-empty default value only
177 if (val->getValue() != "")
178 {
179 os << ", default: " << val->getValue();
180 }
181 }
182 else
183 {
184 os << ", default: " << val->getValue();
185 }
186 }
187 os << ")";
188 }
189 }
190};
191
192} // namespace BaseLib
void tryPrintValue(TCLAP::Arg *arg, std::ostream &os, bool required)
virtual void usage(TCLAP::CmdLineInterface &_cmd)
Definition TCLAPOutput.h:65
const char * type_name< double >()
Definition TCLAPOutput.h:32
const char * type_name< bool >()
Definition TCLAPOutput.h:42
const char * type_name< long >()
Definition TCLAPOutput.h:52
const char * type_name< size_t >()
Definition TCLAPOutput.h:47
const char * type_name< float >()
Definition TCLAPOutput.h:37
const char * type_name< int >()
Definition TCLAPOutput.h:27
const char * type_name< std::string >()
Definition TCLAPOutput.h:22
const char * type_name()
const char * type_name< unsigned >()
Definition TCLAPOutput.h:57