Program Listing for File ConfigurationHelpPrinter.cpp¶
↰ Return to documentation for file (core/src/ConfigurationHelpPrinter.cpp)
#include "include/ConfigurationHelpPrinter.hpp"
#include <regex>
namespace Nextsim {
const std::string ConfigurationHelpPrinter::allStr = "all";
const std::string ConfigurationHelpPrinter::availStr = "avail";
static std::string h1 = "";
static std::string h1End = "";
static std::string h2 = "";
static std::string h2End = "";
static std::string b = "";
static std::string u = "";
static std::string i = "";
static std::string bEnd = "";
static std::string uEnd = "";
static std::string iEnd = "";
static std::string section(const std::string& title) { return h1 + title + h1End; }
static std::string option(const std::string& name) { return h2 + name + h2End; }
static std::string defaultVal(const std::string& name) { return b + name + bEnd; }
static std::string type(const std::string& desc) { return i + desc + iEnd; }
std::ostream& ConfigurationHelpPrinter::print(
std::ostream& os, const ConfigurationHelp::HelpMap& map, const std::string& target)
{
if (target == allStr) {
// All configuration help, in full
for (auto configEntry : map) {
os << section(configEntry.first) << std::endl << std::endl;
for (auto optionEntry : configEntry.second) {
os << optionEntry << std::endl;
}
os << std::endl;
}
} else if (target == availStr || target.empty()) {
// Available configuration options, names only
for (auto configEntry : map) {
os << section(configEntry.first) << std::endl;
for (auto optionEntry : configEntry.second) {
os << optionEntry.name << std::endl;
}
os << std::endl;
}
} else {
// Search for a specific option by case sensitive partial match
std::regex targex(target);
unsigned count = 0; // A count of matched items
for (auto configEntry : map) {
std::smatch sm;
if (std::regex_search(configEntry.first, sm, targex)) {
// Check the section name, and print in full if it matches
os << section(configEntry.first) << std::endl << std::endl;
for (auto optionEntry : configEntry.second) {
os << optionEntry << std::endl;
}
os << std::endl;
++count;
} else {
// Check the name of every option. Update optionCount on each match.
unsigned optionCount = 0;
for (auto optionEntry : configEntry.second) {
if (std::regex_search(optionEntry.name, sm, targex))
++optionCount;
}
if (optionCount) {
// If there have been any matches in this section, print the section name…
os << section(configEntry.first) << std::endl << std::endl;
// Then print the matching options in full by repeating the regex search.
for (auto optionEntry : configEntry.second) {
if (std::regex_search(optionEntry.name, sm, targex)) {
os << optionEntry << std::endl;
}
}
}
count += optionCount;
}
}
if (!count) {
os << "No configuration options matching \"" << target << "\" were found." << std::endl;
}
}
return os;
}
std::ostream& ConfigurationHelpPrinter::print(std::ostream& os, const ConfigurationHelp& help)
{
switch (help.type) {
case (ConfigType::STRING):
return printString(os, help);
break;
case (ConfigType::NUMERIC):
return printNumeric(os, help);
break;
case (ConfigType::INTEGER):
return printInteger(os, help);
break;
case (ConfigType::MODULE):
return printModule(os, help);
break;
case (ConfigType::BOOLEAN):
return printBoolean(os, help);
break;
default:
return os;
}
}
std::ostream& ConfigurationHelpPrinter::printString(std::ostream& os, const ConfigurationHelp& help)
{
os << option(help.name) << std::endl;
os << type("string");
if (!help.defaultValue.empty()) {
os << " (default = " << help.defaultValue << ")";
}
os << std::endl;
os << help.text << std::endl;
return os;
}
std::ostream& ConfigurationHelpPrinter::printNumeric(
std::ostream& os, const ConfigurationHelp& help)
{
os << option(help.name) << std::endl;
os << type("numeric") + " range: " << help.range[0] << "—" << help.range[1] << " "
<< help.units;
if (!help.defaultValue.empty()) {
os << " (default = " << help.defaultValue << ")";
}
os << std::endl;
os << help.text << std::endl;
return os;
}
std::ostream& ConfigurationHelpPrinter::printInteger(
std::ostream& os, const ConfigurationHelp& help)
{
os << option(help.name) << std::endl;
os << type("integer") + " range: " << help.range[0] << "—" << help.range[1] << " "
<< help.units;
if (!help.defaultValue.empty()) {
os << " (default = " << help.defaultValue << ")";
}
os << std::endl;
os << help.text << std::endl;
return os;
}
std::ostream& ConfigurationHelpPrinter::printModule(std::ostream& os, const ConfigurationHelp& help)
{
os << option(help.name) << std::endl;
os << type("module") + " [";
os << defaultVal(help.defaultValue);
for (auto impl : help.range) {
if (impl != help.defaultValue) {
os << ", " << impl;
}
}
os << "]" << std::endl;
os << help.text << std::endl;
return os;
}
std::ostream& ConfigurationHelpPrinter::printBoolean(
std::ostream& os, const ConfigurationHelp& help)
{
os << option(help.name) << std::endl;
os << type("Boolean") + " ";
if (!help.defaultValue.empty()) {
os << " (default = " << help.defaultValue << ")";
}
os << std::endl;
os << help.text << std::endl;
return os;
}
static std::string ansiMode(std::string mode) { return "\033[" + mode + "m"; }
void ConfigurationHelpPrinter::setOutput(Output out)
{
if (out == Output::ANSI) {
std::string esc = "\033[";
std::string cls = "m";
b = ansiMode("1");
u = ansiMode("4");
i = ansiMode("3");
h1 = u + b;
h2 = u;
bEnd = uEnd = iEnd = h1End = h2End = ansiMode("");
} else if (out == Output::MARKDOWN) {
h1 = "# ";
h1End = "";
h2 = "## ";
h2End = "";
b = "**";
bEnd = b;
i = "_";
iEnd = i;
// No pure underline in GitHub Markdown
}
}
} /* namespace Nextsim */