// 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"; } }