#include "options.hpp" #include "backend.hpp" #include "log.hpp" #include "thirdparty/CLI11.hpp" #include "data.h" #include "license.hpp" #include "assets/assets.h" using namespace Looper; using namespace Looper::Options; using namespace Looper::Log; std::unordered_set license_data; std::unordered_set &get_license_data() { return license_data; } int main(int argc, char **argv) { std::vector args; for (int i = 1; i < argc; i++) { args.push_back(std::string(argv[i])); } CLI::App app{DESCRIPTION}; std::string filename = ""; app.allow_extras(); int log_level; std::string ui_backend_option = ""; bool full_help = false; app.add_option("-l, --log-level", LogStream::log_level, "Sets the minimum log level to display in the logs."); app.add_option("-u, --ui-backend", ui_backend_option, "Specifies which UI backend to use."); try { app.parse(args); } catch (const CLI::ParseError &e) { if (app.get_help_ptr()->get_callback_run()) { full_help = true; } else { exit(app.exit(e)); } } args.clear(); args = app.remaining(false); int new_argc = args.size(); char **new_argv = (char**)malloc(new_argc * sizeof(char*)); init_logging(); { auto looper_mit = LicenseData("Looper (MIT)", "MIT"); auto looper_gpl = LicenseData("Looper (GPL)", "GPL-3.0-or-later"); auto looper = LicenseData("Looper", "MIT OR GPL-3.0-or-later"); auto tomlpp = LicenseData("TOML++", "MIT"); auto smx = LicenseData("SDL Mixer X", "Zlib"); auto cli11 = LicenseData("CLI11", "BSD-3-Clause"); auto jsoncpp = LicenseData("JsonCpp", "MIT"); auto soundtouch = LicenseData("SoundTouch", "LGPL-2.1-only"); LOAD_LICENSE(looper_mit, looper_mit); LOAD_LICENSE(looper_gpl, looper_gpl); LOAD_LICENSE(looper, looper); LOAD_LICENSE(tomlpp, tomlplusplus); LOAD_LICENSE(smx, sdl_mixer_x); LOAD_LICENSE(cli11, cli11); LOAD_LICENSE(jsoncpp, jsoncpp); LOAD_LICENSE(soundtouch, lgpl_2_1); license_data.insert(looper); license_data.insert(looper_gpl); license_data.insert(looper_mit); license_data.insert(tomlpp); license_data.insert(smx); license_data.insert(cli11); license_data.insert(jsoncpp); license_data.insert(soundtouch); } DEBUG.writeln("Command line arguments after first parse:"); for (size_t i = 0; i < new_argc; i++) { auto &arg = args[i]; DEBUG.writefln(" - '%s'", arg.c_str()); new_argv[i] = strdup(arg.c_str()); } DEBUG.writeln("Initializing frontends..."); init_backends(); DEBUG.writeln("Loaded frontends: "); for (auto kv : UIBackend::backends) { kv.second->add_licenses(); DEBUG.writefln(" - '%s'", kv.first.c_str()); } DEBUG.writeln("Loading options file..."); load_options(); std::string backend_id = get_option("ui.frontend", "imgui"); UIBackend *backend = UIBackend::get_backend(ui_backend_option).value_or(UIBackend::get_backend(backend_id).value_or(UIBackend::get_first_backend())); int output = 0; if (backend == nullptr) { ERROR.writeln("No UI backend could be found."); return -1; } else { DEBUG.writefln("Using backend: '%s'...", backend->get_id().c_str()); if (full_help) { args.clear(); args.push_back("--help"); } try { output = backend->run(args, new_argc, new_argv); } catch (int return_code) { if (full_help) { std::string helpstr = app.help(); helpstr = helpstr.substr(helpstr.find("\n") + 1); helpstr = helpstr.substr(helpstr.find("\n") + 1); helpstr = helpstr.substr(helpstr.find("\n") + 1); helpstr = helpstr.substr(helpstr.find("\n") + 1); helpstr = helpstr.substr(helpstr.find("\n") + 1); printf(helpstr.c_str()); } output = return_code; } } DEBUG.writeln("Exiting..."); UIBackend::deinit_backends(); for (int i = 0; i < new_argc; i++) { free(new_argv[i]); } free(new_argv); save_options(); return output; }