2012-10-06 36 views
8

मैं बढ़ावा program_options 1.50.0बूस्ट प्रोग्राम विकल्पों का उपयोग करते समय विकल्पों को कई बार निर्दिष्ट करने की अनुमति देना चाहते हैं। अभी मैं अनेक गतिविधियां

उपयोग कर रहा हूँ मैं अपने कार्यक्रम foobar foobar --debug 2 --debug 3

बढ़ावा program_options कोड से निम्नलिखित की अनुमति देना चाहते हो, वहाँ एक उदाहरण regex.cpp है कि एक नया प्रकार बनाने और उस प्रकार के लिए एक वैधकर्ता बनाने दिखाता है।
मैंने कोशिश की है कि, और यह काम करता है, लेकिन अब मैं अन्य add_options() typed_value विकल्प, DEFAULT_VALUE, रचना की तरह से कुछ का उपयोग नहीं कर सकते हैं, आदि

यहाँ मैं अब तक की कोशिश की है:

#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; 
} 

मैं करता हूँ तो अगर: foobar --debug 2 --debug 3

अगर मैं वर्तमान डिबग विकल्प बाहर टिप्पणी ....

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

... और निम्नलिखित दो पंक्तियों को अपूर्ण करें:

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

... तो यह संकलित भी नहीं होता है।

क्या आप जानते हैं कि यह कैसे करें ताकि यह मुझे डिफ़ॉल्ट_वैल्यू और रचना का उपयोग करने की अनुमति दे? यह typed_value से विरासत में हो सकता है, लेकिन मुझे अभी तक ऐसा करने का कोई अच्छा तरीका नहीं मिला है।

+0

यह मेरे लिए स्पष्ट आप क्या हासिल करने की कोशिश कर रहे हैं नहीं है। लाइब्रेरी आसानी से समर्थन करता है जो आपके वांछित सिंटैक्स 'foobar --debug 2 --debug 3'' विकल्प प्रकार के रूप में 'std :: vector ' के साथ दिखाई देता है। –

+0

मैं पहले विकल्प को ओवरराइड करने का दूसरा विकल्प चाहता हूं। तो आपके उदाहरण में, यह डीबग विकल्प को 3. –

उत्तर

5

मुझे नहीं लगता कि आपको वांछित परिणाम प्राप्त करने के लिए एक वैध प्रकार के साथ एक वैध प्रकार को परिभाषित करने की आवश्यकता है। यह पुस्तकालय के मौजूदा अर्थपूर्ण सूचना समर्थन के साथ किया जा सकता है। इस उदाहरण पर विचार

#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; 
    } 
} 

और नमूना उपयोग:

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

पर सेट करेगा, मैं आपका पॉइंट देखता हूं, लेकिन मैं पूरे कार्यक्रम में एक पूर्णांक के रूप में डीबग विकल्प तक पहुंचने में सक्षम होना चाहता हूं। –

+0

उदाहरण के लिए: 'टेम्पलेट टी CCommandLineArgs :: GetOption (कॉन्स स्ट्रिंग और स्ट्रॉप्शन) const' एक ऐसा फ़ंक्शन है जिसका उपयोग मैं सभी कमांड लाइन तर्कों तक पहुंचने के लिए करता हूं। मेरे पास मेरे कार्यक्रम में कई जगहें हैं जहां मैं 'GetOption ("डीबग") कहता हूं। मैं सभी कमांड लाइन विकल्पों के लिए इस तरह के इंटरफ़ेस को बनाए रखना चाहता हूं। –

+0

"GetOption" के अंदर मैं विशेष विकल्पों के लिए विशेष कोड नहीं चाहता हूं। मुझे लगता है कि मैं सिर्फ डीबगवेल्यूज़ को देख सकता हूं और जब भी आप डेटा का इस्तेमाल करते हैं, तो हर बार सुझाव देते हैं .... –