Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57746 - in trunk: boost/program_options libs/program_options/src libs/program_options/test
From: ghost_at_[hidden]
Date: 2009-11-18 08:35:15


Author: vladimir_prus
Date: 2009-11-18 08:35:14 EST (Wed, 18 Nov 2009)
New Revision: 57746
URL: http://svn.boost.org/trac/boost/changeset/57746

Log:
Add option name to a few exception classes.

Fixes #3423. Patch from Sascha Ochsenknecht.

Added:
   trunk/libs/program_options/test/exception_test.cpp (contents, props changed)
Text files modified:
   trunk/boost/program_options/cmdline.hpp | 2
   trunk/boost/program_options/errors.hpp | 50 ++++++++++++++++++++++++++++++++++++---
   trunk/libs/program_options/src/value_semantic.cpp | 10 +++++++
   trunk/libs/program_options/src/variables_map.cpp | 10 ++++++++
   trunk/libs/program_options/test/Jamfile.v2 | 1
   5 files changed, 67 insertions(+), 6 deletions(-)

Modified: trunk/boost/program_options/cmdline.hpp
==============================================================================
--- trunk/boost/program_options/cmdline.hpp (original)
+++ trunk/boost/program_options/cmdline.hpp 2009-11-18 08:35:14 EST (Wed, 18 Nov 2009)
@@ -26,7 +26,7 @@
     enum style_t {
         /// Allow "--long_name" style
         allow_long = 1,
- /// Alow "-<single character" style
+ /// Allow "-<single character" style
         allow_short = allow_long << 1,
         /// Allow "-" in short options
         allow_dash_for_short = allow_short << 1,

Modified: trunk/boost/program_options/errors.hpp
==============================================================================
--- trunk/boost/program_options/errors.hpp (original)
+++ trunk/boost/program_options/errors.hpp 2009-11-18 08:35:14 EST (Wed, 18 Nov 2009)
@@ -42,8 +42,20 @@
     class BOOST_PROGRAM_OPTIONS_DECL unknown_option : public error {
     public:
         unknown_option(const std::string& name)
- : error(std::string("unknown option ").append(name))
+ : error(std::string("unknown option ").append(name)),
+ m_option_name(name)
         {}
+
+ // gcc says that throw specification on dtor is loosened
+ // without this line
+ ~unknown_option() throw() {}
+
+ const std::string& get_option_name() const throw()
+ {
+ return m_option_name;
+ }
+ private:
+ std::string m_option_name;
     };
 
     /** Class thrown when there's ambiguity amoung several possible options. */
@@ -65,7 +77,19 @@
         user called a method which cannot return them all. */
     class BOOST_PROGRAM_OPTIONS_DECL multiple_values : public error {
     public:
- multiple_values(const std::string& what) : error(what) {}
+ multiple_values(const std::string& what)
+ : error(what), m_option_name() {}
+ ~multiple_values() throw() {}
+
+ void set_option_name(const std::string& option);
+
+ const std::string& get_option_name() const throw()
+ {
+ return m_option_name;
+ }
+ private:
+ std::string m_option_name; // The name of the option which
+ // caused the exception.
     };
 
     /** Class thrown when there are several occurrences of an
@@ -73,7 +97,20 @@
         them all. */
     class BOOST_PROGRAM_OPTIONS_DECL multiple_occurrences : public error {
     public:
- multiple_occurrences(const std::string& what) : error(what) {}
+ multiple_occurrences(const std::string& what)
+ : error(what), m_option_name() {}
+ ~multiple_occurrences() throw() {}
+
+ void set_option_name(const std::string& option);
+
+ const std::string& get_option_name() const throw()
+ {
+ return m_option_name;
+ }
+
+ private:
+ std::string m_option_name; // The name of the option which
+ // caused the exception.
     };
 
     /** Class thrown when value of option is incorrect. */
@@ -82,7 +119,12 @@
         validation_error(const std::string& what) : error(what) {}
         ~validation_error() throw() {}
         void set_option_name(const std::string& option);
-
+
+ const std::string& get_option_name() const throw()
+ {
+ return m_option_name;
+ }
+
         const char* what() const throw();
     private:
         mutable std::string m_message; // For on-demand formatting in 'what'

Modified: trunk/libs/program_options/src/value_semantic.cpp
==============================================================================
--- trunk/libs/program_options/src/value_semantic.cpp (original)
+++ trunk/libs/program_options/src/value_semantic.cpp 2009-11-18 08:35:14 EST (Wed, 18 Nov 2009)
@@ -220,9 +220,17 @@
                        .append(convert_value(bad_value))
                        .append("'"))
     {}
-#endif
+#endif
 
+ void multiple_values::set_option_name(const std::string& option_name)
+ {
+ m_option_name = option_name;
+ }
 
+ void multiple_occurrences::set_option_name(const std::string& option_name)
+ {
+ m_option_name = option_name;
+ }
 
     void validation_error::set_option_name(const std::string& option_name)
     {

Modified: trunk/libs/program_options/src/variables_map.cpp
==============================================================================
--- trunk/libs/program_options/src/variables_map.cpp (original)
+++ trunk/libs/program_options/src/variables_map.cpp 2009-11-18 08:35:14 EST (Wed, 18 Nov 2009)
@@ -80,6 +80,16 @@
                 e.set_option_name(name);
                 throw;
             }
+ catch(multiple_occurrences& e)
+ {
+ e.set_option_name(name);
+ throw;
+ }
+ catch(multiple_values& e)
+ {
+ e.set_option_name(name);
+ throw;
+ }
 #endif
             v.m_value_semantic = d.semantic();
             

Modified: trunk/libs/program_options/test/Jamfile.v2
==============================================================================
--- trunk/libs/program_options/test/Jamfile.v2 (original)
+++ trunk/libs/program_options/test/Jamfile.v2 2009-11-18 08:35:14 EST (Wed, 18 Nov 2009)
@@ -27,6 +27,7 @@
     [ po-test positional_options_test.cpp ]
     [ po-test unicode_test.cpp ]
     [ po-test winmain.cpp ]
+ [ po-test exception_test.cpp ]
     ;
         
 exe test_convert : test_convert.cpp ;

Added: trunk/libs/program_options/test/exception_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/program_options/test/exception_test.cpp 2009-11-18 08:35:14 EST (Wed, 18 Nov 2009)
@@ -0,0 +1,127 @@
+// Copyright Sascha Ochsenknecht 2009.
+// 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)
+
+
+#include <boost/program_options/parsers.hpp>
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/cmdline.hpp>
+using namespace boost::program_options;
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <cassert>
+using namespace std;
+
+#include "minitest.hpp"
+
+
+
+void test_unknown_option()
+{
+ options_description desc;
+ desc.add_options()
+ ("cfgfile,c", value<string>(), "the configfile")
+ ;
+
+ const char* cmdline[] = {"program", "-c", "file", "-f", "anotherfile"};
+
+ variables_map vm;
+ try {
+ store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
+ const_cast<char**>(cmdline), desc), vm);
+ }
+ catch (unknown_option& e)
+ {
+ BOOST_CHECK_EQUAL(e.get_option_name(), "-f");
+ BOOST_CHECK_EQUAL(string(e.what()), "unknown option -f");
+ }
+}
+
+
+
+void test_multiple_values()
+{
+ options_description desc;
+ desc.add_options()
+ ("cfgfile,c", value<string>()->multitoken(), "the config file")
+ ("output,o", value<string>(), "the output file")
+ ;
+
+ const char* cmdline[] = { "program", "-o", "fritz", "hugo", "--cfgfile", "file", "c", "-o", "text.out" };
+
+ variables_map vm;
+ try {
+ store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
+ const_cast<char**>(cmdline), desc), vm);
+ notify(vm);
+ }
+ catch (validation_error& e)
+ {
+ // TODO: this is currently validation_error, shouldn't it be multiple_values ???
+ //
+ // multiple_values is thrown only at one place untyped_value::xparse(),
+ // but I think this can never be reached
+ // because: untyped_value always has one value and this is filtered before reach specific
+ // validation and parsing
+ //
+ BOOST_CHECK_EQUAL(e.get_option_name(), "cfgfile");
+ BOOST_CHECK_EQUAL(string(e.what()), "in option 'cfgfile': multiple values not allowed");
+ }
+}
+
+
+void test_multiple_occurrences()
+{
+ options_description desc;
+ desc.add_options()
+ ("cfgfile,c", value<string>(), "the configfile")
+ ;
+
+ const char* cmdline[] = {"program", "--cfgfile", "file", "-c", "anotherfile"};
+
+ variables_map vm;
+ try {
+ store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
+ const_cast<char**>(cmdline), desc), vm);
+ notify(vm);
+ }
+ catch (multiple_occurrences& e)
+ {
+ BOOST_CHECK_EQUAL(e.get_option_name(), "cfgfile");
+ BOOST_CHECK_EQUAL(string(e.what()), "multiple_occurrences");
+ }
+}
+
+
+
+
+int main(int /*ac*/, char** /*av*/)
+{
+ test_unknown_option();
+ test_multiple_values();
+ test_multiple_occurrences();
+
+ bool helpflag = false;
+
+ options_description desc;
+ desc.add_options()
+ ("cfgfile,c", value<string>(), "the configfile")
+ ("help,h", value<bool>(&helpflag)->implicit_value(true), "help")
+ ;
+
+ const char* cmdline[] = {"program", "--cfgfile", "hugo", "-h", "yes" };
+
+ variables_map vm;
+ store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
+ const_cast<char**>(cmdline), desc), vm);
+ notify(vm);
+
+ cout << " help: " << (helpflag ? "true" : "false") << endl;
+
+
+ return 0;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk