2012-10-06 18 views
8

Tôi đang sử dụng tăng program_options 1.50.0Bạn muốn cho phép các tùy chọn được chỉ định nhiều lần khi sử dụng các tùy chọn chương trình tăng cường. Ngay bây giờ tôi nhận được nhiều lần xuất hiện

tôi muốn cho phép sau đây cho chương trình foobar tôi foobar --debug 2 --debug 3

Từ mã tăng program_options, có là một ví dụ regex.cpp rằng cho thấy việc tạo một loại mới và tạo trình xác thực cho loại đó.
Tôi cố gắng đó, và nó hoạt động, nhưng bây giờ tôi không thể sử dụng một số các add_options khác() typed_value tùy chọn, như DEFAULT_VALUE, sáng tác vv

Đây là những gì tôi đã cố gắng cho đến nay:

#include <boost/program_options.hpp> 

    using namespace boost; 

    using namespace boost::program_options; 

    #include <iostream> 
    using namespace std; 
    struct lastmultioccurrenceint { 
     public: 
     lastmultioccurrenceint(int n) : n(n) {} 
     int n; 
    };  

void validate(boost::any& v, 
        const std::vector<std::string>& xs, 
        //const std::vector< std::basic_string<charT> >& xs, 
        lastmultioccurrenceint* , int) 
    { 
     using namespace boost::program_options; 

     cerr << "IN VALIDATE" << endl; 
     //validators::check_first_occurrence(v); 
     string s = validators::get_single_string(xs); 
     if (!v.empty()) { 
      cerr << "\tPRINTTING MULTIOCCURENCE WARNING, allowing v to be overwritten" << endl; 
      cerr << "\tEarlier value was: " << boost::any_cast<int>(v) << endl; 
      cerr << "\tNew value is: " << s << endl; 
     } 
     try { 
      //v = any(lastmultioccurrenceint(lexical_cast<int>(sx))); 
      //v = any(lexical_cast<int>(sx)); // works 
      v = any(lexical_cast<int>(s)); 
      //v = any(lexical_cast<lastmultioccurrenceint>(s)); 
      //v = any(4); 
     //} 
     /*catch(const bad_lexical_cast&) { 
      boost::throw_exception(validation_error::invalid_option_value(s)); 
     } */ 
     } 
     catch(const bad_lexical_cast&) { 
      throw validation_error(validation_error::invalid_option_value); 
     } 
     cerr << "made it through" << endl; 

     int main (int argc, char **argv) { 

    variables_map m_varMap; 
     // define style 
     // unix_style = (allow_short | short_allow_adjacent | short_allow_next 
     //   | allow_long | long_allow_adjacent | long_allow_next 
     //   | allow_sticky | allow_guessing 
     //   | allow_dash_for_short), 
     // ... allows typical unix-style options 
     // allow_long_disguise = can use "-" instead of "--" 
     // Reference: http://www.boost.org/doc/libs/1_42_0/doc/html/boost/program_options/command_line_style/style_t.html 
     // 
    try { 

    ProgOpts::command_line_style::style_t style = ProgOpts::command_line_style::style_t(
      ProgOpts::command_line_style::unix_style | 
      //ProgOpts::command_line_style::case_insensitive | 
      ProgOpts::command_line_style::allow_long_disguise); 

    options_description options("YDD"); 

    //lastmultioccurrenceint debugOpt; 

    options.add_options() 
    ("debug", value<lastmultioccurrenceint>(), "debug value (0-4), default is 0 (performance mode)") 
    //("debug", value<lastmultioccurrenceint>(&debugOpt)->default_value(0)->composing(), "debug value (0-4), default is 0 (performance mode)") 
    ; 

     //ProgOpts::parsed_options firstPreParsed = ProgOpts::command_line_parser(argc,argv).options(options).style(style).allow_unregistered().run(); 
     ProgOpts::parsed_options firstPreParsed = ProgOpts::command_line_parser(argc,argv).options(options).allow_unregistered().run(); 
    ProgOpts::store(firstPreParsed, m_varMap); 

    ProgOpts::notify(m_varMap); 
    } 
    /*catch (boost::program_options::multiple_occurrences &e) { 
     cerr << "GOT MULTIPLES" << endl; 
     cerr << "Option Name: " << e.get_option_name() << endl; 
     cerr << e.what() << endl; 
    } 
    catch(boost::bad_any_cast& e) { 
     cerr << "WRONG TYPE" << endl; 
     cerr << e.what() << endl; 
    } */ 
    catch(std::exception& e) { 
     cerr << "SOMETHING ELSE" << endl; 
     cerr << e.what() << endl; 
    } 
    catch(...) { 
     cerr << "UNKNOWN ERROR" << endl; 
    } 

    cerr << "DEBUG OPT IS: " << m_varMap["debug"].as<int>() << endl; 
} 

Vì vậy, nếu tôi làm: foobar --debug 2 --debug 3

Nếu tôi nhận xét ra tùy chọn gỡ lỗi hiện tại ....

("debug", value<lastmultioccurrenceint>(), "debug value (0-4), default is 0 (performance mode)") 

... và bỏ ghi chú cho hai dòng sau:

lastmultioccurrenceint debugOpt; 
("debug", value<lastmultioccurrenceint>(&debugOpt)->default_value(0)->composing(), "debug value (0-4), default is 0 (performance mode)") 

... sau đó nó thậm chí không biên dịch.

Bạn có biết cách thực hiện điều này để nó cho phép tôi sử dụng default_value và soạn? Nó có thể được kế thừa từ typed_value, nhưng tôi đã không tìm thấy một cách tốt để làm điều này được nêu ra.

+0

nó không phải là rõ ràng với tôi những gì bạn đang cố gắng để đạt được. Thư viện sẵn sàng hỗ trợ những gì dường như là cú pháp mong muốn của bạn 'foobar --debug 2 --debug 3' với một' std :: vector 'làm kiểu tùy chọn. –

+0

Tôi muốn tùy chọn thứ hai ghi đè tùy chọn đầu tiên. Vì vậy, trong ví dụ của bạn, nó sẽ đặt tùy chọn gỡ lỗi thành 3. –

Trả lời

5

Tôi không nghĩ bạn cần xác định loại tùy chỉnh với trình xác thực để đạt được kết quả mong muốn. Nó có thể được thực hiện với sự hỗ trợ thông tin ngữ nghĩa hiện có của thư viện. Hãy xem xét ví dụ này

#include <boost/assign/list_of.hpp> 
#include <boost/program_options.hpp> 
#include <boost/version.hpp> 

#include <iostream> 

int 
main(int argc, char** argv) 
{ 
    namespace po = boost::program_options; 

    po::options_description desc("Options"); 

    typedef std::vector<unsigned> DebugValues; 
    DebugValues debug; 
    desc.add_options() 
     ("help,h", "produce help message") 
     ("debug", po::value<DebugValues>(&debug)->default_value(boost::assign::list_of(0), "0")->composing(), "set debug level") 

     ; 

    po::variables_map vm; 
    try { 
     const po::positional_options_description p; // note empty positional options 
     po::store(
       po::command_line_parser(argc, argv). 
          options(desc). 
          positional(p). 
          run(), 
          vm 
         ); 
     po::notify(vm); 

     if (vm.count("help")) { 
      std::cout << desc << "\n"; 
      std::cout << "boost version: " << BOOST_LIB_VERSION << std::endl; 
      return 0; 
     } 
    } catch (const boost::program_options::error& e) { 
     std::cerr << e.what() << std::endl; 
    } 

    std::cout << "got " << debug.size() << " debug values" << std::endl; 
    if (!debug.empty()) { 
     DebugValues::const_iterator value(debug.end()); 
     std::advance(value, -1); 
     std::cout << "using last value of " << *value << std::endl; 
    } 
} 

và mẫu sử dụng:

samm$ ./a.out -h 
Options: 
    -h [ --help ]   produce help message 
    --debug arg (=0)  set debug level 

boost version: 1_46_1 
samm$ ./a.out --debug 1 --debug 2 
got 2 debug values 
using last value of 2 
samm$ ./a.out --debug 4 --debug 1 
got 2 debug values 
using last value of 1 
samm$ ./a.out --debug 4 --debug 1 --debug 9 
got 3 debug values 
using last value of 9 
samm$ 
+0

Tôi thấy điểm của bạn, nhưng tôi muốn có thể truy cập tùy chọn gỡ lỗi dưới dạng số nguyên trong suốt chương trình. –

+0

Ví dụ: 'mẫu T CCommandLineArgs :: GetOption (const string & strOption) const' là một hàm tôi sử dụng để truy cập tất cả đối số dòng lệnh. Tôi có vài nơi trong chương trình của tôi, nơi tôi gọi là 'GetOption ("debug") '. Tôi muốn duy trì loại giao diện này cho tất cả các tùy chọn dòng lệnh. –

+0

Bên trong "GetOption" Tôi không muốn có mã đặc biệt cho các tùy chọn cụ thể. Tôi đoán tôi chỉ có thể nhìn vào loại DebugValues ​​và làm những gì bạn đề nghị mỗi khi nó là loại dữ liệu được sử dụng .... –

Các vấn đề liên quan