templates-project_setup/cpp/src/main.cpp

153 lines
4.6 KiB
C++

/**
* @file main.cpp
* @brief Main event loop
*
* Here typically goes a more extensive explanation of what the header defines.
*
* @author Name <email@example.com>
* @copyright (c) Company Name/ Author, YEAR
* @copyright Licensed under the Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>
* @copyright Licensed under the GNU GPLv3 License <http://www.gnu.org/licenses/gpl-3.0.txt>
*/
#include <algorithm>
#include <iostream>
#include <thread>
#include <vector>
#include "version.h"
// static configuration
#define LOGFILE_PATH "ctestapp.log"
#define MAINLOOP_SLEEP_US 1
// other default values
#define LOG_VERBOSE 1
#define LOG_DEBUG 2
#define LOG_MAX 9
/**
* @brief Helper class to parse CLI arguments
*
* CLI arguments can be specified with an equals sign between the parameter name and the
* value, so for `-o=foobar.txt` the option would be `-o`.
*/
struct AppOptions {
int verbosity;
std::string configstring{};
AppOptions(int argc, char* argv[] /* NOLINT(modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) */)
: verbosity{0}, applicationName{argv[0]} {
auto cliArgs = std::vector<std::string>{};
for (int i = 1; i < argc; i++) {
cliArgs.emplace_back(argv[i]);
}
while (!cliArgs.empty()) {
auto arg = *cliArgs.begin();
// find flags (but only at the beginning)
if (0 == arg.find("-h")) {
printUsage();
exit(EXIT_SUCCESS);
break;
}
if (0 == arg.find("-v")) {
this->verbosity = static_cast<int>(std::count(arg.begin(), arg.end(), 'v'));
} else if (0 == arg.find("-d=")) {
this->configstring = arg.substr(arg.find('=') + 1);
} else {
printUsageShort();
std::cerr << "error: unrecognized arguments: " << arg << "\n";
exit(EXIT_FAILURE);
break;
}
// remove the parsed argument from the vector
cliArgs.erase(cliArgs.begin());
}
}
void printUsageShort() {
std::cout << "usage: " << this->applicationName << " ";
std::cout << "[-h] ";
std::cout << "[-v] ";
std::cout << "[-d=SOME_CONFIG]\n";
}
void printUsage() {
printUsageShort();
std::cout << "\n";
std::cout << "optional arguments:\n";
std::cout << " -h, show this help message and exit\n";
std::cout << " -v, increase output verbosity (-vv for VERBOSE)\n";
std::cout << " -d=SOME_CONFIG, TODO config parameter\n";
}
private:
std::string applicationName;
};
int main(int argc, char* argv[]) {
printf("Template C++ App: " GIT_VERSION_TAG "\n\n");
// parse CLI options
AppOptions options(argc, argv);
// start logging
loguru::g_preamble_date = false; // The date field
loguru::g_preamble_time = false; // The time of the current day
loguru::g_preamble_uptime = true; // The time since init call
loguru::g_preamble_thread = false; // The logging thread
loguru::g_preamble_file = true; // The file from which the log originates from
loguru::g_preamble_verbose = true; // The verbosity field
loguru::g_preamble_pipe = true; // The pipe symbol right before the message
loguru::add_file(LOGFILE_PATH, loguru::Truncate, loguru::Verbosity_8);
LOG_F(INFO, "Version " GIT_VERSION_TAG "");
// set stdout verbosity level (0 -> WARNING, 1 -> INFO, 2 -> 1, 3 -> 2, 4 -> MAX)
switch (options.verbosity) {
case 0: // NOLINT(bugprone-branch-clone)
loguru::g_stderr_verbosity = loguru::Verbosity_WARNING; // custom default
break;
case 1: // NOLINT(bugprone-branch-clone)
loguru::g_stderr_verbosity = loguru::Verbosity_INFO; // INFO with -v
break;
case 2: // NOLINT(bugprone-branch-clone)
loguru::g_stderr_verbosity = LOG_VERBOSE; // "verbose" with -vv
break;
case 3: // NOLINT(bugprone-branch-clone)
loguru::g_stderr_verbosity = LOG_DEBUG; // "debug" with -vvv
break;
case 4: // NOLINT(bugprone-branch-clone)
loguru::g_stderr_verbosity = loguru::Verbosity_MAX; // everything with -vvvv
break;
default:
LOG_F(WARNING, "Unrecognised verbosity level %i!", options.verbosity);
break;
}
//
// SETUP
//
// TODO: do some setup here
//
// MAIN LOOP
//
while (true) {
// TODO: do some work here
// very simple ratelimit
std::this_thread::sleep_for(std::chrono::milliseconds(MAINLOOP_SLEEP_US));
}
return EXIT_SUCCESS;
}