Ticket #2982: patch_ticket2982_2.diff

File patch_ticket2982_2.diff, 6.7 KB (added by s.ochsenknecht@…, 13 years ago)

patch

  • 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
  • boost/program_options/variables_map.hpp

     
    120120        */
    121121        const variable_value& operator[](const std::string& name) const;
    122122
     123        /** Returns number of non-empty value of variable 'name' */
     124        std::size_t count(const std::string& name) const;
     125       
    123126        /** Sets next variable map, which will be used to find
    124127           variables not found in *this. */
    125128        void next(abstract_variables_map* next);
     
    147150        // Resolve conflict between inherited operators.
    148151        const variable_value& operator[](const std::string& name) const
    149152        { return abstract_variables_map::operator[](name); }
    150 
     153       
     154        std::size_t count(const std::string& name) const
     155        { return abstract_variables_map::count(name); }
     156       
    151157    private:
    152158        /** Implementation of abstract_variables_map::get
    153159            which does 'find' in *this. */
  • libs/program_options/src/variables_map.cpp

     
    1212#include <boost/program_options/variables_map.hpp>
    1313
    1414#include <cassert>
     15#include <iostream>
    1516
    1617namespace boost { namespace program_options {
    1718
     
    9596
    9697       
    9798       
    98         // Second, apply default values.
     99        // Second, apply default values and required options
    99100        const vector<shared_ptr<option_description> >& all = desc.options();
    100101        for(i = 0; i < all.size(); ++i)
    101102        {
     
    117118                    m[key] = variable_value(def, true);
    118119                    m[key].m_value_semantic = d.semantic();
    119120                }
    120             }       
     121            }
     122           
     123            // add empty value if this is an required option
     124            if (d.semantic()->is_required()) {
     125               if (m.count(key) == 0) {
     126                  m[key] = variable_value();
     127                  m[key].m_value_semantic = d.semantic();
     128               }
     129            }
    121130        }
    122131    }
    123132
     
    145154            */
    146155            if (k->second.m_value_semantic)
    147156                k->second.m_value_semantic->notify(k->second.value());
    148         }               
     157        }
     158       
     159        // This checks if all required options occur
     160        for (map<string, variable_value>::const_iterator k = vm.begin();
     161             k != vm.end();
     162             ++k)
     163        {
     164           if (k->second.empty() && k->second.m_value_semantic
     165                  &&  k->second.m_value_semantic->is_required()) {
     166              boost::throw_exception(required_option(
     167                                                  k->first));
     168
     169           }
     170        }
    149171    }
    150172
    151173    abstract_variables_map::abstract_variables_map()
     
    178200    {
    179201        m_next = next;
    180202    }
     203   
     204    std::size_t abstract_variables_map::count(const std::string& name) const
     205    {
     206       const variable_value& v = get(name);
     207       std::size_t c = (v.empty() ? 0 : 1);
     208       return (m_next ? (c + (*m_next).count(name)) : c);   
     209    }
    181210
    182211    variables_map::variables_map()
    183212    {}
  • libs/program_options/src/cmdline.cpp

     
    309309            }
    310310        }
    311311        result.swap(result2);
    312        
    313312
    314313        // Assign position keys to positional options.
    315314        int position_key = 0;