From 22f4c334b7916e2c452e8b800106a50cd1617f84 Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Tue, 10 Mar 2015 14:36:32 +0100 Subject: [PATCH] Adding command line options parser --- src/CLineParser.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/CLineParser.hpp | 43 +++++++++++++++++++++++++ src/CMakeLists.txt | 4 +-- src/main.cpp | 8 +++-- 4 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 src/CLineParser.cpp create mode 100644 src/CLineParser.hpp diff --git a/src/CLineParser.cpp b/src/CLineParser.cpp new file mode 100644 index 0000000..a7afaba --- /dev/null +++ b/src/CLineParser.cpp @@ -0,0 +1,77 @@ +/* + * Monicelli: an esoteric language compiler + * + * Copyright (C) 2014 Stefano Sanfilippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CLineParser.hpp" + +#include +#include +#include +#include + +namespace po = boost::program_options; +using namespace monicelli; + +static po::variables_map CONFIG; +static const std::string VERSION_STRING = + "mcc, Monicelli compiler \n" + "\n" + "Copyright © 2014,2015 Stefano Sanfilippo\n" + "\n" + "This program comes with ABSOLUTELY NO WARRANTY;\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; See LICENSE.txt for all details" +; + +po::variables_map const& monicelli::getConfig() { + return CONFIG; +} + +void monicelli::parseCommandLine(int argc, char **argv) { + po::options_description desc( + std::string("Usage: ") + argv[0] + " [options] file.mc ..." + ); + desc.add_options() + ("help,h", "display this help message") + ("version,v", "display version") + ("input,i", po::value>(), "input files to process") + ; + + po::positional_options_description positional; + positional.add("input", -1); + + po::store( + po::command_line_parser(argc, argv) + .options(desc) + .positional(positional) + .run(), + CONFIG + ); + + po::notify(CONFIG); + + if (configHas("help")) { + std::cout << desc; + exit(0); + } + + if (configHas("version")) { + std::cout << VERSION_STRING << std::endl; + exit(0); + } +} diff --git a/src/CLineParser.hpp b/src/CLineParser.hpp new file mode 100644 index 0000000..46dae91 --- /dev/null +++ b/src/CLineParser.hpp @@ -0,0 +1,43 @@ +#ifndef CLINE_PARSER_HPP +#define CLINE_PARSER_HPP + +/* + * Monicelli: an esoteric language compiler + * + * Copyright (C) 2014 Stefano Sanfilippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +namespace monicelli { + +boost::program_options::variables_map const& getConfig(); + +void parseCommandLine(int argc, char **argv); + +template inline +T config(std::string const& name) { + return getConfig()[name].as(); +} + +static inline +bool configHas(std::string const& name) { + return getConfig().count(name); +} + +} + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ad0d297..76ea90e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,7 +30,7 @@ endif() ## 2. External components -find_package(Boost 1.48 REQUIRED regex system filesystem) +find_package(Boost 1.48 REQUIRED regex system filesystem program_options) find_package(LLVM REQUIRED CONFIG) find_library(YAML_LIBRARIES yaml-cpp) @@ -59,7 +59,7 @@ flex_target(Scanner Monicelli.lpp ${CMAKE_CURRENT_BINARY_DIR}/Lexer.cpp) add_flex_bison_dependency(Scanner Parser) add_executable(mcc - main.cpp Nodes.cpp + main.cpp Nodes.cpp CLineParser.cpp ModuleRegistry.cpp ModuleLoader.cpp ${BISON_Parser_OUTPUTS} ${FLEX_Scanner_OUTPUTS} CppEmitter.cpp BitcodeEmitter.cpp diff --git a/src/main.cpp b/src/main.cpp index d5e5e0d..907d697 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,6 +23,7 @@ #include "ModuleRegistry.hpp" #include "ModuleLoader.hpp" #include "BitcodeEmitter.hpp" +#include "CLineParser.hpp" #include #include @@ -40,6 +41,10 @@ using namespace monicelli; int main(int argc, char **argv) { + parseCommandLine(argc, argv); + + if (!configHas("input")) return 0; + registerStdLib(getModuleRegistry()); boost::regex namere("^(.+)\\.mc$"); @@ -48,8 +53,7 @@ int main(int argc, char **argv) { std::vector sources; std::vector modules; - for (int i = 1; i < argc; ++i) { - std::string arg(argv[i]); + for (std::string const& arg: config>("input")) { if (boost::regex_match(arg, namere)) { sources.push_back(arg); } else if (boost::regex_match(arg, modulere)) {