netxsimdg
Loading...
Searching...
No Matches
ConfigurationHelpPrinter.cpp
Go to the documentation of this file.
1
9
10#include <regex>
11
12namespace Nextsim {
13
14const std::string ConfigurationHelpPrinter::allStr = "all";
15const std::string ConfigurationHelpPrinter::availStr = "avail";
16
17static std::string h1 = "";
18static std::string h1End = "";
19static std::string h2 = "";
20static std::string h2End = "";
21static std::string b = "";
22static std::string u = "";
23static std::string i = "";
24static std::string bEnd = "";
25static std::string uEnd = "";
26static std::string iEnd = "";
27
28static std::string section(const std::string& title) { return h1 + title + h1End; }
29
30static std::string option(const std::string& name) { return h2 + name + h2End; }
31
32static std::string defaultVal(const std::string& name) { return b + name + bEnd; }
33
34static std::string type(const std::string& desc) { return i + desc + iEnd; }
35
36std::ostream& ConfigurationHelpPrinter::print(
37 std::ostream& os, const ConfigurationHelp::HelpMap& map, const std::string& target)
38{
39 if (target == allStr) {
40 // All configuration help, in full
41 for (auto configEntry : map) {
42 os << section(configEntry.first) << std::endl << std::endl;
43 for (auto optionEntry : configEntry.second) {
44 os << optionEntry << std::endl;
45 }
46 os << std::endl;
47 }
48 } else if (target == availStr || target.empty()) {
49 // Available configuration options, names only
50 for (auto configEntry : map) {
51 os << section(configEntry.first) << std::endl;
52 for (auto optionEntry : configEntry.second) {
53 os << optionEntry.name << std::endl;
54 }
55 os << std::endl;
56 }
57 } else {
58 // Search for a specific option by case sensitive partial match
59 std::regex targex(target);
60 unsigned count = 0; // A count of matched items
61 for (auto configEntry : map) {
62 std::smatch sm;
63 if (std::regex_search(configEntry.first, sm, targex)) {
64 // Check the section name, and print in full if it matches
65 os << section(configEntry.first) << std::endl << std::endl;
66 for (auto optionEntry : configEntry.second) {
67 os << optionEntry << std::endl;
68 }
69 os << std::endl;
70 ++count;
71 } else {
72 // Check the name of every option. Update optionCount on each match.
73 unsigned optionCount = 0;
74 for (auto optionEntry : configEntry.second) {
75 if (std::regex_search(optionEntry.name, sm, targex))
76 ++optionCount;
77 }
78 if (optionCount) {
79 // If there have been any matches in this section, print the section name…
80 os << section(configEntry.first) << std::endl << std::endl;
81 // Then print the matching options in full by repeating the regex search.
82 for (auto optionEntry : configEntry.second) {
83 if (std::regex_search(optionEntry.name, sm, targex)) {
84 os << optionEntry << std::endl;
85 }
86 }
87 }
88 count += optionCount;
89 }
90 }
91 if (!count) {
92 os << "No configuration options matching \"" << target << "\" were found." << std::endl;
93 }
94 }
95 return os;
96}
97
98std::ostream& ConfigurationHelpPrinter::print(std::ostream& os, const ConfigurationHelp& help)
99{
100 switch (help.type) {
101 case (ConfigType::STRING):
102 return printString(os, help);
103 break;
104 case (ConfigType::NUMERIC):
105 return printNumeric(os, help);
106 break;
107 case (ConfigType::INTEGER):
108 return printInteger(os, help);
109 break;
110 case (ConfigType::MODULE):
111 return printModule(os, help);
112 break;
113 case (ConfigType::BOOLEAN):
114 return printBoolean(os, help);
115 break;
116 default:
117 return os;
118 }
119}
120
121std::ostream& ConfigurationHelpPrinter::printString(std::ostream& os, const ConfigurationHelp& help)
122{
123 os << option(help.name) << std::endl;
124 os << type("string");
125 if (!help.defaultValue.empty()) {
126 os << " (default = " << help.defaultValue << ")";
127 }
128 os << std::endl;
129 os << help.text << std::endl;
130 return os;
131}
132
133std::ostream& ConfigurationHelpPrinter::printNumeric(
134 std::ostream& os, const ConfigurationHelp& help)
135{
136 os << option(help.name) << std::endl;
137 os << type("numeric") + " range: " << help.range[0] << "—" << help.range[1] << " "
138 << help.units;
139 if (!help.defaultValue.empty()) {
140 os << " (default = " << help.defaultValue << ")";
141 }
142 os << std::endl;
143 os << help.text << std::endl;
144 return os;
145}
146
147std::ostream& ConfigurationHelpPrinter::printInteger(
148 std::ostream& os, const ConfigurationHelp& help)
149{
150 os << option(help.name) << std::endl;
151 os << type("integer") + " range: " << help.range[0] << "—" << help.range[1] << " "
152 << help.units;
153 if (!help.defaultValue.empty()) {
154 os << " (default = " << help.defaultValue << ")";
155 }
156 os << std::endl;
157 os << help.text << std::endl;
158 return os;
159}
160
161std::ostream& ConfigurationHelpPrinter::printModule(std::ostream& os, const ConfigurationHelp& help)
162{
163 os << option(help.name) << std::endl;
164 os << type("module") + " [";
165
166 os << defaultVal(help.defaultValue);
167 for (auto impl : help.range) {
168 if (impl != help.defaultValue) {
169 os << ", " << impl;
170 }
171 }
172 os << "]" << std::endl;
173 os << help.text << std::endl;
174 return os;
175}
176std::ostream& ConfigurationHelpPrinter::printBoolean(
177 std::ostream& os, const ConfigurationHelp& help)
178{
179 os << option(help.name) << std::endl;
180 os << type("Boolean") + " ";
181 if (!help.defaultValue.empty()) {
182 os << " (default = " << help.defaultValue << ")";
183 }
184 os << std::endl;
185 os << help.text << std::endl;
186 return os;
187}
188
189static std::string ansiMode(std::string mode) { return "\033[" + mode + "m"; }
190
191void ConfigurationHelpPrinter::setOutput(Output out)
192{
193 if (out == Output::ANSI) {
194 std::string esc = "\033[";
195 std::string cls = "m";
196 b = ansiMode("1");
197 u = ansiMode("4");
198 i = ansiMode("3");
199 h1 = u + b;
200 h2 = u;
201 bEnd = uEnd = iEnd = h1End = h2End = ansiMode("");
202 } else if (out == Output::MARKDOWN) {
203 h1 = "# ";
204 h1End = "";
205 h2 = "## ";
206 h2End = "";
207 b = "**";
208 bEnd = b;
209 i = "_";
210 iEnd = i;
211 // No pure underline in GitHub Markdown
212 }
213}
214
215} /* namespace Nextsim */