123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- // 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 <boost/program_options.hpp>
- #include <boost/regex.hpp>
- using namespace boost;
- using namespace boost::program_options;
- #include <iostream>
- 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<std::string>& 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<int>(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_number>(),
- "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<magic_number>().n << "\"\n";
- }
- }
- catch(std::exception& e)
- {
- cout << e.what() << "\n";
- }
- }
|