/* * simulator.cc - Implementation of the HorizonScript simulation utility * Project Horizon * * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * * SPDX-License-Identifier: AGPL-3.0-only */ #include #include #include "hscript/script.hh" #include "util/output.hh" bool pretty = false; int main(int argc, char *argv[]) { const Horizon::Script *my_script; Horizon::ScriptOptions opts; int result_code = EXIT_SUCCESS; std::string installfile; bool strict{}, needs_help{}, disable_pretty{}, version_only{}; using Horizon::ScriptOptionFlags; using namespace boost::program_options; /* Default to pretty if we are using a TTY, unless -n specified. */ if(isatty(1) && isatty(2)) { pretty = true; /* LCOV_EXCL_LINE */ } opts.set(ScriptOptionFlags::Simulate); options_description cli_hidden; cli_hidden.add_options() ("installfile", "Installfile to load"); options_description cli_visible("Allowed options"); cli_visible.add_options() ("help,h", bool_switch(&needs_help), "Display this message.") ("version,v", bool_switch(&version_only), "Show program version information.") ("no-colour,n", bool_switch(&disable_pretty), "Do not 'prettify' output.") ("strict,s", bool_switch(&strict), "Use strict parsing mode (enable more warnings/errors)."); options_description cli; cli.add(cli_visible).add(cli_hidden); positional_options_description cli_pos; cli_pos.add("installfile", -1); variables_map args; try { store( command_line_parser(argc, argv) .options(cli) .positional(cli_pos) .run(), args); notify(args); } catch(const boost::program_options::error& cli_err) { std::cerr << cli_err.what() << std::endl; needs_help = true; result_code = EXIT_FAILURE; } if(needs_help) { std::cout << cli_visible << std::endl; return result_code; } if(disable_pretty) { pretty = false; } if(strict) { opts.set(ScriptOptionFlags::StrictMode); } if(!isatty(1)) { std::cout << "#!/bin/sh" << std::endl << std::endl; } bold_if_pretty(std::cout); if(!isatty(1)) std::cout << "# Generated by "; std::cout << "HorizonScript Simulation Utility version " << VERSTR; #ifndef HAS_INSTALL_ENV std::cout << " (runtime environment only)"; #endif #ifdef NON_LIBRE_FIRMWARE colour_if_pretty(std::cout, "31"); std::cout << " (supports non-free firmware)"; #endif reset_if_pretty(std::cout); std::cout << std::endl; if(isatty(1)) { /* LCOV_EXCL_START */ std::cout << "Copyright (c) 2019-2020 Adélie Linux and contributors." << std::endl << "This software is licensed to you under the terms of the " << std::endl << "AGPL 3.0 license, unless otherwise noted." << std::endl << std::endl; } /* LCOV_EXCL_STOP */ if(version_only) { return EXIT_SUCCESS; } if(args.count("installfile")) { installfile = args["installfile"].as(); } else { output_error("", "You must specify an installfile"); return EXIT_FAILURE; } my_script = Horizon::Script::load(installfile, opts); if(my_script == nullptr) { output_error(installfile, "Could not load the specified script"); return EXIT_FAILURE; } if(!my_script->execute()) { output_error("internal", "Script failed. Stop."); result_code = EXIT_FAILURE; } else { output_info("internal", "Script completed successfully."); } delete my_script; return result_code; }