/** * @file main.cpp * @brief Main event loop * * Here typically goes a more extensive explanation of what the header defines. * * @author Name * @copyright (c) Company Name/ Author, YEAR * @copyright Licensed under the Apache License, Version 2.0 * @copyright Licensed under the GNU GPLv3 License */ #include #include #include #include #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{}; 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(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; }