claw  1.9.0
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 
44 claw::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 
59 bool claw::arguments_table::argument_attributes::operator<(
60  const argument_attributes& that) const
61 {
62  return m_name < that.m_name;
63 }
64 
68 std::string
69 claw::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 
87 std::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 
102 std::string
103 claw::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 
116 const std::string& claw::arguments_table::argument_attributes::get_name() const
117 {
118  return m_name;
119 }
120 
124 const std::string&
125 claw::arguments_table::argument_attributes::get_second_name() const
126 {
127  return m_second_name;
128 }
129 
133 bool claw::arguments_table::argument_attributes::is_optional() const
134 {
135  return m_optional;
136 }
137 
142 claw::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 
165 void 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 
183 void 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 
199 void 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 
215 void 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 
239 void 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 
313 bool 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 
360 bool 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 
384 const std::string& claw::arguments_table::get_program_name() const
385 {
386  return m_arguments.get_program_name();
387 }
388 
393 bool 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 
407 int 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 
426 double 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 
445 const std::string&
446 claw::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 
464 std::list<int>
465 claw::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 
488 std::list<double>
489 claw::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 
512 std::list<std::string>
513 claw::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 
541 void claw::arguments_table::add_argument(const std::string& arg)
542 {
543  m_arguments.add_argument(arg);
544 }
545 
552 void 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 
584 std::size_t
585 claw::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 }
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 required_fields_are_set() const
Tell if all arguments not marqued as "optional" have been specified in the command line...
void help(const std::string &free_args="") const
Print some help about the arguments.
arguments_table(const std::string &prog_name)
Constructor.
double get_real(const std::string &arg_name) const
Get the real value of an argument.
bool only_integer_values(const std::string &arg_name) const
Tell if only integer values are associated to an argument.
super::const_iterator const_iterator
The type of the iterator used to access non modifiable values.
Definition: ordered_set.hpp:53
const std::string & get_program_name() const
Get the name of the program.
std::list< int > get_all_of_integer(const std::string &arg_name) const
Get all integer values of an argument.
int get_integer(const std::string &arg_name) const
Get the integer value of an argument.
void add_argument(const std::string &arg)
Add an argument in our list.
bool only_real_values(const std::string &arg_name) const
Tell if only real values are associated to an argument.
void parse(int &argc, char **&argv)
Parse the command line arguments.
A class to manage the arguments of your program, with automatic management of short/long arguments an...
std::list< double > get_all_of_real(const std::string &arg_name) const
Get all real values of an argument.
bool has_value(const std::string &arg_name) const
Tell if an argument has a value.
Some assert macros to strengthen you code.
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.
std::list< std::string > get_all_of_string(const std::string &arg_name) const
Get all string values of an argument.
const std::string & get_string(const std::string &arg_name) const
Get the string value of an argument.
bool get_bool(const std::string &arg_name) const
Get the boolean state of an argument.
This is the main namespace.
Definition: application.hpp:49
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.
#define CLAW_PRECOND(b)
Abort the program if a precondition is not true.
Definition: assert.hpp:94