Implement an options parser.

This commit is contained in:
2017-10-06 16:27:36 +02:00
parent ff8788aa0a
commit ade49bdcc7
4 changed files with 142 additions and 6 deletions

View File

@@ -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)

108
src/Options.cpp Normal file
View File

@@ -0,0 +1,108 @@
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#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<string> 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<string>&& 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<string>& Options::inputs() const
{
return inputPaths;
}

25
src/Options.hpp Normal file
View File

@@ -0,0 +1,25 @@
#include <vector>
#include <string>
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<string>& inputs() const;
private:
const string modelPath;
const string weightsPath;
const vector<string> inputPaths;
Options(string&&, string&&, vector<string>&&) noexcept;
};
}

View File

@@ -1,10 +1,12 @@
#include <iostream>
#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;
}