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