You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

136 lines
3.8 KiB

/*****************************************************************************
*
* demo program - part of CLIPP (command line interfaces for modern C++)
*
* released under MIT license
*
* (c) 2017-2018 André Müller; foss@andremueller-online.de
*
*****************************************************************************/
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include <clipp.h>
//-------------------------------------------------------------------
enum class mode {
none, train, validate, classify
};
struct settings {
mode selected = mode::none;
std::string imageFile;
std::string labelFile;
std::string modelFile = "out.mdl";
std::size_t batchSize = 128;
std::size_t threads = 0;
std::size_t inputLimit = 0;
std::vector<std::string> inputFiles;
};
//-------------------------------------------------------------------
settings configuration(int argc, char* argv[])
{
using namespace clipp;
settings s;
std::vector<std::string> unrecognized;
auto isfilename = clipp::match::prefix_not("-");
auto inputOptions = (
required("-i", "-I", "--img") & !value(isfilename, "image file", s.imageFile),
required("-l", "-L", "--lbl") & !value(isfilename, "label file", s.labelFile)
);
auto trainMode = (
command("train", "t", "T").set(s.selected,mode::train)
.if_conflicted([]{std::cerr << "conflicting modes\n"; }),
inputOptions,
(option("-n") & integer("limit", s.inputLimit))
% "limit number of input images",
(option("-o", "-O", "--out") & !value("model file", s.modelFile))
% "write model to specific file; default: 'out.mdl'",
(option("-b", "--batch-size") & integer("batch size", s.batchSize)),
(option("-p") & integer("threads", s.threads))
% "number of threads to use; default: optimum for machine"
);
auto validationMode = (
command("validate", "v", "V").set(s.selected,mode::validate),
!value(isfilename, "model", s.modelFile),
inputOptions
);
auto classificationMode = (
command("classify", "c", "C").set(s.selected,mode::classify),
!value(isfilename, "model", s.modelFile),
!values(isfilename, "images", s.inputFiles)
);
auto cli = (
trainMode | validationMode | classificationMode,
any_other(unrecognized)
);
auto res = parse(argc, argv, cli);
debug::print(std::cout, res);
if(!res || !unrecognized.empty()) {
std::string msg = "Wrong command line arguments!\n";
if(s.selected == mode::none) {
msg += "Please select a mode!\n";
}
else {
for(const auto& m : res.missing()) {
if(!m.param()->flags().empty()) {
msg += "Missing option: " + m.param()->flags().front() + '\n';
}
else if(!m.param()->label().empty()) {
msg += "Missing value: " + m.param()->label() + '\n';
}
}
for(const auto& arg : unrecognized) {
msg += "Argument not recognized: " + arg + '\n';
}
}
auto fmt = doc_formatting{}.first_column(8).doc_column(16);
//.max_flags_per_param_in_usage(3).surround_alternative_flags("(", ")");
msg += "\nUsage:\n" + usage_lines(cli, argv[0], fmt).str() + '\n';
msg += "\nOptions:\n" + documentation(cli, fmt).str() + '\n';
throw std::invalid_argument{msg};
}
return s;
}
//-------------------------------------------------------------------
int main(int argc, char* argv[])
{
try {
auto conf = configuration(argc, argv);
std::cout << "SUCCESS\n";
}
catch(std::exception& e) {
std::cerr << "ERROR: " << e.what() << '\n';
}
}