Ticket #2982: patch_ticket2982_2.diff
File patch_ticket2982_2.diff, 6.7 KB (added by , 13 years ago) |
---|
-
boost/program_options/errors.hpp
38 38 std::string tokens, msg; 39 39 }; 40 40 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 41 49 /** Class thrown when option name is not recognized. */ 42 50 class BOOST_PROGRAM_OPTIONS_DECL unknown_option : public error { 43 51 public: -
boost/program_options/value_semantic.hpp
44 44 */ 45 45 virtual bool is_composing() const = 0; 46 46 47 /** Returns true if value must be given. Non-optional value 48 49 */ 50 virtual bool is_required() const = 0; 51 47 52 /** Parses a group of tokens that specify a value of option. 48 53 Stores the result in 'value_store', using whatever representation 49 54 is desired. May be be called several times if value of the same … … 132 137 133 138 bool is_composing() const { return false; } 134 139 140 bool is_required() const { return false; } 141 135 142 /** If 'value_store' is already initialized, or new_tokens 136 143 has more than one elements, throws. Otherwise, assigns 137 144 the first string from 'new_tokens' to 'value_store', without … … 177 184 the value when it's known. The parameter can be NULL. */ 178 185 typed_value(T* store_to) 179 186 : 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) 181 189 {} 182 190 183 191 /** Specifies default value, which will be used … … 265 273 m_zero_tokens = true; 266 274 return this; 267 275 } 276 277 typed_value* required() 278 { 279 m_required = true; 280 return this; 281 } 268 282 269 283 270 284 public: // value semantic overrides … … 292 306 } 293 307 } 294 308 309 bool is_required() const { return m_required; } 295 310 311 296 312 /** Creates an instance of the 'validator' class and calls 297 313 its operator() to perform the actual conversion. */ 298 314 void xparse(boost::any& value_store, … … 335 351 std::string m_default_value_as_text; 336 352 boost::any m_implicit_value; 337 353 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; 339 355 boost::function1<void, const T&> m_notifier; 340 356 }; 341 357 -
boost/program_options/variables_map.hpp
120 120 */ 121 121 const variable_value& operator[](const std::string& name) const; 122 122 123 /** Returns number of non-empty value of variable 'name' */ 124 std::size_t count(const std::string& name) const; 125 123 126 /** Sets next variable map, which will be used to find 124 127 variables not found in *this. */ 125 128 void next(abstract_variables_map* next); … … 147 150 // Resolve conflict between inherited operators. 148 151 const variable_value& operator[](const std::string& name) const 149 152 { 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 151 157 private: 152 158 /** Implementation of abstract_variables_map::get 153 159 which does 'find' in *this. */ -
libs/program_options/src/variables_map.cpp
12 12 #include <boost/program_options/variables_map.hpp> 13 13 14 14 #include <cassert> 15 #include <iostream> 15 16 16 17 namespace boost { namespace program_options { 17 18 … … 95 96 96 97 97 98 98 // Second, apply default values .99 // Second, apply default values and required options 99 100 const vector<shared_ptr<option_description> >& all = desc.options(); 100 101 for(i = 0; i < all.size(); ++i) 101 102 { … … 117 118 m[key] = variable_value(def, true); 118 119 m[key].m_value_semantic = d.semantic(); 119 120 } 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 } 121 130 } 122 131 } 123 132 … … 145 154 */ 146 155 if (k->second.m_value_semantic) 147 156 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 } 149 171 } 150 172 151 173 abstract_variables_map::abstract_variables_map() … … 178 200 { 179 201 m_next = next; 180 202 } 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 } 181 210 182 211 variables_map::variables_map() 183 212 {} -
libs/program_options/src/cmdline.cpp
309 309 } 310 310 } 311 311 result.swap(result2); 312 313 312 314 313 // Assign position keys to positional options. 315 314 int position_key = 0;