Ticket #2982: patch_ticket2982.diff

File patch_ticket2982.diff, 5.5 KB (added by s.ochsenknecht@…, 13 years ago)
  • boost/program_options/errors.hpp

     
    3838        std::string tokens, msg;
    3939    };
    4040
     41    /** Class thrown when a required/mandatory option is missing */
     42    class BOOST_PROGRAM_OPTIONS_DECL required_option : public error {
     43    public:
     44       required_option(const std::string& name)
     45       : error(std::string("missing required option ").append(name))
     46       {}
     47    };
     48
    4149    /** Class thrown when option name is not recognized. */
    4250    class BOOST_PROGRAM_OPTIONS_DECL unknown_option : public error {
    4351    public:
  • boost/program_options/value_semantic.hpp

     
    4444        */
    4545        virtual bool is_composing() const = 0;
    4646       
     47        /** Returns true if value must be given. Non-optional value
     48
     49        */
     50        virtual bool is_required() const = 0;
     51
    4752        /** Parses a group of tokens that specify a value of option.
    4853            Stores the result in 'value_store', using whatever representation
    4954            is desired. May be be called several times if value of the same
     
    132137
    133138        bool is_composing() const { return false; }
    134139       
     140        bool is_required() const { return false; }
     141
    135142        /** If 'value_store' is already initialized, or new_tokens
    136143            has more than one elements, throws. Otherwise, assigns
    137144            the first string from 'new_tokens' to 'value_store', without
     
    177184            the value when it's known. The parameter can be NULL. */
    178185        typed_value(T* store_to)
    179186        : m_store_to(store_to), m_composing(false),
    180           m_multitoken(false), m_zero_tokens(false)
     187          m_multitoken(false), m_zero_tokens(false),
     188          m_required(false)
    181189        {}
    182190
    183191        /** Specifies default value, which will be used
     
    265273            m_zero_tokens = true;
    266274            return this;
    267275        }
     276
     277        typed_value* required()
     278        {
     279            m_required = true;
     280            return this;
     281        }
    268282           
    269283
    270284    public: // value semantic overrides
     
    292306            }
    293307        }
    294308
     309        bool is_required() const { return m_required; }
    295310
     311
    296312        /** Creates an instance of the 'validator' class and calls
    297313            its operator() to perform the actual conversion. */
    298314        void xparse(boost::any& value_store,
     
    335351        std::string m_default_value_as_text;
    336352        boost::any m_implicit_value;
    337353        std::string m_implicit_value_as_text;
    338         bool m_composing, m_implicit, m_multitoken, m_zero_tokens;
     354        bool m_composing, m_implicit, m_multitoken, m_zero_tokens, m_required;
    339355        boost::function1<void, const T&> m_notifier;
    340356    };
    341357
  • libs/program_options/src/value_semantic.cpp

     
    171171        check_first_occurrence(v);
    172172        string s(get_single_string(xs));
    173173        if (!s.empty() && (
    174                 (*s.begin() == '\'' && *s.rbegin() == '\'' ||
    175                  *s.begin() == '"' && *s.rbegin() == '"')))
     174                ((*s.begin() == '\'' && *s.rbegin() == '\'') ||
     175                 (*s.begin() == '"' && *s.rbegin() == '"'))))
    176176        {
    177177            v = any(s.substr(1, s.size()-2));
    178178        }
    179179        else
     180        {
    180181            v = any(s);
     182        }
    181183    }
    182184
    183185#if !defined(BOOST_NO_STD_WSTRING)
     
    186188    {
    187189        check_first_occurrence(v);
    188190        wstring s(get_single_string(xs));
    189         if (*s.begin() == L'\'' && *s.rbegin() == L'\'' ||
    190             *s.begin() == L'"' && *s.rbegin() == L'"')
     191        if ((*s.begin() == L'\'' && *s.rbegin() == L'\'') ||
     192            (*s.begin() == L'"' && *s.rbegin() == L'"'))
    191193            v = any(s.substr(1, s.size()-2));
    192194        else
    193195            v = any(s);
  • libs/program_options/src/cmdline.cpp

     
    309309            }
    310310        }
    311311        result.swap(result2);
    312        
    313312
     313        // This checks if all required options occur
     314        const std::vector< shared_ptr<option_description> >&
     315                                         all_options = m_desc->options();
     316        for (unsigned i = 0; i < all_options.size(); ++i) {
     317           if (all_options[i]->semantic()->is_required()) {
     318              bool found_required = false;
     319              for (unsigned j = 0; !found_required && j < result.size(); ++j) {
     320                 if (all_options[i]->key(result[j].string_key) == result[j].string_key) { // REVISIT, is this compare ok?
     321                    found_required = true;
     322                 }
     323              }
     324              if (!found_required) {
     325                 boost::throw_exception(required_option(
     326                                            all_options[i]->format_name()));
     327              }
     328           }
     329        }
     330
    314331        // Assign position keys to positional options.
    315332        int position_key = 0;
    316333        for(unsigned i = 0; i < result.size(); ++i) {