From ade49bdcc763849ca6125a556ae60183982ad55a Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Fri, 6 Oct 2017 16:27:36 +0200 Subject: [PATCH] Implement an options parser. --- src/Makefile | 9 ++-- src/Options.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Options.hpp | 25 +++++++++++ src/main.cpp | 6 ++- 4 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 src/Options.cpp create mode 100644 src/Options.hpp diff --git a/src/Makefile b/src/Makefile index 78f4053..0a119ff 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,14 +1,15 @@ .PHONY: all clean # Compilation settings -CXXFLAGS=-Wall -Wextra -pedantic -std=c++14 -g -O2 +CXXFLAGS=-Wall -Wextra -pedantic -std=c++17 -g -O2 LDLIBS= # Project artifacts _EXE=fmri _OBJECTS=\ - main.o + main.o \ + Options.o all: fmri @@ -17,11 +18,11 @@ fmri: $(_OBJECTS) clean: $(RM) *.o *.d - $(RM) + $(RM) $(_EXE) # Automatic header dependency detection %.d: %.cpp - $(CXX) -MM -MF $@ $< + $(CXX) $(CXXFLAGS) -MM -MF $@ $< _DEPFILES=$(patsubst %.cpp, %.d, $(wildcard *.cpp)) -include $(_DEPFILES) diff --git a/src/Options.cpp b/src/Options.cpp new file mode 100644 index 0000000..8555bd3 --- /dev/null +++ b/src/Options.cpp @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include "Options.hpp" + +using namespace fmri; +using namespace std; + +static void show_help(const char* progname, int exitcode) +{ + cerr << "Usage: " << progname << " -m MODEL -w WEIGHTS INPUTS..." << endl + << endl + << R"END( +Simulate the specified network on the specified inputs. + +Options: + -h show this message + -m (required) the model file to simulate + -w (required) the trained weights +)END" << endl; + + exit(exitcode); +} + +static void check_file(const char * filename) +{ + if (access(filename, R_OK) != 0) { + cerr << filename << " could not be read" << endl; + exit(1); + } +} + +Options Options::parse(const int argc, char * const argv[]) +{ + string model; + string weights; + + char c; + + while ((c = getopt(argc, argv, "hm:w:")) != -1) { + switch (c) { + case 'h': + show_help(argv[0], 0); + break; + + case 'w': + check_file(optarg); + weights = optarg; + break; + + case 'm': + check_file(optarg); + model = optarg; + break; + + case '?': + cerr << "Unknown option character: " << char(optopt) << endl; + show_help(argv[0], 1); + break; + + default: + abort(); + } + } + + if (weights.empty()) { + cerr << "Weights file is required!" << endl; + show_help(argv[0], 1); + } + + if (model.empty()) { + cerr << "Model file is required!" << endl; + show_help(argv[0], 1); + } + + for_each(argv + optind, argv + argc, check_file); + + vector inputs(argv + optind, argv + argc); + if (inputs.empty()) { + cerr << "No inputs specified" << endl; + show_help(argv[0], 1); + } + + return Options(move(model), move(weights), move(inputs)); +} + +Options::Options(string&& model, string&& weights, vector&& inputs) noexcept: + modelPath(move(model)), + weightsPath(move(weights)), + inputPaths(move(inputs)) +{ +} + +const string& Options::model() const +{ + return modelPath; +} + +const string& Options::weights() const +{ + return weightsPath; +} + +const vector& Options::inputs() const +{ + return inputPaths; +} diff --git a/src/Options.hpp b/src/Options.hpp new file mode 100644 index 0000000..bbca8b4 --- /dev/null +++ b/src/Options.hpp @@ -0,0 +1,25 @@ +#include +#include + +namespace fmri { + + using std::vector; + using std::string; + + class Options + { + public: + static Options parse(const int argc, char * const argv[]); + + const string& model() const; + const string& weights() const; + const vector& inputs() const; + + private: + const string modelPath; + const string weightsPath; + const vector inputPaths; + + Options(string&&, string&&, vector&&) noexcept; + }; +} diff --git a/src/main.cpp b/src/main.cpp index e3f6716..3c44257 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,12 @@ #include +#include "Options.hpp" using namespace std; +using namespace fmri; -int main(int argc, const char* argv[]) +int main(int argc, char * const argv[]) { - cout << "This is just a test." << endl; + Options options = Options::parse(argc, argv); return 0; }