Boost logo

Boost :

From: Vladislav Lazarenko (snail_at_[hidden])
Date: 2005-04-20 12:14:35


Hi there again, I've add the feature we talk about. Unfortunately I have no CVS
code with boost sources and can't make "cvs diff -u boost/program_options
libs/program_options". So... I've copy file to file.org, change code and make
"diff -dru file.org file" etc (see diff files in attachment).

As a result I got:

# D:\SnaiL\Projects\SMSMan\bin>smsman --help --help
# Unable to parse command line: Multiple option 'help' is not allowed.

As you can see, exception reason now is: "Multiple option 'help' is not allowed"

--
Volodya, I am not sure that I need to change tests, moreone I don't know how to 
test.... So, let's discuss it.
Please make peer-review and let me know about the result.
P.S.: Hm... Now I became a contributor? :-)) very interesting.
Vladislav Lazarenko wrote:
> Okey-dockey, I will make this change as soon as possible and post a 
> patch here.
> 
> Vladimir Prus wrote:
> 
>> Hi Vladislav,
>>
>>
>>> Good day, guys. I am new to boost and have some qestion concerns
>>> boost::program_options library. I've wrote a simple program (see code
>>> below), and when I trying to pass multiple '--help' option to the 
>>> program,
>>> it throws exception with reason "multiple_occurrences". This exception
>>> reason may confuse the end-user, I wanna get some more pretty error
>>> description.
>>>
>>> So, I have only 2 solutions:
>>>
>>> 1) Prase exception reason and give a user more informative/pretty
>>> description. 2) Refactor boost::program_options to enable it to throw
>>> exceptions with informative reason.
>>
>>
>>
>> The second approach is clearly better. Even adding passing the name of 
>> the
>> duplicate option to the message would help. Are you willing to code this
>> change?
>>
>>
>>> I need a hint from professional. BTW, how can I contribute to
>>> boost::program_options? 
>>
>>
>>
>> Just by sending patches to this list ;-) Or more speicifcally, the 
>> output of
>> "cvs diff -u boost/program_options libs/program_options".
>>
>> Thanks,
>> Volodya
>>
>>
>> _______________________________________________
>> Unsubscribe & other changes: 
>> http://lists.boost.org/mailman/listinfo.cgi/boost
>>
> 
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

--- variables_map.cpp.org 2004-09-16 11:10:28.000000000 +0300
+++ variables_map.cpp 2005-04-20 18:54:04.999875000 +0300
@@ -72,7 +72,7 @@
                 v = variable_value();
             }
             try {
- d.semantic()->parse(v.value(), options.options[i].value, utf8);
+ d.semantic()->parse(v.value(), options.options[i].value, utf8, name);
             }
             catch(validation_error& e)
             {


--- value_semantic.hpp.org 2004-09-20 10:14:18.000000000 +0300
+++ value_semantic.hpp 2005-04-20 19:39:17.281250000 +0300
@@ -144,7 +144,8 @@
     void
     typed_value<T, charT>::
     xparse(boost::any& value_store,
- const std::vector<std::basic_string<charT> >& new_tokens) const
+ const std::vector<std::basic_string<charT> >& new_tokens,
+ const std::string & opt_name) const
     {
         validate(value_store, new_tokens, (T*)0, 0);
     }


--- value_semantic.cpp.org 2004-09-21 10:20:02.000000000 +0300
+++ value_semantic.cpp 2005-04-20 20:01:51.640625000 +0300
@@ -16,7 +16,7 @@
     value_semantic_codecvt_helper<char>::
     parse(boost::any& value_store,
           const std::vector<std::string>& new_tokens,
- bool utf8) const
+ bool utf8, const std::string & opt_name) const
     {
         if (utf8) {
 #ifndef BOOST_NO_STD_WSTRING
@@ -26,13 +26,13 @@
                 std::wstring w = from_utf8(new_tokens[i]);
                 local_tokens.push_back(to_local_8_bit(w));
             }
- xparse(value_store, local_tokens);
+ xparse(value_store, local_tokens, opt_name);
 #else
             throw std::runtime_error("UTF-8 conversion not supported.");
 #endif
         } else {
             // Already in local encoding, pass unmodified
- xparse(value_store, new_tokens);
+ xparse(value_store, new_tokens, opt_name);
         }
     }
 
@@ -41,7 +41,7 @@
     value_semantic_codecvt_helper<wchar_t>::
     parse(boost::any& value_store,
           const std::vector<std::string>& new_tokens,
- bool utf8) const
+ bool utf8, const std::string & opt_name) const
     {
         std::vector<wstring> tokens;
         if (utf8) {
@@ -57,7 +57,7 @@
             }
         }
 
- xparse(value_store, tokens);
+ xparse(value_store, tokens, opt_name);
     }
 #endif
 
@@ -71,12 +71,22 @@
 
     void
     untyped_value::xparse(boost::any& value_store,
- const std::vector<std::string>& new_tokens) const
+ const std::vector<std::string>& new_tokens,
+ const std::string & opt_name) const
     {
- if (!value_store.empty())
- throw multiple_occurrences("multiple_occurrences");
+ if (!value_store.empty())
+ {
+ std::string reason = "Multiple option '";
+ reason.append(opt_name).append("' is not allowed");
+ throw multiple_occurrences(reason);
+ }
+
         if (new_tokens.size() > 1)
- throw multiple_values("multiple_values");
+ {
+ std::string reason = "Multiple values for option '";
+ reason.append(opt_name).append("' is not allowed");
+ throw multiple_values(reason);
+ }
         value_store = new_tokens.empty() ? std::string("") : new_tokens.front();
     }
 


--- value_semantic.hpp.org 2004-09-15 13:57:32.000000000 +0300
+++ value_semantic.hpp 2005-04-20 19:10:11.890625000 +0300
@@ -56,8 +56,7 @@
         */
         virtual void parse(boost::any& value_store,
                            const std::vector<std::string>& new_tokens,
- bool utf8) const
- = 0;
+ bool utf8, const std::string & opt_name) const = 0;
 
         /** Called to assign default value to 'value_store'. Returns
             true if default value is assigned, and false if no default
@@ -85,11 +84,11 @@
     private: // base overrides
         void parse(boost::any& value_store,
                    const std::vector<std::string>& new_tokens,
- bool utf8) const;
+ bool utf8, const std::string & opt_name) const;
     protected: // interface for derived classes.
         virtual void xparse(boost::any& value_store,
- const std::vector<std::string>& new_tokens)
- const = 0;
+ const std::vector<std::string>& new_tokens,
+ const std::string & opt_name) const = 0;
     };
 
     template<>
@@ -98,12 +97,12 @@
     private: // base overrides
         void parse(boost::any& value_store,
                    const std::vector<std::string>& new_tokens,
- bool utf8) const;
+ bool utf8, const std::string & opt_name) const;
     protected: // interface for derived classes.
 #if !defined(BOOST_NO_STD_WSTRING)
         virtual void xparse(boost::any& value_store,
- const std::vector<std::wstring>& new_tokens)
- const = 0;
+ const std::vector<std::wstring>& new_tokens,
+ const std::string & opt_name) const = 0;
 #endif
     };
     /** Class which specifies a simple handling of a value: the value will
@@ -128,7 +127,8 @@
             any modifications.
          */
         void xparse(boost::any& value_store,
- const std::vector<std::string>& new_tokens) const;
+ const std::vector<std::string>& new_tokens,
+ const std::string & opt_name) const;
 
         /** Does nothing. */
         bool apply_default(boost::any&) const { return false; }
@@ -225,8 +225,8 @@
         /** Creates an instance of the 'validator' class and calls
             its operator() to perform athe ctual conversion. */
         void xparse(boost::any& value_store,
- const std::vector< std::basic_string<charT> >& new_tokens)
- const;
+ const std::vector< std::basic_string<charT> >& new_tokens,
+ const std::string & opt_name) const;
 
         /** If default value was specified via previous call to
             'default_value', stores that value into 'value_store'.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk