Ticket #3423: ticket3423.patch

File ticket3423.patch, 9.3 KB (added by Sascha Ochsenknecht <s.ochsenknecht@…>, 13 years ago)

patch

  • boost/program_options/cmdline.hpp

     
    2626    enum style_t {
    2727        /// Allow "--long_name" style
    2828        allow_long = 1,
    29         /// Alow "-<single character" style
     29        /// Allow "-<single character" style
    3030        allow_short = allow_long << 1,
    3131        /// Allow "-" in short options
    3232        allow_dash_for_short = allow_short << 1,
  • boost/program_options/errors.hpp

     
    2121    class BOOST_PROGRAM_OPTIONS_DECL error : public std::logic_error {
    2222    public:
    2323        error(const std::string& what) : std::logic_error(what) {}
     24
    2425    };
    2526
    2627    class BOOST_PROGRAM_OPTIONS_DECL invalid_syntax : public error {
     
    4243    class BOOST_PROGRAM_OPTIONS_DECL unknown_option : public error {
    4344    public:
    4445        unknown_option(const std::string& name)
    45         : error(std::string("unknown option ").append(name))
     46        : error(std::string("unknown option ").append(name)),
     47          m_option_name(name)
    4648        {}
     49
     50        // gcc says that throw specification on dtor is loosened
     51        // without this line
     52        ~unknown_option() throw() {}
     53       
     54        const std::string& get_option_name() const throw()
     55        {
     56           return m_option_name;
     57        }
     58    private:
     59       std::string m_option_name;
    4760    };
    4861
    4962    /** Class thrown when there's ambiguity amoung several possible options. */
     
    6578        user called a method which cannot return them all. */
    6679    class BOOST_PROGRAM_OPTIONS_DECL multiple_values : public error {
    6780    public:
    68         multiple_values(const std::string& what) : error(what) {}
     81        multiple_values(const std::string& what)
     82         : error(what), m_option_name() {}
     83        ~multiple_values() throw() {}
     84       
     85        void set_option_name(const std::string& option);
     86       
     87        const std::string& get_option_name() const throw()
     88        {
     89           return m_option_name;
     90        }
     91    private:
     92        std::string m_option_name; // The name of the option which
     93                                   // caused the exception.       
    6994    };
    7095
    7196    /** Class thrown when there are several occurrences of an
     
    7398        them all. */
    7499    class BOOST_PROGRAM_OPTIONS_DECL multiple_occurrences : public error {
    75100    public:
    76         multiple_occurrences(const std::string& what) : error(what) {}
     101        multiple_occurrences(const std::string& what)
     102         : error(what), m_option_name() {}
     103        ~multiple_occurrences() throw() {}
     104       
     105        void set_option_name(const std::string& option);
     106       
     107        const std::string& get_option_name() const throw()
     108        {
     109           return m_option_name;
     110        }
     111
     112    private:       
     113        std::string m_option_name; // The name of the option which
     114                                   // caused the exception.
    77115    };
    78116
    79117    /** Class thrown when value of option is incorrect. */
     
    82120        validation_error(const std::string& what) : error(what) {}
    83121        ~validation_error() throw() {}
    84122        void set_option_name(const std::string& option);
    85 
     123       
     124        const std::string& get_option_name() const throw()
     125        {
     126           return m_option_name;
     127        }
     128       
    86129        const char* what() const throw();
    87130    private:
    88131        mutable std::string m_message; // For on-demand formatting in 'what'
  • libs/program_options/test/Jamfile.v2

     
    2727    [ po-test positional_options_test.cpp ]
    2828    [ po-test unicode_test.cpp ]
    2929    [ po-test winmain.cpp ]
     30    [ po-test exception_test.cpp ]
    3031    ;
    3132       
    3233exe test_convert : test_convert.cpp ;   
  • libs/program_options/test/exception_test.cpp

     
     1// Copyright Sascha Ochsenknecht 2009.
     2// Distributed under the Boost Software License, Version 1.0.
     3// (See accompanying file LICENSE_1_0.txt
     4// or copy at http://www.boost.org/LICENSE_1_0.txt)
     5
     6
     7#include <boost/program_options/parsers.hpp>
     8#include <boost/program_options/options_description.hpp>
     9#include <boost/program_options/variables_map.hpp>
     10#include <boost/program_options/cmdline.hpp>
     11using namespace boost::program_options;
     12
     13#include <iostream>
     14#include <sstream>
     15#include <vector>
     16#include <cassert>
     17using namespace std;
     18
     19#include "minitest.hpp"
     20
     21
     22
     23void test_unknown_option()
     24{
     25   options_description desc;
     26   desc.add_options()
     27        ("cfgfile,c", value<string>(), "the configfile")
     28      ;
     29
     30   const char* cmdline[] = {"program", "-c", "file", "-f", "anotherfile"};
     31   
     32   variables_map vm;
     33   try {
     34      store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
     35                                    const_cast<char**>(cmdline), desc), vm);
     36   }
     37   catch (unknown_option& e)
     38   {
     39      BOOST_CHECK_EQUAL(e.get_option_name(), "-f");     
     40      BOOST_CHECK_EQUAL(string(e.what()), "unknown option -f");
     41   }
     42}
     43
     44
     45
     46void test_multiple_values()
     47{
     48   options_description desc;
     49   desc.add_options()
     50        ("cfgfile,c", value<string>()->multitoken(), "the config file")
     51        ("output,o", value<string>(), "the output file")
     52      ;
     53
     54   const char* cmdline[] = { "program", "-o", "fritz", "hugo", "--cfgfile", "file", "c", "-o", "text.out" };
     55   
     56   variables_map vm;
     57   try {
     58      store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
     59                                    const_cast<char**>(cmdline), desc), vm);
     60      notify(vm);
     61   }
     62   catch (validation_error& e)
     63   {
     64      // TODO: this is currently validation_error, shouldn't it be multiple_values ???
     65      //
     66      //   multiple_values is thrown only at one place untyped_value::xparse(),
     67      //    but I think this can never be reached
     68      //   because: untyped_value always has one value and this is filtered before reach specific
     69      //   validation and parsing
     70      //
     71      BOOST_CHECK_EQUAL(e.get_option_name(), "cfgfile");     
     72      BOOST_CHECK_EQUAL(string(e.what()), "in option 'cfgfile': multiple values not allowed");
     73   }
     74}
     75
     76
     77void test_multiple_occurrences()
     78{
     79   options_description desc;
     80   desc.add_options()
     81        ("cfgfile,c", value<string>(), "the configfile")
     82      ;
     83
     84   const char* cmdline[] = {"program", "--cfgfile", "file", "-c", "anotherfile"};
     85   
     86   variables_map vm;
     87   try {
     88      store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
     89                                    const_cast<char**>(cmdline), desc), vm);
     90      notify(vm);
     91   }
     92   catch (multiple_occurrences& e)
     93   {
     94      BOOST_CHECK_EQUAL(e.get_option_name(), "cfgfile");     
     95      BOOST_CHECK_EQUAL(string(e.what()), "multiple_occurrences");
     96   }
     97}
     98
     99
     100
     101
     102int main(int /*ac*/, char** /*av*/)
     103{
     104   test_unknown_option();
     105   test_multiple_values();
     106   test_multiple_occurrences();
     107
     108   bool helpflag = false;
     109
     110   options_description desc;
     111   desc.add_options()
     112        ("cfgfile,c", value<string>(), "the configfile")
     113        ("help,h", value<bool>(&helpflag)->implicit_value(true), "help")
     114      ;
     115
     116   const char* cmdline[] = {"program", "--cfgfile", "hugo", "-h", "yes"  };
     117   
     118   variables_map vm;
     119      store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
     120                                    const_cast<char**>(cmdline), desc), vm);
     121      notify(vm);
     122
     123   cout << " help: " << (helpflag ? "true" : "false") << endl;
     124
     125
     126   return 0;
     127}
  • libs/program_options/src/value_semantic.cpp

     
    223223#endif                       
    224224
    225225
     226    void multiple_values::set_option_name(const std::string& option_name)
     227    {
     228        m_option_name = option_name;
     229    }
    226230
     231
     232
     233    void multiple_occurrences::set_option_name(const std::string& option_name)
     234    {
     235        m_option_name = option_name;
     236    }
     237
     238
     239
    227240    void validation_error::set_option_name(const std::string& option_name)
    228241    {
    229242        m_option_name = option_name;
  • libs/program_options/src/variables_map.cpp

     
    8080                e.set_option_name(name);
    8181                throw;
    8282            }
     83            catch(multiple_occurrences& e)
     84            {
     85                e.set_option_name(name);
     86                throw;
     87            }
     88            catch(multiple_values& e)
     89            {
     90                e.set_option_name(name);
     91                throw;
     92            }
    8393#endif
    8494            v.m_value_semantic = d.semantic();
    8595