claw 1.9.0
 
Loading...
Searching...
No Matches
arguments_table.cpp
Go to the documentation of this file.
1/*
2 CLAW - a C++ Library Absolutely Wonderful
3
4 CLAW is a free library without any particular aim but being useful to
5 anyone.
6
7 Copyright (C) 2005-2011 Julien Jorge
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
23 contact: julien.jorge@stuff-o-matic.com
24*/
31
32#include <claw/assert.hpp>
33#include <iomanip>
34#include <iostream>
35
44claw::arguments_table::argument_attributes::argument_attributes(
45 const std::string& name, const std::string& second_name,
46 const std::string& help_message, bool optional,
47 const std::string& value_type)
48 : m_name(name)
49 , m_second_name(second_name)
50 , m_help_message(help_message)
51 , m_optional(optional)
52 , m_value_type(value_type)
53{}
54
59bool claw::arguments_table::argument_attributes::operator<(
60 const argument_attributes& that) const
61{
62 return m_name < that.m_name;
63}
64
68std::string
69claw::arguments_table::argument_attributes::format_short_help() const
70{
71 std::string result(m_name);
72
73 if(!m_value_type.empty())
74 result += "=" + m_value_type;
75
76 if(m_optional)
77 return "[" + result + "]";
78 else
79 return result;
80}
81
87std::string claw::arguments_table::argument_attributes::format_long_help(
88 std::size_t arguments_width) const
89{
90 std::ostringstream result;
91
92 result << std::left << std::setw(arguments_width)
93 << format_long_help_arguments() << ' ' << m_help_message;
94
95 return result.str();
96}
97
102std::string
103claw::arguments_table::argument_attributes::format_long_help_arguments() const
104{
105 std::string result(m_name);
106
107 if(!m_second_name.empty())
108 result += ", " + m_second_name;
109
110 return result;
111}
112
116const std::string& claw::arguments_table::argument_attributes::get_name() const
117{
118 return m_name;
119}
120
124const std::string&
125claw::arguments_table::argument_attributes::get_second_name() const
126{
127 return m_second_name;
128}
129
133bool claw::arguments_table::argument_attributes::is_optional() const
134{
135 return m_optional;
136}
137
142claw::arguments_table::arguments_table(const std::string& prog_name)
143 : m_arguments(prog_name)
144{}
145
154 : m_arguments(argc, argv, claw::math::ordered_set<std::string>())
155{}
156
165void claw::arguments_table::add(const std::string& short_name,
166 const std::string& long_name,
167 const std::string& help_msg, bool optional,
168 const std::string& val_name)
169{
170 m_short_arguments.insert(argument_attributes(short_name, long_name, help_msg,
171 optional, val_name));
172 m_long_arguments.insert(argument_attributes(long_name, short_name, help_msg,
173 optional, val_name));
174}
175
183void claw::arguments_table::add_long(const std::string& long_name,
184 const std::string& help_msg,
185 bool optional,
186 const std::string& val_name)
187{
188 m_long_arguments.insert(
189 argument_attributes(long_name, "", help_msg, optional, val_name));
190}
191
199void claw::arguments_table::add_short(const std::string& short_name,
200 const std::string& help_msg,
201 bool optional,
202 const std::string& val_name)
203{
204 m_short_arguments.insert(
205 argument_attributes(short_name, "", help_msg, optional, val_name));
206}
207
215void claw::arguments_table::parse(int& argc, char**& argv)
216{
219
220 for(it = m_short_arguments.begin(); it != m_short_arguments.end(); ++it)
221 allowed.insert(it->get_name());
222
223 for(it = m_long_arguments.begin(); it != m_long_arguments.end(); ++it)
224 allowed.insert(it->get_name());
225
226 m_arguments.parse(argc, argv, allowed);
227}
228
239void claw::arguments_table::help(const std::string& free_args) const
240{
241 std::cout << m_arguments.get_program_name();
242
244
245 std::list<set_iterator> optional;
246 std::list<set_iterator>::const_iterator it_opt;
247 set_iterator it;
248
249 for(it = m_short_arguments.begin(); it != m_short_arguments.end(); ++it)
250 if(it->is_optional())
251 optional.push_back(it);
252 else
253 std::cout << ' ' << it->format_short_help();
254
255 for(it = m_long_arguments.begin(); it != m_long_arguments.end(); ++it)
256 if(it->get_second_name().empty())
257 {
258 if(it->is_optional())
259 optional.push_back(it);
260 else
261 std::cout << ' ' << it->format_short_help();
262 }
263
264 for(it_opt = optional.begin(); it_opt != optional.end(); ++it_opt)
265 std::cout << ' ' << (*it_opt)->format_short_help();
266
267 if(!free_args.empty())
268 std::cout << ' ' << free_args;
269
270 std::cout << "\n\n";
271
272 const std::size_t description_column(
273 get_maximum_long_help_arguments_width());
274
275 for(it = m_short_arguments.begin(); it != m_short_arguments.end(); ++it)
276 std::cout << " " << it->format_long_help(description_column) << '\n';
277
278 for(it = m_long_arguments.begin(); it != m_long_arguments.end(); ++it)
279 if(it->get_second_name().empty())
280 std::cout << " " << it->format_long_help(description_column) << '\n';
281}
282
292{
293 bool ok = true;
295
296 for(it = m_short_arguments.begin(); (it != m_short_arguments.end()) && ok;
297 ++it)
298 if(!it->is_optional())
299 ok = ok && has_value(it->get_name());
300
301 for(it = m_long_arguments.begin(); (it != m_long_arguments.end()) && ok;
302 ++it)
303 if(!it->is_optional())
304 ok = ok && has_value(it->get_name());
305
306 return ok;
307}
308
313bool claw::arguments_table::has_value(const std::string& arg_name) const
314{
315 bool result = false;
316 std::string short_name, long_name;
317
318 get_argument_names(arg_name, short_name, long_name);
319
320 if(!short_name.empty())
321 result = m_arguments.has_value(short_name);
322
323 if(!result)
324 if(!long_name.empty())
325 result = m_arguments.has_value(long_name);
326
327 return result;
328}
329
335 const std::string& arg_name) const
336{
337 bool result = true;
338 std::string short_name, long_name;
339
340 get_argument_names(arg_name, short_name, long_name);
341
342 if(short_name.empty() && long_name.empty())
343 result = false;
344 else
345 {
346 if(!short_name.empty())
347 result = m_arguments.only_integer_values(short_name);
348
349 if(!long_name.empty())
350 result = result && m_arguments.only_integer_values(long_name);
351 }
352
353 return result;
354}
355
360bool claw::arguments_table::only_real_values(const std::string& arg_name) const
361{
362 bool result = true;
363 std::string short_name, long_name;
364
365 get_argument_names(arg_name, short_name, long_name);
366
367 if(short_name.empty() && long_name.empty())
368 result = false;
369 else
370 {
371 if(!short_name.empty())
372 result = m_arguments.only_real_values(short_name);
373
374 if(!long_name.empty())
375 result = result && m_arguments.only_real_values(long_name);
376 }
377
378 return result;
379}
380
385{
386 return m_arguments.get_program_name();
387}
388
393bool claw::arguments_table::get_bool(const std::string& arg_name) const
394{
395 std::string short_name, long_name;
396
397 get_argument_names(arg_name, short_name, long_name);
398
399 return m_arguments.get_bool(short_name) || m_arguments.get_bool(long_name);
400}
401
407int claw::arguments_table::get_integer(const std::string& arg_name) const
408{
409 CLAW_PRECOND(has_value(arg_name));
410
411 std::string short_name, long_name;
412
413 get_argument_names(arg_name, short_name, long_name);
414
415 if(m_arguments.has_value(short_name))
416 return m_arguments.get_integer(short_name);
417 else
418 return m_arguments.get_integer(long_name);
419}
420
426double claw::arguments_table::get_real(const std::string& arg_name) const
427{
428 CLAW_PRECOND(has_value(arg_name));
429
430 std::string short_name, long_name;
431
432 get_argument_names(arg_name, short_name, long_name);
433
434 if(m_arguments.has_value(short_name))
435 return m_arguments.get_real(short_name);
436 else
437 return m_arguments.get_real(long_name);
438}
439
445const std::string&
446claw::arguments_table::get_string(const std::string& arg_name) const
447{
448 CLAW_PRECOND(has_value(arg_name));
449
450 std::string short_name, long_name;
451
452 get_argument_names(arg_name, short_name, long_name);
453
454 if(m_arguments.has_value(short_name))
455 return m_arguments.get_string(short_name);
456 else
457 return m_arguments.get_string(long_name);
458}
459
464std::list<int>
465claw::arguments_table::get_all_of_integer(const std::string& arg_name) const
466{
467 std::list<int> result;
468 std::string short_name, long_name;
469
470 get_argument_names(arg_name, short_name, long_name);
471
472 if(!short_name.empty())
473 result = m_arguments.get_all_of_integer(short_name);
474
475 if(!long_name.empty())
476 {
477 const std::list<int> p(m_arguments.get_all_of_integer(long_name));
478 result.insert(result.end(), p.begin(), p.end());
479 }
480
481 return result;
482}
483
488std::list<double>
489claw::arguments_table::get_all_of_real(const std::string& arg_name) const
490{
491 std::list<double> result;
492 std::string short_name, long_name;
493
494 get_argument_names(arg_name, short_name, long_name);
495
496 if(!short_name.empty())
497 result = m_arguments.get_all_of_real(short_name);
498
499 if(!long_name.empty())
500 {
501 const std::list<double> p(m_arguments.get_all_of_real(long_name));
502 result.insert(result.end(), p.begin(), p.end());
503 }
504
505 return result;
506}
507
512std::list<std::string>
513claw::arguments_table::get_all_of_string(const std::string& arg_name) const
514{
515 std::list<std::string> result;
516 std::string short_name, long_name;
517
518 get_argument_names(arg_name, short_name, long_name);
519
520 if(!short_name.empty())
521 result = m_arguments.get_all_of_string(short_name);
522
523 if(!long_name.empty())
524 {
525 const std::list<std::string> p(m_arguments.get_all_of_string(long_name));
526 result.insert(result.end(), p.begin(), p.end());
527 }
528
529 return result;
530}
531
541void claw::arguments_table::add_argument(const std::string& arg)
542{
543 m_arguments.add_argument(arg);
544}
545
552void claw::arguments_table::get_argument_names(const std::string& arg_name,
553 std::string& short_name,
554 std::string& long_name) const
555{
556 argument_attributes attr(arg_name, "", "", false, "");
558
559 // if arg_name is short, try to find the long version
560 it = m_short_arguments.find(attr);
561
562 if(it != m_short_arguments.end())
563 {
564 short_name = arg_name;
565 long_name = it->get_second_name();
566 }
567 else
568 {
569 // if arg_name is long, try to find the short version
570 it = m_long_arguments.find(attr);
571
572 if(it != m_long_arguments.end())
573 {
574 short_name = it->get_second_name();
575 long_name = arg_name;
576 }
577 }
578}
579
584std::size_t
585claw::arguments_table::get_maximum_long_help_arguments_width() const
586{
588 std::size_t result(0);
589
590 for(it = m_short_arguments.begin(); it != m_short_arguments.end(); ++it)
591 result = std::max(result, it->format_long_help_arguments().size());
592
593 for(it = m_long_arguments.begin(); it != m_long_arguments.end(); ++it)
594 if(it->get_second_name().empty())
595 result = std::max(result, it->format_long_help_arguments().size());
596
597 return result;
598}
A class to manage the arguments of your program, with automatic management of short/long arguments an...
Some assert macros to strengthen you code.
#define CLAW_PRECOND(b)
Abort the program if a precondition is not true.
Definition assert.hpp:94
void help(const std::string &free_args="") const
Print some help about the arguments.
const std::string & get_string(const std::string &arg_name) const
Get the string value of an argument.
std::list< double > get_all_of_real(const std::string &arg_name) const
Get all real values of an argument.
arguments_table(const std::string &prog_name)
Constructor.
bool has_value(const std::string &arg_name) const
Tell if an argument has a value.
bool only_integer_values(const std::string &arg_name) const
Tell if only integer values are associated to an argument.
int get_integer(const std::string &arg_name) const
Get the integer value of an argument.
const std::string & get_program_name() const
Get the name of the program.
void add_short(const std::string &short_name, const std::string &help_msg="", bool optional=false, const std::string &val_name="")
Add an argument in the table.
void add_long(const std::string &long_name, const std::string &help_msg="", bool optional=false, const std::string &val_name="")
Add an argument in the table.
void add_argument(const std::string &arg)
Add an argument in our list.
void parse(int &argc, char **&argv)
Parse the command line arguments.
std::list< std::string > get_all_of_string(const std::string &arg_name) const
Get all string values of an argument.
bool get_bool(const std::string &arg_name) const
Get the boolean state of an argument.
std::list< int > get_all_of_integer(const std::string &arg_name) const
Get all integer values of an argument.
void add(const std::string &short_name, const std::string &long_name, const std::string &help_msg="", bool optional=false, const std::string &val_name="")
Add an argument in the table.
bool only_real_values(const std::string &arg_name) const
Tell if only real values are associated to an argument.
bool required_fields_are_set() const
Tell if all arguments not marqued as "optional" have been specified in the command line.
double get_real(const std::string &arg_name) const
Get the real value of an argument.
A class to manage sets of ordered items.
super::const_iterator const_iterator
The type of the iterator used to access non modifiable values.
Manipulation of mathematic, geometric, etc. items.
Definition box_2d.hpp:38
This is the main namespace.