26constexpr const char*
copyright =
"Copyright (C) 2024-"
28 " Andrew S. Rightenburg\n\n"
29 "This program is free software; you can redistribute it and/or modify\n"
30 "it under the terms of the GNU General Public License as published by\n"
31 "the Free Software Foundation; either version 3 of the License, or\n"
32 "(at your option) any later version.\n\n"
33 "This program is distributed in the hope that it will be useful,\n"
34 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
35 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
36 "GNU General Public License for more details.\n\n"
37 "You should have received a copy of the GNU General Public License\n"
38 "along with this program. If not, see http://www.gnu.org/licenses/.\n";
41 "Usage: bpp [options] [file] ...\n"
42 "If no file is specified, read from stdin\n"
43 "All arguments after the file are passed to the compiled program\n"
72 std::shared_ptr<std::vector<std::string>>
m_include_paths = std::make_shared<std::vector<std::string>>();
93 auto arguments_span = std::span<char*>{argv,
static_cast<size_t>(argc)};
94 this->m_program_arguments = std::vector<char*>(arguments_span.begin(), arguments_span.end());
112 throw std::runtime_error(
"Source file '" + std::string(
input_file) +
"' does not exist");
114 if (!std::filesystem::is_regular_file(
input_file)) {
115 throw std::runtime_error(
"Source file '" + std::string(
input_file) +
"' is not a regular file");
134 if (output_file_arg ==
"-") {
135 this->m_output_file = output_file_arg;
139 std::string parsed_output_file;
142 std::filesystem::path output_path(output_file_arg);
143 if (output_path.is_absolute()) {
144 parsed_output_file = output_path.string();
146 parsed_output_file = std::filesystem::current_path() / output_path;
153 if (std::filesystem::exists(parsed_output_file)) {
154 if (access(parsed_output_file.c_str(), W_OK) != 0) {
155 throw std::runtime_error(
"No write permission for output file '" + parsed_output_file +
"'");
158 std::filesystem::path parent_path = std::filesystem::path(parsed_output_file).parent_path();
159 if (!std::filesystem::exists(parent_path) || !std::filesystem::is_directory(parent_path)) {
160 throw std::runtime_error(
"Parent directory of output file '" + parsed_output_file +
"' does not exist or is not a directory");
162 if (access(parent_path.c_str(), W_OK) != 0) {
163 throw std::runtime_error(
"No write permission for parent directory of output file '" + parsed_output_file +
"'");
166 }
catch (
const std::exception& e) {
167 throw std::runtime_error(std::string(
"Could not verify write permission for output file '") + parsed_output_file +
"': " + e.what());
170 this->m_output_file = parsed_output_file;
186 this->m_target_bash_version =
BashVersion(version_arg);
204 if (!std::filesystem::is_directory(path)) {
205 throw std::runtime_error(
"Include path '" + std::string(path) +
"' is not a directory");
207 this->m_include_paths->emplace_back(path);
214 this->f_suppress_warnings = suppress;
221 this->f_display_tokens = display;
228 this->f_display_parse_tree = display;
235 this->f_exit_early = exit;
249 return this->m_output_file ==
"-";
253 return this->m_output_file.has_value() && this->m_output_file.value() !=
"-";
257 return !this->m_input_file.has_value();
265 auto [compiler_arguments, program_arguments]
270 if (compiler_arguments.getNonOptionArguments().size() > 0) {
271 args.
set_input_file(compiler_arguments.getNonOptionArguments()[0]);
274 for (
const auto& arg : compiler_arguments) {
275 switch (arg.getShortOpt()) {
278 std::cerr <<
program_name <<
": Warning: Unhandled option '" <<
static_cast<char>(arg.getShortOpt()) <<
"'" << std::endl;
Represents the parsed command-line arguments given to the compiler.
Definition parse_arguments.h:66
void set_suppress_warnings(bool suppress)
Definition parse_arguments.h:213
void set_run_on_exit(bool run_on_exit)
Definition parse_arguments.h:241
void add_include_path(std::string_view path)
Adds a directory to the include paths.
Definition parse_arguments.h:203
void set_display_parse_tree(bool display)
Definition parse_arguments.h:227
bool run_on_exit() const
Definition parse_arguments.h:244
bool display_parse_tree() const
Definition parse_arguments.h:230
std::vector< char * > m_program_arguments
Definition parse_arguments.h:68
bool exit_early() const
Definition parse_arguments.h:237
const std::optional< std::string > & output_file() const
Definition parse_arguments.h:172
bool f_exit_early
Definition parse_arguments.h:77
std::optional< std::string > m_input_file
Definition parse_arguments.h:69
void set_program_arguments(int argc, char **argv)
Sets the program arguments to be passed to the compiled program.
Definition parse_arguments.h:92
bool suppress_warnings() const
Definition parse_arguments.h:216
void set_input_file(std::string_view input_file)
Sets the input file for the compiler.
Definition parse_arguments.h:109
const std::vector< char * > & program_arguments() const
Definition parse_arguments.h:96
bool f_display_parse_tree
Definition parse_arguments.h:75
void set_display_tokens(bool display)
Definition parse_arguments.h:220
bool f_display_tokens
Definition parse_arguments.h:74
bool output_to_file() const
Definition parse_arguments.h:252
void set_target_bash_version(std::string_view version_arg)
Parses a given target Bash version argument and updates the Arguments object accordingly.
Definition parse_arguments.h:185
const std::optional< std::string > & input_file() const
Definition parse_arguments.h:119
bool input_from_stdin() const
Definition parse_arguments.h:256
std::shared_ptr< std::vector< std::string > > m_include_paths
Definition parse_arguments.h:72
const BashVersion & target_bash_version() const
Definition parse_arguments.h:188
void set_output_file(std::string_view output_file_arg)
Parses a given output_file argument and updates the Arguments object accordingly.
Definition parse_arguments.h:133
std::optional< std::string > m_output_file
Definition parse_arguments.h:70
bool f_run_on_exit
Definition parse_arguments.h:76
bool f_suppress_warnings
Definition parse_arguments.h:73
void set_exit_early(bool exit)
Definition parse_arguments.h:234
const std::shared_ptr< std::vector< std::string > > & include_paths() const
Definition parse_arguments.h:209
bool display_tokens() const
Definition parse_arguments.h:223
bool output_to_stdout() const
Definition parse_arguments.h:248
BashVersion m_target_bash_version
Definition parse_arguments.h:71
Parses command-line arguments based on a set of defined options.
Definition xgetopt.h:548
@ NoArgument
Definition xgetopt.h:187
@ RequiredArgument
Definition xgetopt.h:188
@ AfterFirstNonOptionArgument
Definition xgetopt.h:532
Arguments parse_arguments(int argc, char *argv[])
Definition parse_arguments.h:261
constexpr XGetOpt::OptionParser< XGetOpt::Option< 'o', "output", "Specify output file (default: run on exit)", XGetOpt::RequiredArgument, "file">, XGetOpt::Option< 'b', "target-bash", "Compile to Bash version (default: 5.2)", XGetOpt::RequiredArgument, "version">, XGetOpt::Option< 's', "no-warnings", "Suppress warnings", XGetOpt::NoArgument >, XGetOpt::Option< 'I', "include", "Add directory to include path", XGetOpt::RequiredArgument, "directory">, XGetOpt::Option< 't', "tokens", "Display tokens from lexer (do not compile program)", XGetOpt::NoArgument >, XGetOpt::Option< 'p', "parse-tree", "Display parse tree (do not compile program)", XGetOpt::NoArgument >, XGetOpt::Option< 'v', "version", "Display version information and exit", XGetOpt::NoArgument >, XGetOpt::Option< 'h', "help", "Display this help message and exit", XGetOpt::NoArgument > > OptionParser
Definition parse_arguments.h:55
constexpr const char * help_intro
Definition parse_arguments.h:40
constexpr const char * copyright
Definition parse_arguments.h:26
constexpr const char * program_name
Definition parse_arguments.h:24
Represents a Bash version to target for code generation.
Definition BashVersion.h:22
Compile-time representation of a command-line option.
Definition xgetopt.h:208
#define bpp_compiler_updated_year
Definition updated_year.h:1
#define bpp_compiler_version
Definition version.h:1