From bdc20c1b20ab79fb8f64191ab85949a97712ccb4 Mon Sep 17 00:00:00 2001 From: Frank Bossen <fbossen@gmail.com> Date: Thu, 18 May 2023 09:24:48 -0400 Subject: [PATCH] Rename df::program_options_lite as ProgramOptionsLite --- .../BitstreamExtractorAppCfg.cpp | 3 +- .../bitstreamextractormain.cpp | 6 +- source/App/DecoderApp/DecAppCfg.cpp | 2 +- source/App/DecoderApp/decmain.cpp | 6 +- source/App/EncoderApp/EncAppCfg.cpp | 2 +- source/App/EncoderApp/EncAppCfg.h | 2 +- source/App/EncoderApp/encmain.cpp | 10 +- .../SEIFilmGrainApp/SEIFilmGrainAppCfg.cpp | 2 +- .../App/SEIFilmGrainApp/SEIFilmGrainMain.cpp | 6 +- source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp | 2 +- source/App/SEIRemovalApp/seiremovalmain.cpp | 6 +- .../App/StreamMergeApp/StreamMergeAppCfg.cpp | 2 +- source/App/SubpicMergeApp/SubpicMergeMain.cpp | 7 +- source/Lib/CommonLib/CacheModel.cpp | 2 +- source/Lib/Utilities/program_options_lite.cpp | 891 +++++++++--------- source/Lib/Utilities/program_options_lite.h | 424 ++++----- 16 files changed, 661 insertions(+), 712 deletions(-) diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp index 586ee2d1cd..9d40a72557 100644 --- a/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp +++ b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp @@ -42,8 +42,7 @@ #include "CommonLib/dtrace_next.h" #endif -namespace po = df::program_options_lite; - +namespace po = ProgramOptionsLite; // ==================================================================================================================== // Public member functions diff --git a/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp b/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp index d04641cad7..cc7383def8 100644 --- a/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp +++ b/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp @@ -54,10 +54,10 @@ int main(int argc, char* argv[]) fprintf( stdout, NVM_BITS ); #if ENABLE_SIMD_OPT std::string SIMD; - df::program_options_lite::Options optsSimd; + ProgramOptionsLite::Options optsSimd; optsSimd.addOptions()( "SIMD", SIMD, std::string( "" ), "" ); - df::program_options_lite::SilentReporter err; - df::program_options_lite::scanArgv( optsSimd, argc, ( const char** ) argv, err ); + ProgramOptionsLite::SilentReporter err; + ProgramOptionsLite::scanArgv(optsSimd, argc, (const char**) argv, err); fprintf( stdout, "[SIMD=%s] ", read_x86_extension( SIMD ) ); #endif #if ENABLE_TRACING diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp index c679504eaf..ea36f3662b 100644 --- a/source/App/DecoderApp/DecAppCfg.cpp +++ b/source/App/DecoderApp/DecAppCfg.cpp @@ -44,7 +44,7 @@ #include "CommonLib/ChromaFormat.h" #include "CommonLib/dtrace_next.h" -namespace po = df::program_options_lite; +namespace po = ProgramOptionsLite; //! \ingroup DecoderApp //! \{ diff --git a/source/App/DecoderApp/decmain.cpp b/source/App/DecoderApp/decmain.cpp index bc765bbd92..09cbd0564b 100644 --- a/source/App/DecoderApp/decmain.cpp +++ b/source/App/DecoderApp/decmain.cpp @@ -60,10 +60,10 @@ int main(int argc, char* argv[]) fprintf( stdout, NVM_BITS ); #if ENABLE_SIMD_OPT std::string SIMD; - df::program_options_lite::Options optsSimd; + ProgramOptionsLite::Options optsSimd; optsSimd.addOptions()("SIMD", SIMD, std::string(""), ""); - df::program_options_lite::SilentReporter err; - df::program_options_lite::scanArgv( optsSimd, argc, ( const char** ) argv, err ); + ProgramOptionsLite::SilentReporter err; + ProgramOptionsLite::scanArgv(optsSimd, argc, (const char**) argv, err); fprintf( stdout, "[SIMD=%s] ", read_x86_extension( SIMD ) ); #endif #if ENABLE_TRACING diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index c23d4da32e..662213c865 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -55,7 +55,7 @@ #define MACRO_TO_STRING_HELPER(val) #val #define MACRO_TO_STRING(val) MACRO_TO_STRING_HELPER(val) -namespace po = df::program_options_lite; +namespace po = ProgramOptionsLite; enum ExtendedProfileName // this is used for determining profile strings, where multiple profiles map to a single // profile idc with various constraint flag combinations diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 393d122076..d799d7046f 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -58,7 +58,7 @@ static inline std::istream& operator >> (std::istream &in, std::map<T1, T2> &map #undef UNDEFINED #endif #endif -namespace po = df::program_options_lite; +namespace po = ProgramOptionsLite; #include <sstream> #include <vector> diff --git a/source/App/EncoderApp/encmain.cpp b/source/App/EncoderApp/encmain.cpp index a0329ef1d5..971aef526a 100644 --- a/source/App/EncoderApp/encmain.cpp +++ b/source/App/EncoderApp/encmain.cpp @@ -90,10 +90,10 @@ int main(int argc, char* argv[]) fprintf( stdout, NVM_BITS ); #if ENABLE_SIMD_OPT std::string SIMD; - df::program_options_lite::Options opts; - opts.addOptions()("SIMD", SIMD, std::string(""), "")("c", df::program_options_lite::parseConfigFile, ""); - df::program_options_lite::SilentReporter err; - df::program_options_lite::scanArgv( opts, argc, ( const char** ) argv, err ); + ProgramOptionsLite::Options opts; + opts.addOptions()("SIMD", SIMD, std::string(""), "")("c", ProgramOptionsLite::parseConfigFile, ""); + ProgramOptionsLite::SilentReporter err; + ProgramOptionsLite::scanArgv(opts, argc, (const char**) argv, err); fprintf( stdout, "[SIMD=%s] ", read_x86_extension( SIMD ) ); #endif #if ENABLE_TRACING @@ -167,7 +167,7 @@ int main(int argc, char* argv[]) return 1; } } - catch( df::program_options_lite::ParseFailure &e ) + catch (ProgramOptionsLite::ParseFailure& e) { std::cerr << "Error parsing option \"" << e.arg << "\" with argument \"" << e.val << "\"." << std::endl; return 1; diff --git a/source/App/SEIFilmGrainApp/SEIFilmGrainAppCfg.cpp b/source/App/SEIFilmGrainApp/SEIFilmGrainAppCfg.cpp index 3f5a6da545..c21a1c0894 100644 --- a/source/App/SEIFilmGrainApp/SEIFilmGrainAppCfg.cpp +++ b/source/App/SEIFilmGrainApp/SEIFilmGrainAppCfg.cpp @@ -44,7 +44,7 @@ #include "CommonLib/dtrace_next.h" #endif -namespace po = df::program_options_lite; +namespace po = ProgramOptionsLite; //! \ingroup SEIFilmGrainApp //! \{ diff --git a/source/App/SEIFilmGrainApp/SEIFilmGrainMain.cpp b/source/App/SEIFilmGrainApp/SEIFilmGrainMain.cpp index 0fafd98a92..7f8c14bb7d 100644 --- a/source/App/SEIFilmGrainApp/SEIFilmGrainMain.cpp +++ b/source/App/SEIFilmGrainApp/SEIFilmGrainMain.cpp @@ -59,10 +59,10 @@ int main(int argc, char* argv[]) fprintf( stdout, NVM_BITS ); #if ENABLE_SIMD_OPT std::string SIMD; - df::program_options_lite::Options optsSimd; + ProgramOptionsLite::Options optsSimd; optsSimd.addOptions()("SIMD", SIMD, std::string(""), ""); - df::program_options_lite::SilentReporter err; - df::program_options_lite::scanArgv( optsSimd, argc, ( const char** ) argv, err ); + ProgramOptionsLite::SilentReporter err; + ProgramOptionsLite::scanArgv(optsSimd, argc, (const char**) argv, err); fprintf( stdout, "[SIMD=%s] ", read_x86_extension( SIMD ) ); #endif #if ENABLE_TRACING diff --git a/source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp b/source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp index 24b587b7dc..be44505813 100644 --- a/source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp +++ b/source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp @@ -41,7 +41,7 @@ #include "SEIRemovalAppCfg.h" #include "Utilities/program_options_lite.h" -namespace po = df::program_options_lite; +namespace po = ProgramOptionsLite; //! \ingroup DecoderApp //! \{ diff --git a/source/App/SEIRemovalApp/seiremovalmain.cpp b/source/App/SEIRemovalApp/seiremovalmain.cpp index b2dd387ba4..910e3d20d5 100644 --- a/source/App/SEIRemovalApp/seiremovalmain.cpp +++ b/source/App/SEIRemovalApp/seiremovalmain.cpp @@ -60,10 +60,10 @@ int main(int argc, char* argv[]) fprintf( stdout, NVM_BITS ); #if ENABLE_SIMD_OPT std::string SIMD; - df::program_options_lite::Options optsSimd; + ProgramOptionsLite::Options optsSimd; optsSimd.addOptions()("SIMD", SIMD, std::string(""), ""); - df::program_options_lite::SilentReporter err; - df::program_options_lite::scanArgv( optsSimd, argc, ( const char** ) argv, err ); + ProgramOptionsLite::SilentReporter err; + ProgramOptionsLite::scanArgv(optsSimd, argc, (const char**) argv, err); fprintf( stdout, "[SIMD=%s] ", read_x86_extension( SIMD ) ); #endif #if ENABLE_TRACING diff --git a/source/App/StreamMergeApp/StreamMergeAppCfg.cpp b/source/App/StreamMergeApp/StreamMergeAppCfg.cpp index 14605d03d1..74ac006dcd 100644 --- a/source/App/StreamMergeApp/StreamMergeAppCfg.cpp +++ b/source/App/StreamMergeApp/StreamMergeAppCfg.cpp @@ -41,7 +41,7 @@ #include "StreamMergeAppCfg.h" #include "Utilities/program_options_lite.h" -namespace po = df::program_options_lite; +namespace po = ProgramOptionsLite; //! \ingroup DecoderApp //! \{ diff --git a/source/App/SubpicMergeApp/SubpicMergeMain.cpp b/source/App/SubpicMergeApp/SubpicMergeMain.cpp index 9743ba8522..576a728bfb 100644 --- a/source/App/SubpicMergeApp/SubpicMergeMain.cpp +++ b/source/App/SubpicMergeApp/SubpicMergeMain.cpp @@ -47,11 +47,10 @@ #include "Utilities/program_options_lite.h" #include "SubpicMergeApp.h" +namespace po = ProgramOptionsLite; -namespace po = df::program_options_lite; - - //! \ingroup SubpicMergeApp - //! \{ +//! \ingroup SubpicMergeApp +//! \{ /** diff --git a/source/Lib/CommonLib/CacheModel.cpp b/source/Lib/CommonLib/CacheModel.cpp index 7678cfb1d0..60658afe0d 100644 --- a/source/Lib/CommonLib/CacheModel.cpp +++ b/source/Lib/CommonLib/CacheModel.cpp @@ -62,7 +62,7 @@ enum CacheAddressMap MAX_NUM_CACHE_MODE }; -namespace po = df::program_options_lite; +namespace po = ProgramOptionsLite; CacheModel::CacheModel() { diff --git a/source/Lib/Utilities/program_options_lite.cpp b/source/Lib/Utilities/program_options_lite.cpp index b0b617addd..6e5287b4ec 100644 --- a/source/Lib/Utilities/program_options_lite.cpp +++ b/source/Lib/Utilities/program_options_lite.cpp @@ -40,536 +40,519 @@ #include <algorithm> #include "program_options_lite.h" -//! \ingroup TAppCommon -//! \{ +namespace ProgramOptionsLite +{ +ErrorReporter default_error_reporter; + +std::ostream& ErrorReporter::error(const std::string& where) +{ + is_errored = 1; + std::cerr << where << " error: "; + return std::cerr; +} + +std::ostream& ErrorReporter::warn(const std::string& where) +{ + std::cerr << where << " warning: "; + return std::cerr; +} -namespace df +Options::~Options() { - namespace program_options_lite + for (Options::NamesPtrList::iterator it = opt_list.begin(); it != opt_list.end(); it++) { - ErrorReporter default_error_reporter; + delete *it; + } +} - std::ostream &ErrorReporter::error(const std::string &where) +void Options::addOption(OptionBase* opt) +{ + Names* names = new Names(); + names->opt = opt; + std::string& opt_string = opt->opt_string; + + size_t opt_start = 0; + for (size_t opt_end = 0; opt_end != std::string::npos;) + { + opt_end = opt_string.find_first_of(',', opt_start); + bool force_short = 0; + if (opt_string[opt_start] == '-') { - is_errored = 1; - std::cerr << where << " error: "; - return std::cerr; + opt_start++; + force_short = 1; } - - std::ostream &ErrorReporter::warn(const std::string &where) + std::string opt_name = opt_string.substr(opt_start, opt_end - opt_start); + if (force_short || opt_name.size() == 1) { - std::cerr << where << " warning: "; - return std::cerr; + names->opt_short.push_back(opt_name); + opt_short_map[opt_name].push_back(names); } - - Options::~Options() + else { - for(Options::NamesPtrList::iterator it = opt_list.begin(); it != opt_list.end(); it++) + if (opt_name.size() > 0 && opt_name.back() == '*') { - delete *it; + std::string prefix_name = opt_name.substr(0, opt_name.size() - 1); + names->opt_prefix.push_back(prefix_name); + opt_prefix_map[prefix_name].push_back(names); } - } - - void Options::addOption(OptionBase *opt) - { - Names* names = new Names(); - names->opt = opt; - std::string &opt_string = opt->opt_string; - - size_t opt_start = 0; - for (size_t opt_end = 0; opt_end != std::string::npos;) + else { - opt_end = opt_string.find_first_of(',', opt_start); - bool force_short = 0; - if (opt_string[opt_start] == '-') - { - opt_start++; - force_short = 1; - } - std::string opt_name = opt_string.substr(opt_start, opt_end - opt_start); - if (force_short || opt_name.size() == 1) - { - names->opt_short.push_back(opt_name); - opt_short_map[opt_name].push_back(names); - } - else - { - if (opt_name.size() > 0 && opt_name.back() == '*') - { - std::string prefix_name = opt_name.substr(0, opt_name.size() - 1); - names->opt_prefix.push_back(prefix_name); - opt_prefix_map[prefix_name].push_back(names); - } - else - { - names->opt_long.push_back(opt_name); - opt_long_map[opt_name].push_back(names); - } - } - opt_start += opt_end + 1; + names->opt_long.push_back(opt_name); + opt_long_map[opt_name].push_back(names); } - opt_list.push_back(names); } + opt_start += opt_end + 1; + } + opt_list.push_back(names); +} - /* Helper method to initiate adding options to Options */ - OptionSpecific Options::addOptions() - { - return OptionSpecific(*this); - } +/* Helper method to initiate adding options to Options */ +OptionSpecific Options::addOptions() { return OptionSpecific(*this); } - static void setOptions(Options::NamesPtrList &opt_list, const std::string &value, ErrorReporter &error_reporter) +static void setOptions(Options::NamesPtrList& opt_list, const std::string& value, ErrorReporter& error_reporter) +{ + /* multiple options may be registered for the same name: + * allow each to parse value */ + for (Options::NamesPtrList::iterator it = opt_list.begin(); it != opt_list.end(); ++it) + { + (*it)->opt->parse(value, error_reporter); + } +} + +static const char spaces[41] = " "; + +/* format help text for a single option: + * using the formatting: "-x, --long", + * if a short/long option isn't specified, it is not printed + */ +static void doHelpOpt(std::ostream& out, const Options::Names& entry, unsigned pad_short = 0) +{ + pad_short = std::min(pad_short, 8u); + + if (!entry.opt_short.empty()) + { + unsigned pad = std::max((int) pad_short - (int) entry.opt_short.front().size(), 0); + out << "-" << entry.opt_short.front(); + if (!entry.opt_long.empty()) { - /* multiple options may be registered for the same name: - * allow each to parse value */ - for (Options::NamesPtrList::iterator it = opt_list.begin(); it != opt_list.end(); ++it) - { - (*it)->opt->parse(value, error_reporter); - } + out << ", "; } + out << &(spaces[40 - pad]); + } + else + { + out << " "; + out << &(spaces[40 - pad_short]); + } - static const char spaces[41] = " "; + if (!entry.opt_long.empty()) + { + out << "--" << entry.opt_long.front(); + } + else if (!entry.opt_prefix.empty()) + { + out << "--" << entry.opt_prefix.front() << "*"; + } +} - /* format help text for a single option: - * using the formatting: "-x, --long", - * if a short/long option isn't specified, it is not printed - */ - static void doHelpOpt(std::ostream &out, const Options::Names &entry, unsigned pad_short = 0) - { - pad_short = std::min(pad_short, 8u); +/* format the help text */ +void doHelp(std::ostream& out, Options& opts, unsigned columns) +{ + const unsigned pad_short = 3; + /* first pass: work out the longest option name */ + unsigned max_width = 0; + for (Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++) + { + std::ostringstream line(std::ios_base::out); + doHelpOpt(line, **it, pad_short); + max_width = std::max(max_width, (unsigned) line.tellp()); + } + + unsigned opt_width = std::min(max_width + 2, 28u + pad_short) + 2; + unsigned desc_width = columns - opt_width; + + /* second pass: write out formatted option and help text. + * - align start of help text to start at opt_width + * - if the option text is longer than opt_width, place the help + * text at opt_width on the next line. + */ + for (Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++) + { + std::ostringstream line(std::ios_base::out); + line << " "; + doHelpOpt(line, **it, pad_short); - if (!entry.opt_short.empty()) + const std::string& opt_desc = (*it)->opt->opt_desc; + if (opt_desc.empty()) + { + /* no help text: output option, skip further processing */ + std::cout << line.str() << std::endl; + continue; + } + size_t currlength = size_t(line.tellp()); + if (currlength > opt_width) + { + /* if option text is too long (and would collide with the + * help text, split onto next line */ + line << std::endl; + currlength = 0; + } + /* split up the help text, taking into account new lines, + * (add opt_width of padding to each new line) */ + for (size_t newline_pos = 0, cur_pos = 0; cur_pos != std::string::npos; currlength = 0) + { + /* print any required padding space for vertical alignment */ + line << &(spaces[40 - opt_width + currlength]); + newline_pos = opt_desc.find_first_of('\n', newline_pos); + if (newline_pos != std::string::npos) { - unsigned pad = std::max((int) pad_short - (int) entry.opt_short.front().size(), 0); - out << "-" << entry.opt_short.front(); - if (!entry.opt_long.empty()) - { - out << ", "; - } - out << &(spaces[40 - pad]); + /* newline found, print substring (newline needn't be stripped) */ + newline_pos++; + line << opt_desc.substr(cur_pos, newline_pos - cur_pos); + cur_pos = newline_pos; + continue; } - else + if (cur_pos + desc_width > opt_desc.size()) { - out << " "; - out << &(spaces[40 - pad_short]); + /* no need to wrap text, remainder is less than avaliable width */ + line << opt_desc.substr(cur_pos); + break; } - - if (!entry.opt_long.empty()) + /* find a suitable point to split text (avoid spliting in middle of word) */ + size_t split_pos = opt_desc.find_last_of(' ', cur_pos + desc_width); + if (split_pos != std::string::npos) { - out << "--" << entry.opt_long.front(); + /* eat up multiple space characters */ + split_pos = opt_desc.find_last_not_of(' ', split_pos) + 1; } - else if (!entry.opt_prefix.empty()) + + /* bad split if no suitable space to split at. fall back to width */ + bool bad_split = split_pos == std::string::npos || split_pos <= cur_pos; + if (bad_split) { - out << "--" << entry.opt_prefix.front() << "*"; + split_pos = cur_pos + desc_width; } - } + line << opt_desc.substr(cur_pos, split_pos - cur_pos); - /* format the help text */ - void doHelp(std::ostream &out, Options &opts, unsigned columns) - { - const unsigned pad_short = 3; - /* first pass: work out the longest option name */ - unsigned max_width = 0; - for(Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++) + /* eat up any space for the start of the next line */ + if (!bad_split) { - std::ostringstream line(std::ios_base::out); - doHelpOpt(line, **it, pad_short); - max_width = std::max(max_width, (unsigned) line.tellp()); + split_pos = opt_desc.find_first_not_of(' ', split_pos); } + cur_pos = newline_pos = split_pos; - unsigned opt_width = std::min(max_width + 2, 28u + pad_short) + 2; - unsigned desc_width = columns - opt_width; - - /* second pass: write out formatted option and help text. - * - align start of help text to start at opt_width - * - if the option text is longer than opt_width, place the help - * text at opt_width on the next line. - */ - for(Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++) + if (cur_pos >= opt_desc.size()) { - std::ostringstream line(std::ios_base::out); - line << " "; - doHelpOpt(line, **it, pad_short); - - const std::string &opt_desc = (*it)->opt->opt_desc; - if (opt_desc.empty()) - { - /* no help text: output option, skip further processing */ - std::cout << line.str() << std::endl; - continue; - } - size_t currlength = size_t(line.tellp()); - if (currlength > opt_width) - { - /* if option text is too long (and would collide with the - * help text, split onto next line */ - line << std::endl; - currlength = 0; - } - /* split up the help text, taking into account new lines, - * (add opt_width of padding to each new line) */ - for (size_t newline_pos = 0, cur_pos = 0; cur_pos != std::string::npos; currlength = 0) - { - /* print any required padding space for vertical alignment */ - line << &(spaces[40 - opt_width + currlength]); - newline_pos = opt_desc.find_first_of('\n', newline_pos); - if (newline_pos != std::string::npos) - { - /* newline found, print substring (newline needn't be stripped) */ - newline_pos++; - line << opt_desc.substr(cur_pos, newline_pos - cur_pos); - cur_pos = newline_pos; - continue; - } - if (cur_pos + desc_width > opt_desc.size()) - { - /* no need to wrap text, remainder is less than avaliable width */ - line << opt_desc.substr(cur_pos); - break; - } - /* find a suitable point to split text (avoid spliting in middle of word) */ - size_t split_pos = opt_desc.find_last_of(' ', cur_pos + desc_width); - if (split_pos != std::string::npos) - { - /* eat up multiple space characters */ - split_pos = opt_desc.find_last_not_of(' ', split_pos) + 1; - } - - /* bad split if no suitable space to split at. fall back to width */ - bool bad_split = split_pos == std::string::npos || split_pos <= cur_pos; - if (bad_split) - { - split_pos = cur_pos + desc_width; - } - line << opt_desc.substr(cur_pos, split_pos - cur_pos); - - /* eat up any space for the start of the next line */ - if (!bad_split) - { - split_pos = opt_desc.find_first_not_of(' ', split_pos); - } - cur_pos = newline_pos = split_pos; - - if (cur_pos >= opt_desc.size()) - { - break; - } - line << std::endl; - } - - std::cout << line.str() << std::endl; + break; } + line << std::endl; } - struct OptionWriter - { - OptionWriter(Options& rOpts, ErrorReporter& err) - : opts(rOpts), error_reporter(err) - {} - virtual ~OptionWriter() {} + std::cout << line.str() << std::endl; + } +} - virtual const std::string where() = 0; +struct OptionWriter +{ + OptionWriter(Options& rOpts, ErrorReporter& err) : opts(rOpts), error_reporter(err) {} + virtual ~OptionWriter() {} + + virtual const std::string where() = 0; - bool storePair(bool allow_long, bool allow_short, const std::string &name, const std::string &value); - bool storePair(const std::string &name, const std::string &value) { return storePair(true, true, name, value); } + bool storePair(bool allow_long, bool allow_short, const std::string& name, const std::string& value); + bool storePair(const std::string& name, const std::string& value) { return storePair(true, true, name, value); } - Options& opts; - ErrorReporter& error_reporter; - }; + Options& opts; + ErrorReporter& error_reporter; +}; - bool OptionWriter::storePair(bool allow_long, bool allow_short, const std::string &name, const std::string &value) +bool OptionWriter::storePair(bool allow_long, bool allow_short, const std::string& name, const std::string& value) +{ + bool found = false; + std::string val = value; + Options::NamesMap::iterator opt_it; + if (allow_long) + { + opt_it = opts.opt_long_map.find(name); + if (opt_it != opts.opt_long_map.end()) { - bool found = false; - std::string val = value; - Options::NamesMap::iterator opt_it; - if (allow_long) - { - opt_it = opts.opt_long_map.find(name); - if (opt_it != opts.opt_long_map.end()) - { - found = true; - } - } + found = true; + } + } - /* check for the short list */ - if (allow_short && !(found && allow_long)) - { - opt_it = opts.opt_short_map.find(name); - if (opt_it != opts.opt_short_map.end()) - { - found = true; - } - } - bool allow_prefix = allow_long; - if (allow_prefix && !found) - { - for (opt_it = opts.opt_prefix_map.begin(); opt_it != opts.opt_prefix_map.end(); opt_it++) - { - std::string name_prefix = name.substr(0, opt_it->first.size()); - if (name_prefix == opt_it->first) - { - // prepend value matching * - val = name.substr(name_prefix.size()) + std::string(" ") + val; - found = true; - break; - } - } - } - if (!found) + /* check for the short list */ + if (allow_short && !(found && allow_long)) + { + opt_it = opts.opt_short_map.find(name); + if (opt_it != opts.opt_short_map.end()) + { + found = true; + } + } + bool allow_prefix = allow_long; + if (allow_prefix && !found) + { + for (opt_it = opts.opt_prefix_map.begin(); opt_it != opts.opt_prefix_map.end(); opt_it++) + { + std::string name_prefix = name.substr(0, opt_it->first.size()); + if (name_prefix == opt_it->first) { - error_reporter.error(where()) - << "Unknown option `" << name << "' (value:`" << value << "')\n"; - return false; + // prepend value matching * + val = name.substr(name_prefix.size()) + std::string(" ") + val; + found = true; + break; } - setOptions((*opt_it).second, val, error_reporter); - return true; } + } + if (!found) + { + error_reporter.error(where()) << "Unknown option `" << name << "' (value:`" << value << "')\n"; + return false; + } + setOptions((*opt_it).second, val, error_reporter); + return true; +} - struct ArgvParser : public OptionWriter - { - ArgvParser(Options& rOpts, ErrorReporter& rError_reporter) - : OptionWriter(rOpts, rError_reporter) - {} +struct ArgvParser : public OptionWriter +{ + ArgvParser(Options& rOpts, ErrorReporter& rError_reporter) : OptionWriter(rOpts, rError_reporter) {} - const std::string where() { return "command line"; } + const std::string where() { return "command line"; } - unsigned parseGNU(unsigned argc, const char* argv[]); - unsigned parseSHORT(unsigned argc, const char* argv[]); - }; + unsigned parseGNU(unsigned argc, const char* argv[]); + unsigned parseSHORT(unsigned argc, const char* argv[]); +}; - /** - * returns number of extra arguments consumed - */ - unsigned ArgvParser::parseGNU(unsigned argc, const char* argv[]) +/** + * returns number of extra arguments consumed + */ +unsigned ArgvParser::parseGNU(unsigned argc, const char* argv[]) +{ + /* gnu style long options can take the forms: + * --option=arg + * --option arg + */ + std::string arg(argv[0]); + size_t arg_opt_start = arg.find_first_not_of('-'); + size_t arg_opt_sep = arg.find_first_of('='); + std::string option = arg.substr(arg_opt_start, arg_opt_sep - arg_opt_start); + + unsigned extra_argc_consumed = 0; + if (arg_opt_sep == std::string::npos) + { + /* no argument found => argument in argv[1] (maybe) */ + /* xxx, need to handle case where option isn't required */ + if (!storePair(true, false, option, "1")) { - /* gnu style long options can take the forms: - * --option=arg - * --option arg - */ - std::string arg(argv[0]); - size_t arg_opt_start = arg.find_first_not_of('-'); - size_t arg_opt_sep = arg.find_first_of('='); - std::string option = arg.substr(arg_opt_start, arg_opt_sep - arg_opt_start); - - unsigned extra_argc_consumed = 0; - if (arg_opt_sep == std::string::npos) - { - /* no argument found => argument in argv[1] (maybe) */ - /* xxx, need to handle case where option isn't required */ - if(!storePair(true, false, option, "1")) - { - return 0; - } - } - else - { - /* argument occurs after option_sep */ - std::string val = arg.substr(arg_opt_sep + 1); - storePair(true, false, option, val); - } - - return extra_argc_consumed; + return 0; } + } + else + { + /* argument occurs after option_sep */ + std::string val = arg.substr(arg_opt_sep + 1); + storePair(true, false, option, val); + } - unsigned ArgvParser::parseSHORT(unsigned argc, const char* argv[]) - { - /* short options can take the forms: - * --option arg - * -option arg - */ - std::string arg(argv[0]); - size_t arg_opt_start = arg.find_first_not_of('-'); - std::string option = arg.substr(arg_opt_start); - /* lookup option */ - - /* argument in argv[1] */ - /* xxx, need to handle case where option isn't required */ - if (argc == 1) - { - error_reporter.error(where()) - << "Not processing option `" << option << "' without argument\n"; - return 0; /* run out of argv for argument */ - } - storePair(false, true, option, std::string(argv[1])); + return extra_argc_consumed; +} - return 1; - } +unsigned ArgvParser::parseSHORT(unsigned argc, const char* argv[]) +{ + /* short options can take the forms: + * --option arg + * -option arg + */ + std::string arg(argv[0]); + size_t arg_opt_start = arg.find_first_not_of('-'); + std::string option = arg.substr(arg_opt_start); + /* lookup option */ + + /* argument in argv[1] */ + /* xxx, need to handle case where option isn't required */ + if (argc == 1) + { + error_reporter.error(where()) << "Not processing option `" << option << "' without argument\n"; + return 0; /* run out of argv for argument */ + } + storePair(false, true, option, std::string(argv[1])); - std::list<const char *> scanArgv(Options &opts, unsigned argc, const char *argv[], ErrorReporter &error_reporter) - { - ArgvParser avp(opts, error_reporter); + return 1; +} - /* a list for anything that didn't get handled as an option */ - std::list<const char *> non_option_arguments; +std::list<const char*> scanArgv(Options& opts, unsigned argc, const char* argv[], ErrorReporter& error_reporter) +{ + ArgvParser avp(opts, error_reporter); - for(unsigned i = 1; i < argc; i++) - { - if (argv[i][0] != '-') - { - non_option_arguments.push_back(argv[i]); - continue; - } - - if (argv[i][1] == 0) - { - /* a lone single dash is an argument (usually signifying stdin) */ - non_option_arguments.push_back(argv[i]); - continue; - } - - if (argv[i][1] != '-') - { - /* handle short (single dash) options */ - i += avp.parseSHORT(argc - i, &argv[i]); - continue; - } - - if (argv[i][2] == 0) - { - /* a lone double dash ends option processing */ - while (++i < argc) - { - non_option_arguments.push_back(argv[i]); - } - break; - } - - /* handle long (double dash) options */ - i += avp.parseGNU(argc - i, &argv[i]); - } + /* a list for anything that didn't get handled as an option */ + std::list<const char*> non_option_arguments; - return non_option_arguments; + for (unsigned i = 1; i < argc; i++) + { + if (argv[i][0] != '-') + { + non_option_arguments.push_back(argv[i]); + continue; } - struct CfgStreamParser : public OptionWriter + if (argv[i][1] == 0) { - CfgStreamParser(const std::string &rName, Options &rOpts, ErrorReporter &rError_reporter) - : OptionWriter(rOpts, rError_reporter), name(rName), linenum(0) - {} - - const std::string name; - int linenum; - const std::string where() - { - std::ostringstream os; - os << name << ":" << linenum; - return os.str(); - } + /* a lone single dash is an argument (usually signifying stdin) */ + non_option_arguments.push_back(argv[i]); + continue; + } - void scanLine(std::string &line); - void scanStream(std::istream &in); - }; + if (argv[i][1] != '-') + { + /* handle short (single dash) options */ + i += avp.parseSHORT(argc - i, &argv[i]); + continue; + } - void CfgStreamParser::scanLine(std::string &line) + if (argv[i][2] == 0) { - /* strip any leading whitespace */ - size_t start = line.find_first_not_of(" \t\n\r"); - if (start == std::string::npos) - { - /* blank line */ - return; - } - if (line[start] == '#') + /* a lone double dash ends option processing */ + while (++i < argc) { - /* comment line */ - return; + non_option_arguments.push_back(argv[i]); } - /* look for first whitespace or ':' after the option end */ - size_t option_end = line.find_first_of(": \t\n\r",start); - std::string option = line.substr(start, option_end - start); + break; + } - /* look for ':', eat up any whitespace first */ - start = line.find_first_not_of(" \t\n\r", option_end); - if (start == std::string::npos) - { - /* error: badly formatted line */ - error_reporter.warn(where()) << "line formatting error\n"; - return; - } - if (line[start] != ':') - { - /* error: badly formatted line */ - error_reporter.warn(where()) << "line formatting error\n"; - return; - } + /* handle long (double dash) options */ + i += avp.parseGNU(argc - i, &argv[i]); + } - /* look for start of value string -- eat up any leading whitespace */ - start = line.find_first_not_of(" \t\n\r", ++start); - if (start == std::string::npos) - { - /* error: badly formatted line */ - error_reporter.warn(where()) << "line formatting error\n"; - return; - } + return non_option_arguments; +} - /* extract the value part, which may contain embedded spaces - * by searching for a word at a time, until we hit a comment or end of line */ - size_t value_end = start; - do - { - if (line[value_end] == '#') - { - /* rest of line is a comment */ - value_end--; - break; - } - value_end = line.find_first_of(" \t\n\r", value_end); - /* consume any white space, incase there is another word. - * any trailing whitespace will be removed shortly */ - value_end = line.find_first_not_of(" \t\n\r", value_end); - } while (value_end != std::string::npos); - /* strip any trailing space from value*/ - value_end = line.find_last_not_of(" \t\n\r", value_end); - - std::string value; - if (value_end >= start) - { - value = line.substr(start, value_end +1 - start); - } - else - { - /* error: no value */ - error_reporter.warn(where()) << "no value found\n"; - return; - } +struct CfgStreamParser : public OptionWriter +{ + CfgStreamParser(const std::string& rName, Options& rOpts, ErrorReporter& rError_reporter) + : OptionWriter(rOpts, rError_reporter), name(rName), linenum(0) + {} - /* store the value in option */ - storePair(true, false, option, value); - } + const std::string name; + int linenum; + const std::string where() + { + std::ostringstream os; + os << name << ":" << linenum; + return os.str(); + } - void CfgStreamParser::scanStream(std::istream &in) - { - do - { - linenum++; - std::string line; - getline(in, line); - scanLine(line); - } while(!!in); - } + void scanLine(std::string& line); + void scanStream(std::istream& in); +}; - /* for all options in opts, set their storage to their specified - * default value */ - void setDefaults(Options& opts) - { - for(Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++) - { - (*it)->opt->setDefault(); - } - } +void CfgStreamParser::scanLine(std::string& line) +{ + /* strip any leading whitespace */ + size_t start = line.find_first_not_of(" \t\n\r"); + if (start == std::string::npos) + { + /* blank line */ + return; + } + if (line[start] == '#') + { + /* comment line */ + return; + } + /* look for first whitespace or ':' after the option end */ + size_t option_end = line.find_first_of(": \t\n\r", start); + std::string option = line.substr(start, option_end - start); - void parseConfigFile(Options &opts, const std::string &filename, ErrorReporter &error_reporter) + /* look for ':', eat up any whitespace first */ + start = line.find_first_not_of(" \t\n\r", option_end); + if (start == std::string::npos) + { + /* error: badly formatted line */ + error_reporter.warn(where()) << "line formatting error\n"; + return; + } + if (line[start] != ':') + { + /* error: badly formatted line */ + error_reporter.warn(where()) << "line formatting error\n"; + return; + } + + /* look for start of value string -- eat up any leading whitespace */ + start = line.find_first_not_of(" \t\n\r", ++start); + if (start == std::string::npos) + { + /* error: badly formatted line */ + error_reporter.warn(where()) << "line formatting error\n"; + return; + } + + /* extract the value part, which may contain embedded spaces + * by searching for a word at a time, until we hit a comment or end of line */ + size_t value_end = start; + do + { + if (line[value_end] == '#') { - std::ifstream cfgstream(filename.c_str(), std::ifstream::in); - if (!cfgstream) - { - error_reporter.error(filename) << "Failed to open config file\n"; - return; - } - CfgStreamParser csp(filename, opts, error_reporter); - csp.scanStream(cfgstream); + /* rest of line is a comment */ + value_end--; + break; } + value_end = line.find_first_of(" \t\n\r", value_end); + /* consume any white space, incase there is another word. + * any trailing whitespace will be removed shortly */ + value_end = line.find_first_not_of(" \t\n\r", value_end); + } while (value_end != std::string::npos); + /* strip any trailing space from value*/ + value_end = line.find_last_not_of(" \t\n\r", value_end); + + std::string value; + if (value_end >= start) + { + value = line.substr(start, value_end + 1 - start); + } + else + { + /* error: no value */ + error_reporter.warn(where()) << "no value found\n"; + return; + } + + /* store the value in option */ + storePair(true, false, option, value); +} +void CfgStreamParser::scanStream(std::istream& in) +{ + do + { + linenum++; + std::string line; + getline(in, line); + scanLine(line); + } while (!!in); +} + +/* for all options in opts, set their storage to their specified + * default value */ +void setDefaults(Options& opts) +{ + for (Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++) + { + (*it)->opt->setDefault(); + } +} + +void parseConfigFile(Options& opts, const std::string& filename, ErrorReporter& error_reporter) +{ + std::ifstream cfgstream(filename.c_str(), std::ifstream::in); + if (!cfgstream) + { + error_reporter.error(filename) << "Failed to open config file\n"; + return; } + CfgStreamParser csp(filename, opts, error_reporter); + csp.scanStream(cfgstream); } -//! \} +} // namespace ProgramOptionsLite diff --git a/source/Lib/Utilities/program_options_lite.h b/source/Lib/Utilities/program_options_lite.h index 0302412119..1063c52779 100644 --- a/source/Lib/Utilities/program_options_lite.h +++ b/source/Lib/Utilities/program_options_lite.h @@ -30,6 +30,9 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ + +#pragma once + #include <iostream> #include <sstream> #include <string> @@ -38,12 +41,6 @@ #include <vector> #include <optional> -#ifndef __PROGRAM_OPTIONS_LITE__ -#define __PROGRAM_OPTIONS_LITE__ - -//! \ingroup TAppCommon -//! \{ - template<class T> inline std::istream& operator>>(std::istream& in, std::optional<T>& value) { in >> std::ws; @@ -84,268 +81,239 @@ struct SMultiValueInput std::istream &readValues(std::istream &in); }; -namespace df +namespace ProgramOptionsLite { - namespace program_options_lite - { - struct Options; +struct Options; - struct ParseFailure : public std::exception - { - ParseFailure(std::string arg0, std::string val0) throw() - : arg(arg0), val(val0) - {} +struct ParseFailure : public std::exception +{ + ParseFailure(std::string arg0, std::string val0) throw() : arg(arg0), val(val0) {} - ~ParseFailure() throw() {}; + ~ParseFailure() throw(){}; - std::string arg; - std::string val; + std::string arg; + std::string val; - const char* what() const throw() { return "Option Parse Failure"; } - }; + const char* what() const throw() { return "Option Parse Failure"; } +}; - struct ErrorReporter - { - ErrorReporter() : is_errored(0) {} - virtual ~ErrorReporter() {} - virtual std::ostream& error(const std::string& where); - virtual std::ostream& warn(const std::string& where); - bool is_errored; - }; +struct ErrorReporter +{ + ErrorReporter() : is_errored(0) {} + virtual ~ErrorReporter() {} + virtual std::ostream& error(const std::string& where); + virtual std::ostream& warn(const std::string& where); + bool is_errored; +}; - extern ErrorReporter default_error_reporter; +extern ErrorReporter default_error_reporter; - struct SilentReporter : ErrorReporter - { - SilentReporter() { } - virtual ~SilentReporter() { } - virtual std::ostream& error( const std::string& where ) { return dest; } - virtual std::ostream& warn( const std::string& where ) { return dest; } - std::stringstream dest; - }; - - void doHelp(std::ostream& out, Options& opts, unsigned columns = 80); - std::list<const char*> scanArgv(Options& opts, unsigned argc, const char* argv[], ErrorReporter& error_reporter = default_error_reporter); - void setDefaults(Options& opts); - void parseConfigFile(Options& opts, const std::string& filename, ErrorReporter& error_reporter = default_error_reporter); - - /** OptionBase: Virtual base class for storing information relating to a - * specific option This base class describes common elements. Type specific - * information should be stored in a derived class. */ - struct OptionBase - { - OptionBase(const std::string& name, const std::string& desc) - : opt_string(name), opt_desc(desc) - {}; +struct SilentReporter : ErrorReporter +{ + SilentReporter() {} + virtual ~SilentReporter() {} + virtual std::ostream& error(const std::string& where) { return dest; } + virtual std::ostream& warn(const std::string& where) { return dest; } + std::stringstream dest; +}; - virtual ~OptionBase() {} +void doHelp(std::ostream& out, Options& opts, unsigned columns = 80); +std::list<const char*> scanArgv(Options& opts, unsigned argc, const char* argv[], + ErrorReporter& error_reporter = default_error_reporter); +void setDefaults(Options& opts); +void parseConfigFile(Options& opts, const std::string& filename, + ErrorReporter& error_reporter = default_error_reporter); + +/** OptionBase: Virtual base class for storing information relating to a + * specific option This base class describes common elements. Type specific + * information should be stored in a derived class. */ +struct OptionBase +{ + OptionBase(const std::string& name, const std::string& desc) : opt_string(name), opt_desc(desc){}; - /* parse argument arg, to obtain a value for the option */ - virtual void parse(const std::string& arg, ErrorReporter&) = 0; - /* set the argument to the default value */ - virtual void setDefault() = 0; + virtual ~OptionBase() {} - std::string opt_string; - std::string opt_desc; - }; + /* parse argument arg, to obtain a value for the option */ + virtual void parse(const std::string& arg, ErrorReporter&) = 0; + /* set the argument to the default value */ + virtual void setDefault() = 0; - /** Type specific option storage */ - template<typename T> - struct Option : public OptionBase - { - Option(const std::string& name, T& storage, T default_val, const std::string& desc) - : OptionBase(name, desc), opt_storage(storage), opt_default_val(default_val) - {} + std::string opt_string; + std::string opt_desc; +}; - void parse(const std::string& arg, ErrorReporter&); +/** Type specific option storage */ +template<typename T> struct Option : public OptionBase +{ + Option(const std::string& name, T& storage, T default_val, const std::string& desc) + : OptionBase(name, desc), opt_storage(storage), opt_default_val(default_val) + {} - void setDefault() - { - opt_storage = opt_default_val; - } + void parse(const std::string& arg, ErrorReporter&); - T& opt_storage; - T opt_default_val; - }; + void setDefault() { opt_storage = opt_default_val; } - /* Generic parsing */ - template<typename T> - inline void - Option<T>::parse(const std::string& arg, ErrorReporter&) - { - std::istringstream arg_ss (arg,std::istringstream::in); - arg_ss.exceptions(std::ios::failbit); - try - { - arg_ss >> opt_storage; - } - catch (...) - { - throw ParseFailure(opt_string, arg); - } - } + T& opt_storage; + T opt_default_val; +}; - /* string parsing is specialized -- copy the whole string, not just the - * first word */ - template<> - inline void - Option<std::string>::parse(const std::string& arg, ErrorReporter&) - { - opt_storage = arg; - } +/* Generic parsing */ +template<typename T> inline void Option<T>::parse(const std::string& arg, ErrorReporter&) +{ + std::istringstream arg_ss(arg, std::istringstream::in); + arg_ss.exceptions(std::ios::failbit); + try + { + arg_ss >> opt_storage; + } + catch (...) + { + throw ParseFailure(opt_string, arg); + } +} - /** Option class for argument handling using a user provided function */ - struct OptionFunc : public OptionBase - { - typedef void (Func)(Options&, const std::string&, ErrorReporter&); +/* string parsing is specialized -- copy the whole string, not just the + * first word */ +template<> inline void Option<std::string>::parse(const std::string& arg, ErrorReporter&) { opt_storage = arg; } - OptionFunc(const std::string& name, Options& parent_, Func *func_, const std::string& desc) - : OptionBase(name, desc), parent(parent_), func(func_) - {} +/** Option class for argument handling using a user provided function */ +struct OptionFunc : public OptionBase +{ + typedef void(Func)(Options&, const std::string&, ErrorReporter&); - void parse(const std::string& arg, ErrorReporter& error_reporter) - { - func(parent, arg, error_reporter); - } + OptionFunc(const std::string& name, Options& parent_, Func* func_, const std::string& desc) + : OptionBase(name, desc), parent(parent_), func(func_) + {} - void setDefault() - { - return; - } + void parse(const std::string& arg, ErrorReporter& error_reporter) { func(parent, arg, error_reporter); } - private: - Options& parent; - Func* func; - }; + void setDefault() { return; } - class OptionSpecific; - struct Options - { - ~Options(); +private: + Options& parent; + Func* func; +}; - OptionSpecific addOptions(); +class OptionSpecific; +struct Options +{ + ~Options(); - struct Names - { - Names() : opt(0) {}; - ~Names() - { - if (opt) - { - delete opt; - } - } - std::list<std::string> opt_long; - std::list<std::string> opt_short; - std::list<std::string> opt_prefix; - OptionBase* opt; - }; - - void addOption(OptionBase *opt); - - typedef std::list<Names*> NamesPtrList; - NamesPtrList opt_list; - - typedef std::map<std::string, NamesPtrList> NamesMap; - NamesMap opt_long_map; - NamesMap opt_short_map; - NamesMap opt_prefix_map; - }; - - /* Class with templated overloaded operator(), for use by Options::addOptions() */ - class OptionSpecific + OptionSpecific addOptions(); + + struct Names + { + Names() : opt(0){}; + ~Names() { - public: - OptionSpecific(Options& parent_) : parent(parent_) {} - - /** - * Add option described by name to the parent Options list, - * with storage for the option's value - * with default_val as the default value - * with desc as an optional help description - */ - template<typename T> - OptionSpecific& - operator()(const std::string& name, T& storage, T default_val, const std::string& desc = "") + if (opt) { - parent.addOption(new Option<T>(name, storage, default_val, desc)); - return *this; + delete opt; } - template<typename T> - OptionSpecific& - operator()(const std::string& name, T* storage, T default_val, unsigned uiMaxNum, const std::string& desc = "") - { - std::string cNameBuffer; - std::string cDescriptionBuffer; + } + std::list<std::string> opt_long; + std::list<std::string> opt_short; + std::list<std::string> opt_prefix; + OptionBase* opt; + }; + + void addOption(OptionBase* opt); - for (unsigned int k = 0; k < uiMaxNum; k++) - { - // it needs to be reset when extra digit is added, e.g. number 10 and above - cNameBuffer.resize(name.size() + 10); - cDescriptionBuffer.resize(desc.size() + 10); + typedef std::list<Names*> NamesPtrList; + NamesPtrList opt_list; - // isn't there are sprintf function for string?? - snprintf((char *) cNameBuffer.c_str(), cNameBuffer.size(), name.c_str(), k, k); - snprintf((char *) cDescriptionBuffer.c_str(), cDescriptionBuffer.size(), desc.c_str(), k, k); + typedef std::map<std::string, NamesPtrList> NamesMap; + NamesMap opt_long_map; + NamesMap opt_short_map; + NamesMap opt_prefix_map; +}; + +/* Class with templated overloaded operator(), for use by Options::addOptions() */ +class OptionSpecific +{ +public: + OptionSpecific(Options& parent_) : parent(parent_) {} + + /** + * Add option described by name to the parent Options list, + * with storage for the option's value + * with default_val as the default value + * with desc as an optional help description + */ + template<typename T> + OptionSpecific& operator()(const std::string& name, T& storage, T default_val, const std::string& desc = "") + { + parent.addOption(new Option<T>(name, storage, default_val, desc)); + return *this; + } + template<typename T> OptionSpecific& operator()(const std::string& name, T* storage, T default_val, unsigned uiMaxNum, + const std::string& desc = "") + { + std::string cNameBuffer; + std::string cDescriptionBuffer; - size_t pos = cNameBuffer.find_first_of('\0'); - if (pos != std::string::npos) - { - cNameBuffer.resize(pos); - } + for (unsigned int k = 0; k < uiMaxNum; k++) + { + // it needs to be reset when extra digit is added, e.g. number 10 and above + cNameBuffer.resize(name.size() + 10); + cDescriptionBuffer.resize(desc.size() + 10); - parent.addOption(new Option<T>(cNameBuffer, (storage[k]), default_val, cDescriptionBuffer)); - } + // isn't there are sprintf function for string?? + snprintf((char*) cNameBuffer.c_str(), cNameBuffer.size(), name.c_str(), k, k); + snprintf((char*) cDescriptionBuffer.c_str(), cDescriptionBuffer.size(), desc.c_str(), k, k); - return *this; + size_t pos = cNameBuffer.find_first_of('\0'); + if (pos != std::string::npos) + { + cNameBuffer.resize(pos); } - template<typename T> - OptionSpecific& - operator()(const std::string& name, T** storage, T default_val, unsigned uiMaxNum, const std::string& desc = "") - { - std::string cNameBuffer; - std::string cDescriptionBuffer; + parent.addOption(new Option<T>(cNameBuffer, (storage[k]), default_val, cDescriptionBuffer)); + } + + return *this; + } - for (unsigned int k = 0; k < uiMaxNum; k++) - { - // it needs to be reset when extra digit is added, e.g. number 10 and above - cNameBuffer.resize(name.size() + 10); - cDescriptionBuffer.resize(desc.size() + 10); + template<typename T> OptionSpecific& operator()(const std::string& name, T** storage, T default_val, + unsigned uiMaxNum, const std::string& desc = "") + { + std::string cNameBuffer; + std::string cDescriptionBuffer; - // isn't there are sprintf function for string?? - snprintf((char *) cNameBuffer.c_str(), cNameBuffer.size(), name.c_str(), k, k); - snprintf((char *) cDescriptionBuffer.c_str(), cDescriptionBuffer.size(), desc.c_str(), k, k); + for (unsigned int k = 0; k < uiMaxNum; k++) + { + // it needs to be reset when extra digit is added, e.g. number 10 and above + cNameBuffer.resize(name.size() + 10); + cDescriptionBuffer.resize(desc.size() + 10); - size_t pos = cNameBuffer.find_first_of('\0'); - if (pos != std::string::npos) - cNameBuffer.resize(pos); + // isn't there are sprintf function for string?? + snprintf((char*) cNameBuffer.c_str(), cNameBuffer.size(), name.c_str(), k, k); + snprintf((char*) cDescriptionBuffer.c_str(), cDescriptionBuffer.size(), desc.c_str(), k, k); - parent.addOption(new Option<T>(cNameBuffer, *(storage[k]), default_val, cDescriptionBuffer)); - } + size_t pos = cNameBuffer.find_first_of('\0'); + if (pos != std::string::npos) + cNameBuffer.resize(pos); - return *this; - } - /** - * Add option described by name to the parent Options list, - * with desc as an optional help description - * instead of storing the value somewhere, a function of type - * OptionFunc::Func is called. It is upto this function to correctly - * handle evaluating the option's value. - */ - OptionSpecific& - operator()(const std::string& name, OptionFunc::Func *func, const std::string& desc = "") - { - parent.addOption(new OptionFunc(name, parent, func, desc)); - return *this; - } - private: - Options& parent; - }; + parent.addOption(new Option<T>(cNameBuffer, *(storage[k]), default_val, cDescriptionBuffer)); + } - } /* namespace: program_options_lite */ -} /* namespace: df */ + return *this; + } + /** + * Add option described by name to the parent Options list, + * with desc as an optional help description + * instead of storing the value somewhere, a function of type + * OptionFunc::Func is called. It is upto this function to correctly + * handle evaluating the option's value. + */ + OptionSpecific& operator()(const std::string& name, OptionFunc::Func* func, const std::string& desc = "") + { + parent.addOption(new OptionFunc(name, parent, func, desc)); + return *this; + } -//! \} +private: + Options& parent; +}; -#endif +} // namespace ProgramOptionsLite -- GitLab