Use struct to store global application info

This commit is contained in:
Martchus 2019-05-04 22:49:57 +02:00
parent 80fba8b6d4
commit 6d4e13f2dc
3 changed files with 38 additions and 38 deletions

View File

@ -424,18 +424,7 @@ ostream &operator<<(ostream &os, const Wrapper &wrapper)
return os; return os;
} }
/// \brief Specifies the name of the application (used by ArgumentParser::printHelp()). CPP_UTILITIES_EXPORT ApplicationInfo applicationInfo;
const char *applicationName = nullptr;
/// \brief Specifies the author of the application (used by ArgumentParser::printHelp()).
const char *applicationAuthor = nullptr;
/// \brief Specifies the version of the application (used by ArgumentParser::printHelp()).
const char *applicationVersion = nullptr;
/// \brief Specifies the URL to the application website (used by ArgumentParser::printHelp()).
const char *applicationUrl = nullptr;
/// \brief Specifies the dependency versions the application was linked against (used by ArgumentParser::printHelp()).
std::vector<const char *> dependencyVersions;
// TODO v5 use a struct for these properties
/// \cond /// \cond
@ -784,33 +773,34 @@ void ArgumentParser::addMainArgument(Argument *argument)
void ArgumentParser::printHelp(ostream &os) const void ArgumentParser::printHelp(ostream &os) const
{ {
EscapeCodes::setStyle(os, EscapeCodes::TextAttribute::Bold); EscapeCodes::setStyle(os, EscapeCodes::TextAttribute::Bold);
if (applicationName && *applicationName) { if (applicationInfo.name && *applicationInfo.name) {
os << applicationName; os << applicationInfo.name;
if (applicationVersion && *applicationVersion) { if (applicationInfo.version && *applicationInfo.version) {
os << ',' << ' '; os << ',' << ' ';
} }
} }
if (applicationVersion && *applicationVersion) { if (applicationInfo.version && *applicationInfo.version) {
os << "version " << applicationVersion; os << "version " << applicationInfo.version;
} }
if (dependencyVersions.size()) { if (applicationInfo.dependencyVersions.size()) {
if ((applicationName && *applicationName) || (applicationVersion && *applicationVersion)) { if ((applicationInfo.name && *applicationInfo.name) || (applicationInfo.version && *applicationInfo.version)) {
os << '\n'; os << '\n';
EscapeCodes::setStyle(os); EscapeCodes::setStyle(os);
} }
auto i = dependencyVersions.begin(), end = dependencyVersions.end(); auto i = applicationInfo.dependencyVersions.begin(), end = applicationInfo.dependencyVersions.end();
os << "Linked against: " << *i; os << "Linked against: " << *i;
for (++i; i != end; ++i) { for (++i; i != end; ++i) {
os << ',' << ' ' << *i; os << ',' << ' ' << *i;
} }
} }
if ((applicationName && *applicationName) || (applicationVersion && *applicationVersion) || dependencyVersions.size()) { if ((applicationInfo.name && *applicationInfo.name) || (applicationInfo.version && *applicationInfo.version)
|| applicationInfo.dependencyVersions.size()) {
os << '\n' << '\n'; os << '\n' << '\n';
} }
EscapeCodes::setStyle(os); EscapeCodes::setStyle(os);
if (!m_mainArgs.empty()) { if (!m_mainArgs.empty()) {
bool hasOperations = false; bool hasOperations = false;
for (const Argument *arg : m_mainArgs) { for (const Argument *const arg : m_mainArgs) {
if (arg->denotesOperation()) { if (arg->denotesOperation()) {
hasOperations = true; hasOperations = true;
break; break;
@ -821,14 +811,14 @@ void ArgumentParser::printHelp(ostream &os) const
if (hasOperations) { if (hasOperations) {
// split top-level operations and other configurations // split top-level operations and other configurations
os << "Available operations:"; os << "Available operations:";
for (const Argument *arg : m_mainArgs) { for (const Argument *const arg : m_mainArgs) {
if (arg->denotesOperation() && strcmp(arg->name(), "help")) { if (arg->denotesOperation() && strcmp(arg->name(), "help")) {
os << '\n'; os << '\n';
arg->printInfo(os); arg->printInfo(os);
} }
} }
os << "\nAvailable top-level options:"; os << "\nAvailable top-level options:";
for (const Argument *arg : m_mainArgs) { for (const Argument *const arg : m_mainArgs) {
if (!arg->denotesOperation() && strcmp(arg->name(), "help")) { if (!arg->denotesOperation() && strcmp(arg->name(), "help")) {
os << '\n'; os << '\n';
arg->printInfo(os); arg->printInfo(os);
@ -837,7 +827,7 @@ void ArgumentParser::printHelp(ostream &os) const
} else { } else {
// just show all args if no operations are available // just show all args if no operations are available
os << "Available arguments:"; os << "Available arguments:";
for (const Argument *arg : m_mainArgs) { for (const Argument *const arg : m_mainArgs) {
if (strcmp(arg->name(), "help")) { if (strcmp(arg->name(), "help")) {
os << '\n'; os << '\n';
arg->printInfo(os); arg->printInfo(os);
@ -845,8 +835,8 @@ void ArgumentParser::printHelp(ostream &os) const
} }
} }
} }
if (applicationUrl && *applicationUrl) { if (applicationInfo.url && *applicationInfo.url) {
os << "\nProject website: " << applicationUrl << endl; os << "\nProject website: " << applicationInfo.url << endl;
} }
} }

View File

@ -17,11 +17,21 @@ class ArgumentParserTests;
namespace ApplicationUtilities { namespace ApplicationUtilities {
CPP_UTILITIES_EXPORT extern const char *applicationName; /*!
CPP_UTILITIES_EXPORT extern const char *applicationAuthor; * \brief Stores information about an application.
CPP_UTILITIES_EXPORT extern const char *applicationVersion; */
CPP_UTILITIES_EXPORT extern const char *applicationUrl; struct ApplicationInfo {
CPP_UTILITIES_EXPORT extern std::vector<const char *> dependencyVersions; const char *name = nullptr;
const char *author = nullptr;
const char *version = nullptr;
const char *url = nullptr;
std::vector<const char *> dependencyVersions;
};
/*!
* \brief Stores global application info used by ArgumentParser::printHelp() and AboutDialog.
*/
CPP_UTILITIES_EXPORT extern ApplicationInfo applicationInfo;
/*! /*!
* \def SET_DEPENDENCY_INFO * \def SET_DEPENDENCY_INFO
@ -29,7 +39,7 @@ CPP_UTILITIES_EXPORT extern std::vector<const char *> dependencyVersions;
* used by ArgumentParser::printHelp(). * used by ArgumentParser::printHelp().
* \remarks Reads those data from the config header so "config.h" must be included. * \remarks Reads those data from the config header so "config.h" must be included.
*/ */
#define SET_DEPENDENCY_INFO ::ApplicationUtilities::dependencyVersions = DEPENCENCY_VERSIONS #define SET_DEPENDENCY_INFO ::ApplicationUtilities::applicationInfo.dependencyVersions = DEPENCENCY_VERSIONS
/*! /*!
* \def SET_APPLICATION_INFO * \def SET_APPLICATION_INFO
@ -37,10 +47,10 @@ CPP_UTILITIES_EXPORT extern std::vector<const char *> dependencyVersions;
* \remarks Reads those data from the config header so "config.h" must be included. * \remarks Reads those data from the config header so "config.h" must be included.
*/ */
#define SET_APPLICATION_INFO \ #define SET_APPLICATION_INFO \
::ApplicationUtilities::applicationName = APP_NAME; \ ::ApplicationUtilities::applicationInfo.name = APP_NAME; \
::ApplicationUtilities::applicationAuthor = APP_AUTHOR; \ ::ApplicationUtilities::applicationInfo.author = APP_AUTHOR; \
::ApplicationUtilities::applicationVersion = APP_VERSION; \ ::ApplicationUtilities::applicationInfo.version = APP_VERSION; \
::ApplicationUtilities::applicationUrl = APP_URL; \ ::ApplicationUtilities::applicationInfo.url = APP_URL; \
SET_DEPENDENCY_INFO SET_DEPENDENCY_INFO
class Argument; class Argument;

View File

@ -769,7 +769,7 @@ void ArgumentParserTests::testHelp()
envArg.appendValueName("file"); envArg.appendValueName("file");
parser.helpArg().setRequired(true); parser.helpArg().setRequired(true);
parser.setMainArguments({ &verboseArg, &filesArg, &envArg, &parser.noColorArg(), &parser.helpArg() }); parser.setMainArguments({ &verboseArg, &filesArg, &envArg, &parser.noColorArg(), &parser.helpArg() });
dependencyVersions = { "somelib", "some other lib" }; applicationInfo.dependencyVersions = { "somelib", "some other lib" };
// parse args and assert output // parse args and assert output
const char *const argv[] = { "app", "-h" }; const char *const argv[] = { "app", "-h" };