paludis  Version 2.6.0
args_option.hh
Go to the documentation of this file.
1 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
2 
3 /*
4  * Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Ciaran McCreesh
5  * Copyright (c) 2006 Stephen Bennett
6  *
7  * This file is part of the Paludis package manager. Paludis is free software;
8  * you can redistribute it and/or modify it under the terms of the GNU General
9  * Public License version 2, as published by the Free Software Foundation.
10  *
11  * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18  * Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 #ifndef PALUDIS_GUARD_ARGS_ARGS_OPTION_HH
22 #define PALUDIS_GUARD_ARGS_ARGS_OPTION_HH 1
23 
24 #include <paludis/util/pimp.hh>
25 #include <paludis/util/wrapped_forward_iterator.hh>
26 #include <paludis/util/type_list.hh>
27 #include <paludis/util/named_value.hh>
28 #include <paludis/util/visitor.hh>
30 #include <memory>
31 
32 /** \file
33  * Declarations for ArgsOption.
34  *
35  * \ingroup g_args
36  *
37  * \section Examples
38  *
39  * - None at this time.
40  */
41 
42 namespace paludis
43 {
44  namespace n
45  {
46  typedef Name<struct name_description> description;
47  typedef Name<struct name_long_name> long_name;
48  typedef Name<struct name_short_name> short_name;
49  }
50 
51  namespace args
52  {
53  class ArgsGroup;
54  class StringArg;
55  class AliasArg;
56  class SwitchArg;
57  class IntegerArg;
58  class EnumArg;
59  class StringSetArg;
60  class StringSequenceArg;
61 
62  enum ArgsOptionSpecifiedness
63  {
64  aos_not,
65  aos_weak,
66  aos_specified
67  };
68 
69  /**
70  * Base class for a command line option.
71  *
72  * \ingroup g_args
73  */
75  public virtual DeclareAbstractAcceptMethods<ArgsOption, MakeTypeList<
76  StringArg, AliasArg, SwitchArg, IntegerArg, EnumArg, StringSetArg, StringSequenceArg>::Type>
77  {
78  friend class ArgsHandler;
79 
80  private:
81  ArgsGroup * const _group;
82 
83  const std::string _long_name;
84  const char _short_name;
85  const std::string _description;
86 
87  ArgsOptionSpecifiedness _specified;
88 
89  ArgsOption(const ArgsOption &);
90  void operator= (const ArgsOption &);
91 
92  protected:
93  /**
94  * Constructor.
95  */
96  ArgsOption(ArgsGroup * const, const std::string & long_name,
97  const char short_name, const std::string & description);
98 
99  /**
100  * Destructor.
101  */
102  virtual ~ArgsOption();
103 
104  public:
105  /**
106  * Remove this option. Removes our group from its
107  * section if the group would be left empty.
108  */
109  void remove();
110 
111  /**
112  * Fetch our long name.
113  */
114  const std::string & long_name() const
115  {
116  return _long_name;
117  }
118 
119  /**
120  * Fetch our short name (may be 0).
121  */
122  char short_name() const
123  {
124  return _short_name;
125  }
126 
127  /**
128  * Fetch our description.
129  */
130  const std::string & description() const
131  {
132  return _description;
133  }
134 
135  /**
136  * Fetch whether or not we were specified on the
137  * command line (or as an env var).
138  */
139  virtual bool specified() const
140  {
141  return _specified != aos_not;
142  }
143 
144  /**
145  * Fetch whether or not we were explicitly (not
146  * an env var) specified. Used to catch -x y -x z
147  * where -x takes a single value.
148  */
149  virtual bool explicitly_specified() const
150  {
151  return _specified == aos_specified;
152  }
153 
154  /**
155  * Set the value returned by specified().
156  */
157  virtual void set_specified(const ArgsOptionSpecifiedness value)
158  {
159  _specified = value;
160  }
161 
162  /**
163  * Fetch our group.
164  */
166  {
167  return _group;
168  }
169 
170  /**
171  * Can we be negated?
172  *
173  * Needs to match up with ArgsVisitor logic.
174  */
175  virtual bool can_be_negated() const = 0;
176 
177  /**
178  * Ourself as a forwardable string.
179  *
180  * For example, '--foo bar' or '--foo bar --foo baz' or '--foo', or
181  * if not specified, the empty string.
182  *
183  * \since 0.40
184  */
185  virtual const std::string forwardable_string() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
186 
187  /**
188  * Ourself as a sequence of strings.
189  *
190  * For example, { '--foo', 'bar' } or { '--foo', 'bar', '--foo', 'baz' }
191  * if not specified, an empty sequence.
192  *
193  * \since 0.46
194  */
195  virtual const std::shared_ptr<Sequence<std::string> > forwardable_args() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
196  };
197 
198  /**
199  * A SwitchArg is an option that can either be specified or not
200  * specified, and that takes no value (for example, --help).
201  *
202  * \ingroup g_args
203  */
205  public ArgsOption,
206  public ImplementAcceptMethods<ArgsOption, SwitchArg>
207  {
208  private:
209  bool _can_be_negated;
210 
211  public:
212  /**
213  * Constructor.
214  *
215  * \since 0.26
216  */
217  SwitchArg(ArgsGroup * const group, const std::string & long_name, char short_name,
218  const std::string & description, const bool can_be_negated);
219 
220  ~SwitchArg();
221 
222  virtual bool can_be_negated() const;
223 
224  virtual const std::string forwardable_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
225  virtual const std::shared_ptr<Sequence<std::string> > forwardable_args() const PALUDIS_ATTRIBUTE((warn_unused_result));
226  };
227 
228  /**
229  * An option that takes a string argument.
230  *
231  * \ingroup g_args
232  */
234  public ArgsOption,
235  public ImplementAcceptMethods<ArgsOption, StringArg>
236  {
237  private:
238  std::string _argument;
239  bool _can_be_negated;
240  void (* _validator) (const std::string &);
241 
242  public:
243  /**
244  * Constructor
245  */
246  StringArg(ArgsGroup * const, const std::string & long_name,
247  const char short_name, const std::string & description,
248  const bool can_be_negated = false);
249 
250  /**
251  * Constructor with validator.
252  */
253  StringArg(ArgsGroup * const, const std::string & long_name,
254  const char short_name, const std::string & description,
255  void (* validator) (const std::string &),
256  const bool can_be_negated = false);
257 
258  /**
259  * Fetch the argument that was given to this option.
260  */
261  const std::string & argument() const { return _argument; }
262 
263  /**
264  * Set the argument returned by argument().
265  */
266  void set_argument(const std::string & arg);
267 
268  virtual bool can_be_negated() const;
269 
270  virtual const std::string forwardable_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
271  virtual const std::shared_ptr<Sequence<std::string> > forwardable_args() const PALUDIS_ATTRIBUTE((warn_unused_result));
272  };
273 
274  /**
275  * An option that takes a set of strings.
276  *
277  * \ingroup g_args
278  * \nosubgrouping
279  */
281  public ArgsOption,
282  public ImplementAcceptMethods<ArgsOption, StringSetArg>
283  {
284  private:
285  Pimp<StringSetArg> _imp;
286 
287  void (* _validator) (const std::string &);
288 
289  public:
290  /**
291  * Helper class for passing available options and associated descriptions
292  * to the StringSetArg constructor.
293  *
294  * \ingroup grplibpaludisargs
295  */
297  {
298  friend class StringSetArg;
299 
300  private:
302 
303  public:
304  /**
305  * Constructor
306  */
307  StringSetArgOptions(const std::string &, const std::string &);
308 
309  /**
310  * Blank constructor
311  */
312  explicit StringSetArgOptions();
313 
314  /**
315  * Copy constructor
316  */
318 
319  /**
320  * Destructor.
321  */
323 
324  /**
325  * Adds another (option, description) pair.
326  */
327  StringSetArgOptions & operator() (const std::string &, const std::string &);
328  };
329 
330  ///\name Basic operations
331  ///\{
332 
333  StringSetArg(ArgsGroup * const, const std::string & long_name,
334  const char short_name, const std::string & description,
335  const StringSetArgOptions & options = StringSetArgOptions());
336 
337  StringSetArg(ArgsGroup * const, const std::string & long_name,
338  const char short_name, const std::string & description,
339  const StringSetArgOptions & options,
340  void (* validator) (const std::string &));
341 
342  ~StringSetArg();
343 
344  ///\}
345 
346  ///\name Iterate over our args.
347  ///\{
348 
349  struct ConstIteratorTag;
351 
352  ConstIterator begin_args() const;
353 
354  ConstIterator end_args() const;
355 
356  ///\}
357 
358  /**
359  * Add an argument to the set.
360  */
361  void add_argument(const std::string & arg);
362 
363  ///\name Iterate over our allowed arguments and associated descriptions
364  ///\{
365 
366  struct AllowedArgConstIteratorTag;
367  typedef WrappedForwardIterator<AllowedArgConstIteratorTag,
368  const std::pair<std::string, std::string> > AllowedArgConstIterator;
369 
370  AllowedArgConstIterator begin_allowed_args() const;
371 
372  AllowedArgConstIterator end_allowed_args() const;
373 
374  ///\}
375 
376  virtual bool can_be_negated() const;
377 
378  virtual const std::string forwardable_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
379  virtual const std::shared_ptr<Sequence<std::string> > forwardable_args() const PALUDIS_ATTRIBUTE((warn_unused_result));
380  };
381 
382  /**
383  * An option that takes a set of strings.
384  *
385  * \since 0.32
386  * \ingroup g_args
387  * \nosubgrouping
388  */
390  public ArgsOption,
391  public ImplementAcceptMethods<ArgsOption, StringSequenceArg>
392  {
393  private:
395 
396  public:
397  ///\name Basic operations
398  ///\{
399 
400  StringSequenceArg(ArgsGroup * const, const std::string & long_name,
401  const char short_name, const std::string & description);
402 
404 
405  ///\}
406 
407  ///\name Iterate over our args.
408  ///\{
409 
410  struct ConstIteratorTag;
412 
413  ConstIterator begin_args() const;
414 
415  ConstIterator end_args() const;
416 
417  ///\}
418 
419  /**
420  * Add an argument to the set.
421  */
422  void add_argument(const std::string & arg);
423 
424  virtual bool can_be_negated() const;
425 
426  virtual const std::string forwardable_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
427  virtual const std::shared_ptr<Sequence<std::string> > forwardable_args() const PALUDIS_ATTRIBUTE((warn_unused_result));
428  };
429 
430 
431  /**
432  * An AliasArg is an alias for another argument.
433  *
434  * \ingroup g_args
435  */
437  public ArgsOption,
438  public ImplementAcceptMethods<ArgsOption, AliasArg>
439  {
440  private:
441  ArgsOption * const _other;
442  bool _hidden;
443 
444  public:
445  /**
446  * Constructor.
447  */
448  AliasArg(ArgsOption * const other, const std::string & new_long_name, bool is_hidden = false);
449 
450  virtual bool specified() const
451  {
452  return _other->specified();
453  }
454 
455  virtual bool explicitly_specified() const
456  {
457  return _other->explicitly_specified();
458  }
459 
460  virtual void set_specified(const ArgsOptionSpecifiedness value)
461  {
462  _other->set_specified(value);
463  }
464 
465  virtual bool hidden() const
466  {
467  return _hidden;
468  }
469 
470  virtual void set_hidden(const bool value)
471  {
472  _hidden = value;
473  }
474 
475  /**
476  * Fetch our associated option.
477  */
478  ArgsOption * other() const
479  {
480  return _other;
481  }
482 
483  virtual bool can_be_negated() const;
484 
485  virtual const std::string forwardable_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
486  virtual const std::shared_ptr<Sequence<std::string> > forwardable_args() const PALUDIS_ATTRIBUTE((warn_unused_result));
487  };
488 
489  /**
490  * An option that takes an integer argument.
491  *
492  * \ingroup grplibpaludisargs
493  */
495  public ArgsOption,
496  public ImplementAcceptMethods<ArgsOption, IntegerArg>
497  {
498  private:
499  int _argument;
500 
501  public:
502  /**
503  * Constructor
504  */
505  IntegerArg(ArgsGroup * const, const std::string & long_name,
506  const char short_name, const std::string & description);
507  /**
508  * Fetch the argument that was given to this option.
509  */
510  int argument() const { return _argument; }
511 
512  /**
513  * Set the argument returned by argument().
514  */
515  void set_argument(const int arg) { _argument = arg; }
516 
517  virtual bool can_be_negated() const;
518 
519  virtual const std::string forwardable_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
520  virtual const std::shared_ptr<Sequence<std::string> > forwardable_args() const PALUDIS_ATTRIBUTE((warn_unused_result));
521  };
522 
523  /**
524  * An allowed argument for an EnumArg.
525  *
526  * \ingroup g_args
527  * \since 0.40
528  */
530  {
533 
534  /// Might be '\0', for none.
536  };
537 
538  /**
539  * An option that takes one of a predefined set of string arguments.
540  *
541  * \ingroup g_args
542  * \nosubgrouping
543  */
545  public ArgsOption,
546  public ImplementAcceptMethods<ArgsOption, EnumArg>
547  {
548  private:
549  Pimp<EnumArg> _imp;
550 
551  std::string _argument;
552  std::string _default_arg;
553 
554  public:
555  /**
556  * Helper class for passing available options and associated descriptions
557  * to the EnumArg constructor.
558  *
559  * \ingroup grplibpaludisargs
560  */
562  {
563  friend class EnumArg;
564 
565  private:
567 
568  public:
569  /**
570  * Constructor
571  */
572  EnumArgOptions(const std::string &, const std::string &);
573 
574  /**
575  * Constructor, with short arg.
576  *
577  * \since 0.40
578  */
579  EnumArgOptions(const std::string &, const char, const std::string &);
580 
581  /**
582  * Destructor.
583  */
584  ~EnumArgOptions();
585 
586  /**
587  * Adds another (option, description).
588  */
589  EnumArgOptions & operator() (const std::string &, const std::string &);
590 
591  /**
592  * Adds another (option, short-option, description).
593  *
594  * \since 0.40
595  */
596  EnumArgOptions & operator() (const std::string &, const char, const std::string &);
597  };
598 
599  /**
600  * Constructor.
601  */
602  EnumArg(ArgsGroup * const group, const std::string & long_name,
603  const char short_name, const std::string & description,
604  const EnumArgOptions & opts, const std::string & default_arg);
605 
606  ~EnumArg();
607 
608  /**
609  * Fetch the argument that was given to this option.
610  */
611  const std::string & argument() const
612  {
613  return _argument;
614  }
615 
616  /**
617  * Set the argument returned by argument(), having verified that
618  * it is one of the arguments allowed for this option.
619  */
620  void set_argument(const std::string & arg);
621 
622  /**
623  * Change the default option (should be called before
624  * set_argument()).
625  */
626  void set_default_arg(const std::string & arg);
627 
628  /**
629  * Fetch the default option, as specified to the
630  * constructor or set_default_arg().
631  */
632  const std::string & default_arg() const
633  {
634  return _default_arg;
635  }
636 
637  ///\name Iterate over our allowed arguments and associated descriptions
638  ///\{
639 
640  struct AllowedArgConstIteratorTag;
641  typedef WrappedForwardIterator<AllowedArgConstIteratorTag,
643 
644  AllowedArgConstIterator begin_allowed_args() const;
645 
646  AllowedArgConstIterator end_allowed_args() const;
647 
648  ///\}
649 
650  virtual bool can_be_negated() const;
651 
652  virtual const std::string forwardable_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
653  virtual const std::shared_ptr<Sequence<std::string> > forwardable_args() const PALUDIS_ATTRIBUTE((warn_unused_result));
654  };
655  }
656 
658  extern template class PALUDIS_VISIBLE WrappedForwardIterator<args::StringSetArg::AllowedArgConstIteratorTag,
659  const std::pair<std::string, std::string> >;
661  extern template class PALUDIS_VISIBLE WrappedForwardIterator<args::EnumArg::AllowedArgConstIteratorTag,
662  const args::AllowedEnumArg>;
663 }
664 
665 #endif
Definition: args_option.hh:436
Definition: pimp.hh:51
Definition: about_metadata-fwd.hh:23
const std::string & description() const
Definition: args_option.hh:130
Definition: args_group.hh:50
Definition: visitor-fwd.hh:52
const std::string & argument() const
Definition: args_option.hh:261
const std::string & default_arg() const
Definition: args_option.hh:632
char short_name() const
Definition: args_option.hh:122
virtual void set_specified(const ArgsOptionSpecifiedness value)
Definition: args_option.hh:460
ArgsGroup * group()
Definition: args_option.hh:165
Definition: args_option.hh:544
const std::string & argument() const
Definition: args_option.hh:611
Definition: args_option.hh:494
Definition: args_option.hh:529
Definition: args_option.hh:204
virtual bool specified() const
Definition: args_option.hh:450
Definition: args_option.hh:233
virtual bool specified() const
Definition: args_option.hh:139
const std::string & long_name() const
Definition: args_option.hh:114
Definition: wrapped_forward_iterator-fwd.hh:26
Definition: args_handler.hh:59
ArgsOption * other() const
Definition: args_option.hh:478
Definition: args_option.hh:74
virtual void set_specified(const ArgsOptionSpecifiedness value)
Definition: args_option.hh:157
void set_argument(const int arg)
Definition: args_option.hh:515
virtual bool explicitly_specified() const
Definition: args_option.hh:149
Definition: visitor-fwd.hh:49
Definition: args_option.hh:389
int argument() const
Definition: args_option.hh:510
Definition: args_option.hh:561
#define PALUDIS_ATTRIBUTE(x)
Definition: attributes.hh:53
#define PALUDIS_VISIBLE
Definition: attributes.hh:59
virtual bool explicitly_specified() const
Definition: args_option.hh:455
Definition: args_option.hh:280
NamedValue< n::short_name, char > short_name
Might be &#39;\0&#39;, for none.
Definition: args_option.hh:535