boost.program_options

// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)/** This example shows how to support custom options syntax. It's possible to install 'custom_parser'. It will be invoked on all command line tokens and can return name/value pair, or nothing. If it returns nothing, usual processing will be done.*/#include #include #include using namespace boost::program_options;#include using namespace std;/* This custom option parse function recognize gcc-style option "-fbar" / "-fno-bar".*/pair reg_foo(const string& s){ if (s.find("-f") == 0) { if (s.substr(2, 3) == "no-") return make_pair(s.substr(5), string("false")); else return make_pair(s.substr(2), string("true")); } else { return make_pair(string(), string()); } }int main(int ac, char* av[]){ try { options_description desc("Allowed options"); desc.add_options() ("help", "produce a help message") ("foo", value(), "just an option") ; variables_map vm; store(command_line_parser(ac, av).options(desc).extra_parser(reg_foo) .run(), vm); if (vm.count("help")) { cout << desc; cout << "\nIn addition -ffoo and -fno-foo syntax are recognized.\n"; } if (vm.count("foo")) { cout << "foo value with the value of " << vm["foo"].as() << "\n"; } } catch(exception& e) { cout << e.what() << "\n"; }}// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)/** This example shows how to handle response file. For a test, build and run: response_file -I foo @response_file.rsp The expected output is: Include paths: foo bar biz Thanks to Hartmut Kaiser who raised the issue of response files and discussed the possible approach.*/#include #include #include #include #include using namespace boost;using namespace boost::program_options;#include #include using namespace std;// Additional command line parser which interprets '@something' as a// option "config-file" with the value "something"pair at_option_parser(string const&s){ if ('@' == s[0]) return std::make_pair(string("response-file"), s.substr(1)); else return pair();}int main(int ac, char* av[]){ try { options_description desc("Allowed options"); desc.add_options() ("help", "produce a help message") ("include-path,I", value< vector >()->composing(), "include path") ("magic", value(), "magic value") ("response-file", value(), "can be specified with '@name', too") ; variables_map vm; store(command_line_parser(ac, av).options(desc) .extra_parser(at_option_parser).run(), vm); if (vm.count("help")) { cout << desc; } if (vm.count("response-file")) { // Load the file and tokenize it ifstream ifs(vm["response-file"].as().c_str()); if (!ifs) { cout << "Could not open the response file\n"; return 1; } // Read the whole file into a string stringstream ss; ss << ifs.rdbuf(); // Split the file content char_separator sep(" \n\r"); string sstr = ss.str(); tokenizer tok(sstr, sep); vector args; copy(tok.begin(), tok.end(), back_inserter(args)); // Parse the file and store the options store(command_line_parser(args).options(desc).run(), vm); } if (vm.count("include-path")) { const vector& s = vm["include-path"].as >(); cout << "Include paths: "; copy(s.begin(), s.end(), ostream_iterator(cout, " ")); cout << "\n"; } if (vm.count("magic")) { cout << "Magic value: " << vm["magic"].as() << "\n"; } } catch (std::exception& e) { cout << e.what() << "\n"; }}// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)/** This example shows how to handle options groups. For a test, run: option_groups --help option_groups --num-threads 10 option_groups --help-module backend The first invocation would show to option groups, and will not show the '--num-threads' options. The second invocation will still get the value of the hidden '--num-threads' option. Finally, the third invocation will show the options for the 'backend' module, including the '--num-threads' option.*/#include #include #include #include #include using namespace boost;using namespace boost::program_options;#include #include using namespace std;int main(int ac, char* av[]){ try { // Declare three groups of options. options_description general("General options"); general.add_options() ("help", "produce a help message") ("help-module", value()->implicit(), "produce a help for a given module") ("version", "output the version number") ; options_description gui("GUI options"); gui.add_options() ("display", value(), "display to use") ; options_description backend("Backend options"); backend.add_options() ("num-threads", value(), "the initial number of threads") ; // Declare an options description instance which will include // all the options options_description all("Allowed options"); all.add(general).add(gui).add(backend); // Declare an options description instance which will be shown // to the user options_description visible("Allowed options"); visible.add(general).add(gui); variables_map vm; store(parse_command_line(ac, av, all), vm); if (vm.count("help")) { cout << visible; return 0; } if (vm.count("help-module")) { const string& s = vm["help-module"].as(); if (s == "gui") { cout << gui; } else if (s == "backend") { cout << backend; } else { cout << "Unknown module '" << s << "' in the --help-module option\n"; return 1; } return 0; } if (vm.count("num-threads")) { cout << "The 'num-threads' options was set to " << vm["num-threads"].as() << "\n"; } } catch(exception& e) { cout << e.what() << "\n"; }}// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)/* Shows how to use both command line and config file. */#include namespace po = boost::program_options;#include #include #include using namespace std;// A helper function to simplify the main part.templateostream& operator<<(ostream& os, const vector& v){ copy(v.begin(), v.end(), ostream_iterator(os, " ")); return os;}int main(int ac, char* av[]){ try { int opt; string config_file; // Declare a group of options that will be // allowed only on command line po::options_description generic("Generic options"); generic.add_options() ("version,v", "print version string") ("help", "produce help message") ("config,c", po::value(&config_file)->default_value("multiple_sources.cfg"), "name of a file of a configuration.") ; // Declare a group of options that will be // allowed both on command line and in // config file po::options_description config("Configuration"); config.add_options() ("optimization", po::value(&opt)->default_value(10), "optimization level") ("include-path,I", po::value< vector >()->composing(), "include path") ; // Hidden options, will be allowed both on command line and // in config file, but will not be shown to the user. po::options_description hidden("Hidden options"); hidden.add_options() ("input-file", po::value< vector >(), "input file") ; po::options_description cmdline_options; cmdline_options.add(generic).add(config).add(hidden); po::options_description config_file_options; config_file_options.add(config).add(hidden); po::options_description visible("Allowed options"); visible.add(generic).add(config); po::positional_options_description p; p.add("input-file", -1); po::variables_map vm; store(po::command_line_parser(ac, av). options(cmdline_options).positional(p).run(), vm); notify(vm); ifstream ifs(config_file.c_str()); if (!ifs) { cout << "can not open config file: " << config_file << "\n"; return 0; } else { store(parse_config_file(ifs, config_file_options), vm); notify(vm); } if (vm.count("help")) { cout << visible << "\n"; return 0; } if (vm.count("version")) { cout << "Multiple sources example, version 1.0\n"; return 0; } if (vm.count("include-path")) { cout << "Include paths are: " << vm["include-path"].as< vector >() << "\n"; } if (vm.count("input-file")) { cout << "Input files are: " << vm["input-file"].as< vector >() << "\n"; } cout << "Optimization level is " << opt << "\n"; } catch(exception& e) { cout << e.what() << "\n"; return 1; } return 0;}// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)/* The simplest usage of the library. */#include namespace po = boost::program_options;#include #include using namespace std;int main(int ac, char* av[]){ try { po::options_description desc("Allowed options"); desc.add_options() ("help", "produce help message") ("compression", po::value(), "set compression level") ; po::variables_map vm; po::store(po::parse_command_line(ac, av, desc), vm); po::notify(vm); if (vm.count("help")) { cout << desc << "\n"; return 0; } if (vm.count("compression")) { cout << "Compression level was set to " << vm["compression"].as() << ".\n"; } else { cout << "Compression level was not set.\n"; } } catch(exception& e) { cerr << "error: " << e.what() << "\n"; return 1; } catch(...) { cerr << "Exception of unknown type!\n"; } return 0;}// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)/** This example shows how to support custom options syntax. It's possible to install 'custom_parser'. It will be invoked on all command line tokens and can return name/value pair, or nothing. If it returns nothing, usual processing will be done.*/#include #include #include using namespace boost::program_options;#include using namespace std;/* This custom option parse function recognize gcc-style option "-fbar" / "-fno-bar".*/pair reg_foo(const string& s){ if (s.find("-f") == 0) { if (s.substr(2, 3) == "no-") return make_pair(s.substr(5), string("false")); else return make_pair(s.substr(2), string("true")); } else { return make_pair(string(), string()); } }int main(int ac, char* av[]){ try { options_description desc("Allowed options"); desc.add_options() ("help", "produce a help message") ("foo", value(), "just an option") ; variables_map vm; store(command_line_parser(ac, av).options(desc).extra_parser(reg_foo) .run(), vm); if (vm.count("help")) { cout << desc; cout << "\nIn addition -ffoo and -fno-foo syntax are recognized.\n"; } if (vm.count("foo")) { cout << "foo value with the value of " << vm["foo"].as() << "\n"; } } catch(exception& e) { cout << e.what() << "\n"; }}// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)#include using namespace boost::program_options;#include using namespace std;/* Auxiliary functions for checking input for validity. *//* Function used to check that 'opt1' and 'opt2' are not specified at the same time. */void conflicting_options(const variables_map& vm, const char* opt1, const char* opt2){ if (vm.count(opt1) && !vm[opt1].defaulted() && vm.count(opt2) && !vm[opt2].defaulted()) throw logic_error(string("Conflicting options '") + opt1 + "' and '" + opt2 + "'.");}/* Function used to check that of 'for_what' is specified, then 'required_option' is specified too. */void option_dependency(const variables_map& vm, const char* for_what, const char* required_option){ if (vm.count(for_what) && !vm[for_what].defaulted()) if (vm.count(required_option) == 0 || vm[required_option].defaulted()) throw logic_error(string("Option '") + for_what + "' requires option '" + required_option + "'.");}int main(int argc, char* argv[]){ try { string ofile; string macrofile, libmakfile; bool t_given = false; bool b_given = false; string mainpackage; string depends = "deps_file"; string sources = "src_file"; string root = "."; options_description desc("Allowed options"); desc.add_options() // First parameter describes option name/short name // The second is parameter to option // The third is description ("help,h", "print usage message") ("output,o", value(&ofile), "pathname for output") ("macrofile,m", value(¯ofile), "full pathname of macro.h") ("two,t", bool_switch(&t_given), "preprocess both header and body") ("body,b", bool_switch(&b_given), "preprocess body in the header context") ("libmakfile,l", value(&libmakfile), "write include makefile for library") ("mainpackage,p", value(&mainpackage), "output dependency information") ("depends,d", value(&depends), "write dependencies to ") ("sources,s", value(&sources), "write source package list to ") ("root,r", value(&root), "treat as project root directory") ; variables_map vm; store(parse_command_line(argc, argv, desc), vm); if (vm.count("help")) { cout << desc << "\n"; return 0; } conflicting_options(vm, "output", "two"); conflicting_options(vm, "output", "body"); conflicting_options(vm, "output", "mainpackage"); conflicting_options(vm, "two", "mainpackage"); conflicting_options(vm, "body", "mainpackage"); conflicting_options(vm, "two", "body"); conflicting_options(vm, "libmakfile", "mainpackage"); conflicting_options(vm, "libmakfile", "mainpackage"); option_dependency(vm, "depends", "mainpackage"); option_dependency(vm, "sources", "mainpackage"); option_dependency(vm, "root", "mainpackage"); cout << "two = " << vm["two"].as() << "\n"; } catch(exception& e) { cerr << e.what() << "\n"; }}// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)#include using namespace boost;namespace po = boost::program_options;#include #include #include using namespace std;// A helper function to simplify the main part.templateostream& operator<<(ostream& os, const vector& v){ copy(v.begin(), v.end(), ostream_iterator(os, " ")); return os;}int main(int ac, char* av[]){ try { int opt; int portnum; po::options_description desc("Allowed options"); desc.add_options() ("help", "produce help message") ("optimization", po::value(&opt)->default_value(10), "optimization level") ("verbose,v", po::value()->implicit_value(1), "enable verbosity (optionally specify level)") ("listen,l", po::value(&portnum)->implicit_value(1001) ->default_value(0,"no"), "listen on a port.") ("include-path,I", po::value< vector >(), "include path") ("input-file", po::value< vector >(), "input file") ; po::positional_options_description p; p.add("input-file", -1); po::variables_map vm; po::store(po::command_line_parser(ac, av). options(desc).positional(p).run(), vm); po::notify(vm); if (vm.count("help")) { cout << "Usage: options_description [options]\n"; cout << desc; return 0; } if (vm.count("include-path")) { cout << "Include paths are: " << vm["include-path"].as< vector >() << "\n"; } if (vm.count("input-file")) { cout << "Input files are: " << vm["input-file"].as< vector >() << "\n"; } if (vm.count("verbose")) { cout << "Verbosity enabled. Level is " << vm["verbose"].as() << "\n"; } cout << "Optimization level is " << opt << "\n"; cout << "Listen port is " << portnum << "\n"; } catch(std::exception& e) { cout << e.what() << "\n"; return 1; } return 0;}// Copyright Vladimir Prus 2002-2004.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)// This example shows how a user-defined class can be parsed using// specific mechanism -- not the iostream operations used by default.//// A new class 'magic_number' is defined and the 'validate' method is overloaded// to validate the values of that class using Boost.Regex.// To test, run// // regex -m 123-456// regex -m 123-4567// // The first invocation should output://// The magic is "456"//// and the second invocation should issue an error message.#include #include using namespace boost;using namespace boost::program_options;#include using namespace std;/* Define a completely non-sensical class. */struct magic_number {public: magic_number(int n) : n(n) {} int n;};/* Overload the 'validate' function for the user-defined class. It makes sure that value is of form XXX-XXX where X are digits and converts the second group to an integer. This has no practical meaning, meant only to show how regex can be used to validate values.*/void validate(boost::any& v, const std::vector& values, magic_number*, int){ static regex r("\\d\\d\\d-(\\d\\d\\d)"); using namespace boost::program_options; // Make sure no previous assignment to 'a' was made. validators::check_first_occurrence(v); // Extract the first string from 'values'. If there is more than // one string, it's an error, and exception will be thrown. const string& s = validators::get_single_string(values); // Do regex match and convert the interesting part to // int. smatch match; if (regex_match(s, match, r)) { v = any(magic_number(lexical_cast(match[1]))); } else { throw validation_error(validation_error::invalid_option_value); } }int main(int ac, char* av[]){ try { options_description desc("Allowed options"); desc.add_options() ("help", "produce a help screen") ("version,v", "print the version number") ("magic,m", value(), "magic value (in NNN-NNN format)") ; variables_map vm; store(parse_command_line(ac, av, desc), vm); if (vm.count("help")) { cout << "Usage: regex [options]\n"; cout << desc; return 0; } if (vm.count("version")) { cout << "Version 1.\n"; return 0; } if (vm.count("magic")) { cout << "The magic is \"" << vm["magic"].as().n << "\"\n"; } } catch(std::exception& e) { cout << e.what() << "\n"; } }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章