BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balcl_commandline.h
Go to the documentation of this file.
1/// @file balcl_commandline.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balcl_commandline.h -*-C++-*-
8#ifndef INCLUDED_BALCL_COMMANDLINE
9#define INCLUDED_BALCL_COMMANDLINE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balcl_commandline balcl_commandline
15/// @brief Provide command line parsing, validation, and access.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balcl
19/// @{
20/// @addtogroup balcl_commandline
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balcl_commandline-purpose"> Purpose</a>
25/// * <a href="#balcl_commandline-classes"> Classes </a>
26/// * <a href="#balcl_commandline-description"> Description </a>
27/// * <a href="#balcl_commandline-component-features-summary"> Component Features Summary </a>
28/// * <a href="#balcl_commandline-background-for-unix-style-command-line-arguments-and-definitions"> Background for Unix-Style Command-Line Arguments and Definitions </a>
29/// * <a href="#balcl_commandline-specifying-option-values"> Specifying Option Values </a>
30/// * <a href="#balcl_commandline-flag-grouping"> Flag Grouping </a>
31/// * <a href="#balcl_commandline-multi-valued-options-and-how-to-specify-them"> Multi-Valued Options and How to Specify Them </a>
32/// * <a href="#balcl_commandline-order-of-arguments"> Order of Arguments </a>
33/// * <a href="#balcl_commandline-setting-options-via-environment-variables"> Setting Options via Environment Variables </a>
34/// * <a href="#balcl_commandline-setting-boolean-options-via-environment-variables"> Setting Boolean Options via Environment Variables </a>
35/// * <a href="#balcl_commandline-setting-array-options-via-environement-variables"> Setting Array Options via Environement Variables </a>
36/// * <a href="#balcl_commandline-best-practices-for-environment-variable-naming"> Best Practices for Environment Variable Naming </a>
37/// * <a href="#balcl_commandline-specifying-options"> Specifying Options </a>
38/// * <a href="#balcl_commandline-balcl-optioninfo-versus-balcl-option"> balcl::OptionInfo versus balcl::Option </a>
39/// * <a href="#balcl_commandline-tag-field"> Tag Field </a>
40/// * <a href="#balcl_commandline-name-field"> Name Field </a>
41/// * <a href="#balcl_commandline-description-field"> Description Field </a>
42/// * <a href="#balcl_commandline-type-and-constraint-field"> Type-and-Constraint Field </a>
43/// * <a href="#balcl_commandline-linked-variables"> Linked Variables </a>
44/// * <a href="#balcl_commandline-occurrence-information-field"> Occurrence Information Field </a>
45/// * <a href="#balcl_commandline-environment-variable-name-field"> Environment Variable Name Field </a>
46/// * <a href="#balcl_commandline-example-field-values"> Example Field Values </a>
47/// * <a href="#balcl_commandline-example-tag-field"> Example: Tag Field </a>
48/// * <a href="#balcl_commandline-example-name-field"> Example: Name Field </a>
49/// * <a href="#balcl_commandline-example-type-and-constraint-field"> Example: Type-and-Constraint Field </a>
50/// * <a href="#balcl_commandline-example-occurrence-information-field"> Example: Occurrence Information Field </a>
51/// * <a href="#balcl_commandline-example-environment-variable-name-field"> Example: Environment Variable Name Field </a>
52/// * <a href="#balcl_commandline-supported-types"> Supported Types </a>
53/// * <a href="#balcl_commandline-supported-constraint-values"> Supported Constraint Values </a>
54/// * <a href="#balcl_commandline-building-new-constraints"> Building New Constraints </a>
55/// * <a href="#balcl_commandline-valid-balcl-optioninfo-specifications"> Valid balcl::OptionInfo Specifications </a>
56/// * <a href="#balcl_commandline-tagnamedescription-fields"> TagNameDescription Fields </a>
57/// * <a href="#balcl_commandline-default-values"> Default Values </a>
58/// * <a href="#balcl_commandline-non-option-arguments"> Non-Option Arguments </a>
59/// * <a href="#balcl_commandline-boolean-options"> Boolean Options (Flags) </a>
60/// * <a href="#balcl_commandline-usage"> Usage </a>
61/// * <a href="#balcl_commandline-example-1-parsing-command-line-options-using-minimal-functionality"> Example 1: Parsing Command Line Options Using Minimal Functionality </a>
62/// * <a href="#balcl_commandline-example-2-accessing-option-values-through-balcl-commandline-accessors"> Example 2: Accessing Option Values Through balcl::CommandLine Accessors </a>
63/// * <a href="#balcl_commandline-example-3-default-values-and-specifying-values-via-the-environment"> Example 3: Default Values and Specifying Values Via The Environment </a>
64/// * <a href="#balcl_commandline-example-4-option-constraints"> Example 4: Option Constraints </a>
65/// * <a href="#balcl_commandline-example-5-using-bsl-optional-for-optional-command-line-parameters"> Example 5: Using bsl::optional for Optional Command Line Parameters </a>
66///
67/// # Purpose {#balcl_commandline-purpose}
68/// Provide command line parsing, validation, and access.
69///
70/// # Classes {#balcl_commandline-classes}
71///
72/// - balcl::CommandLine: value-semantic command-line arguments
73/// - balcl::CommandLineOptionsHandle: references to parsed options
74///
75/// @see balcl_optionvalue, balcl_optiontype
76///
77/// # Description {#balcl_commandline-description}
78/// This component provides a value-semantic class,
79/// `balcl::CommandLine`, used to represent the command-line arguments passed to
80/// a process. Also provided is `balcl::CommandLineOptionsHandle`, an
81/// optionally-used class that provides an alternate means of access to the
82/// options (and associative values, if any) found in a `balcl::CommandLine`
83/// object in a "parsed" state.
84///
85/// The constructor of `balcl::CommandLine` takes a specification describing the
86/// command-line arguments. Once created, `printUsage` can be invoked to print
87/// the usage syntax. The `parse` method takes command-line arguments and
88/// validates them against the specification supplied at construction, printing
89/// suitable messages on an optionally-specified stream in case of a parsing
90/// error. Once parsed, options and values can be accessed using various access
91/// methods. The class provides a set of *theType* access methods (for example,
92/// `theString`, `theInt`) that return the value of the specified option name.
93/// It is also possible to link a variable with an option in the specification;
94/// doing so will cause the variable to be loaded with the option value once
95/// `parse` has been invoked and was successful.
96///
97/// ## Component Features Summary {#balcl_commandline-component-features-summary}
98///
99///
100/// This component offers the following features:
101///
102/// 1. Validation of command-line arguments against the provided specification.
103/// 2. The ability to specify sophisticated constraints easily. Users can also
104/// build their own constraints and use them in the specification.
105/// 3. The ability to automatically generate usage syntax.
106/// 4. The ability to directly link a variable to an option. Parsing a command
107/// line loads such variables with the option value as specified on the
108/// command line (or a default value if one is configured). Linked variables
109/// provide a sometimes convenient alternative to using the accessor methods.
110/// See {Type-and-Constraint Field}. Linked variables can be `bsl::optional`
111/// objects for each of the scalar option types except `bool`.
112/// 5. The ability to access options and their corresponding values through
113/// various accessor methods.
114/// 6. The ability to parse Unix-style command lines (for example, grouping of
115/// flags, allowing any ordering of options, or a mix between options and
116/// non-option arguments, short tag and long tag forms, etc.).
117/// 7. The ability to have multiple non-option arguments of possibly different
118/// types. Note that only the last non-option argument may be multi-valued,
119/// and that if a non-option has a default value, then all subsequent
120/// non-options must also have a default value.
121/// 8. The ability to specify option values through environment variables.
122/// 9. The ability to specify defaults for options, to be used when options are
123/// not specified on the command line or through environment variables.
124///
125/// A lower bound can be placed on the number of multi-valued non-option
126/// arguments (e.g., two or more values) can be achieved by explicitly
127/// specifying the required number of single-valued non-option arguments of the
128/// same type before the unrestricted multi-value non-option of that same type.
129///
130/// ## Background for Unix-Style Command-Line Arguments and Definitions {#balcl_commandline-background-for-unix-style-command-line-arguments-and-definitions}
131///
132///
133/// This section provides background on Unix-style command-line arguments, as
134/// well as definitions of terms used frequently in this documentation (such as
135/// "option", "flag", "non-option", "tag", "short tag", "long tag"). Readers
136/// familiar with Unix command lines can skim this section or omit entirely.
137///
138/// Command-line arguments can be classified as:
139///
140/// * command name (there is only one, and it is always the first argument)
141/// * options (tags and associated values)
142/// * flags (boolean options)
143/// * non-option arguments
144///
145/// For example, in the following command line:
146/// @code
147/// $ mybuildcommand -e -c CC64 myproject
148/// @endcode
149/// the command name is `mybuildcommand`. There is one option, described by
150/// `-c CC64`: `c` is the tag name, and `CC64` is the option value. There is
151/// also one boolean option (flag): `-e` is a flag, `e` is the flag name. The
152/// last parameter, `myproject`, is a non-option argument.
153///
154/// Sometimes *option* is also used where "flag" or "non-option" would be more
155/// accurate. What is actually intended should be clear from context.
156///
157/// A user specifies an option on a command line by entering one of the tag
158/// values configured for that option. Each option has a mandatory long tag and
159/// an optional short tag. The short tag, if specified, must be a single
160/// character; the long tag generally must follow the same rules applicable to
161/// C/C++ identifiers, except that `-` is allowed (but not as the leading
162/// character). When a short tag is used on a command line, it must be preceded
163/// by `-`, and when a long tag is used it must be preceded by `--`. Flags have
164/// no corresponding values; they are either present or absent. Option tags
165/// *must* be followed by a corresponding option value. An option can have
166/// multiple values (such options are called multi-valued options). When
167/// multiple values are provided for an option, the tag must appear with each
168/// value (see the section {Multi-Valued Options and How to Specify Them}).
169/// Arguments that are not the command name, options, or flags are called
170/// "non-option" arguments and can be either single-valued or multi-valued.
171/// They do not have any tag associated with them.
172///
173/// Consider the syntax of a typical Unix-style command whose options are
174/// described by the usage string:
175/// @code
176/// usage: mysort [-r|reverse] [-o|outputfile <outfile>] files...
177/// @endcode
178/// Here:
179/// @code
180/// '-r|reverse' is a flag: 'r' is the short tag, 'reverse' is the long tag.
181///
182/// '-o|outputfile' is an option: 'o' is the short tag, 'outputfile' is the
183/// long tag. The value is parsed from the string 'outfile'.
184///
185/// 'files...' describes the multi-valued non-option argument.
186/// @endcode
187/// The command can be invoked as follows:
188/// @code
189/// $ mysort -r -o myoutfile file1 file2 file3
190/// @endcode
191/// and an equivalent command line is:
192/// @code
193/// $ mysort --reverse --outputfile myoutfile file1 file2 file3
194/// @endcode
195/// Note that short tags must be prepended with `-` and long tags with `--`. To
196/// specify a non-option argument beginning with `-`, use a single `--`
197/// separator (not followed by a long tag).
198///
199/// ## Specifying Option Values {#balcl_commandline-specifying-option-values}
200///
201///
202/// This component supports a variety of forms for specifying option values.
203/// They are best described by example. Consider the command-line specification
204/// described by the following usage string:
205/// @code
206/// usage: myserver [-p|port <portNumber>]
207/// @endcode
208/// The following (valid) forms can be used with equivalent meaning:
209/// @code
210/// $ myserver -p 13
211/// $ myserver -p=13 # option value is '13' and *not* '=13'
212/// $ myserver -p13
213/// $ myserver --port 13
214/// $ myserver --port=13
215/// @endcode
216/// Note that if `=13` is desired as an option value, then whitespace must be
217/// used as in:
218/// @code
219/// $ myserver -p =13 # option value *is* '=13'
220/// @endcode
221/// All of the following are invalid:
222/// @code
223/// $ myserver -port13
224/// $ myserver --p 13
225/// $ myserver -port 13
226/// @endcode
227///
228/// ## Flag Grouping {#balcl_commandline-flag-grouping}
229///
230///
231/// Flags can be grouped (i.e., expressed more succinctly like `-ctv` instead of
232/// `-c -t -v`). While grouping flags, short tags must be used. For example,
233/// given the command-line specification described by the following usage
234/// string:
235/// @code
236/// usage: mysort [-r|reverse] [-i|insensitiveToCase] [-u|uniq]
237/// @endcode
238/// the following command lines are valid and equivalent:
239/// @code
240/// $ mysort -r -i -u
241/// $ cmd -riu
242/// $ cmd -uir
243/// $ cmd -i -ru
244/// @endcode
245/// Note that the last character in a group need not be a flag; it could be an
246/// option. Any character that is the short tag of an option signals the end of
247/// the flag group, and it must be followed by the value of the option. For
248/// example, given the command-line specification described by the following
249/// usage string:
250/// @code
251/// usage: mysort [-r|reverse] [-i|insensitiveToCase] [-u|uniq]
252/// [-o|outfile <outputfile>]
253/// @endcode
254/// the following command lines are valid and equivalent:
255/// @code
256/// $ mysort -riu -o myoutfile
257/// $ mysort -riuo myoutfile
258/// $ mysort -riuomyoutfile
259/// $ mysort -riuo=myoutfile
260/// @endcode
261///
262/// ## Multi-Valued Options and How to Specify Them {#balcl_commandline-multi-valued-options-and-how-to-specify-them}
263///
264///
265/// Options can have several values. For example, in the command-line
266/// specification described by the following usage string, `*` denotes a
267/// multi-valued option, and `+` denotes a multivalued option that must occur at
268/// least once.
269/// @code
270/// usage: mycompiler [-l|library <libName>]* [-o|out outFile] [<object>]+
271/// @endcode
272/// multiple values can be given as follows:
273/// @code
274/// $ mycompiler -l lib1 -l lib2 -l lib3 -o main a.o b.o
275/// @endcode
276/// They need not be supplied contiguously. For example, the following command
277/// line is valid and equivalent to the above:
278/// @code
279/// $ mycompiler -l lib1 -o main -l lib2 -l lib3 a.o b.o
280/// @endcode
281/// Note that the tag needs to be repeated for every option value. For example,
282/// the following command line is invalid (because `-l` must be repeated before
283/// both `lib2` and `lib3`):
284/// @code
285/// $ mycompiler -l lib1 lib2 lib3 -o main a.o b.o
286/// @endcode
287/// Short and long forms can be used in mixed fashion, however:
288/// @code
289/// $ mycompiler -l lib1 -o main --library lib2 -l lib3 a.o b.o
290/// @endcode
291///
292/// ## Order of Arguments {#balcl_commandline-order-of-arguments}
293///
294///
295/// Command-line arguments can appear in any order. For example, given the
296/// command-line specification described by the following usage string:
297/// @code
298/// usage: mysort [-r|reverse] [-o|outputfile <outfile>] [<file>]+
299/// @endcode
300/// all the following command lines are valid (and equivalent):
301/// @code
302/// $ mysort -r -o myoutfile file1 file2 file3
303/// $ mysort file1 file2 file3 -r -o myoutfile
304/// $ mysort file1 -o myoutfile file2 -r file3
305/// $ mysort file1 -o=myoutfile file2 -r file3
306/// @endcode
307/// There are three exceptions to the above rule on argument order:
308///
309/// 1. An option tag must be followed by that option's value, if any (either in
310/// the next argument, or in the same argument using "=value").
311/// 2. When a non-option argument starts with a `-` then it must not appear
312/// before any option or flag *and* a `--` must be put on the command line to
313/// indicate the end of all options and flags.
314/// 3. Non-option arguments are parsed and assigned in the order they appear on
315/// the command line.
316///
317/// For example, the following is invalid because of rule (1) above (because
318/// `-o` should be followed by `myoutfile`):
319/// @code
320/// $ mysort -o -r myoutfile file1 file2 file3
321/// @endcode
322/// and the following is incorrect because of rule (2) (because
323/// `-weirdfilename`, which starts with `-`, must appear after `--`):
324/// @code
325/// $ mysort -weirdfilename file2 file3 -r -o myoutfile
326/// @endcode
327/// The previous examples can be corrected in either of the following ways:
328/// @code
329/// $ mysort -r -o myoutfile -- -weirdfilename file2 file3
330/// $ mysort file2 file3 -r -o myoutfile -- -weirdfilename
331/// @endcode
332/// Note that the order of values within the sequence of multi-valued non-option
333/// arguments differs in both examples, as per rule (3). In the first example,
334/// the non-option arguments have for a value the (ordered) sequence:
335/// @code
336/// -weirdfilename file2 file3
337/// @endcode
338/// while in the second example, the non-option argument value is the sequence:
339/// @code
340/// file2 file3 -weirdfilename
341/// @endcode
342/// This order may or may not matter to the application.
343///
344/// ## Setting Options via Environment Variables {#balcl_commandline-setting-options-via-environment-variables}
345///
346///
347/// Sometimes users may wish to supply configuration via environment variables,
348/// which is common practice, for example, for services deployed via Docker
349/// containers in cloud environments.
350///
351/// By default, parsed command line option values are unaffected by the
352/// environment. If an environment variable name is specified for an option,
353/// then, during parsing, if an option is not set on the command line, and the
354/// specified environment variable has a value, that value is used for the
355/// command line option. If a value is not supplied, either via the command
356/// line, or via an environment variable, then the default value for the option,
357/// if any, is used.
358///
359/// ### Setting Boolean Options via Environment Variables {#balcl_commandline-setting-boolean-options-via-environment-variables}
360///
361///
362/// Boolean options when set via the environment variable must be associated
363/// with a string.
364/// @code
365/// +---------------+--------------+
366/// | desired value | valid text |
367/// +---------------+--------------+
368/// | true | "true", "1" |
369/// | false | "false", "0" |
370/// +---------------+--------------+
371/// @endcode
372/// Any other text, including an empty string, is treated as invalid input.
373///
374/// ### Setting Array Options via Environement Variables {#balcl_commandline-setting-array-options-via-environement-variables}
375///
376///
377/// Array options can be set by environment variable. When an array option is
378/// supplied via an environment variable string, the discrete values must be
379/// separated using the space character. For example, if the program takes an
380/// integer array of years as an option, and that option is associated with the
381/// environment variable name "MYPROG_YEARS", to supply a value via the command
382/// line one could specify:
383/// @code
384/// $ export MYPROG_YEARS="2010 2014 2018 2022"
385/// @endcode
386/// The '\' is used as an escape-character if an element of an array contains a
387/// space. For example:
388/// @code
389/// $ export MYPROG_WINPATH='C:\\Program\ Files\\MyProg D:\\Another\\Path'
390/// @endcode
391/// would configure an array containing "C:\Program Files\MyProg" and
392/// "D:\Another\Path".
393///
394/// ### Best Practices for Environment Variable Naming {#balcl_commandline-best-practices-for-environment-variable-naming}
395///
396///
397/// Environment variable exist in a single namespace accessed by all programs
398/// run in the shell, and many environment variable names are used by many
399/// different systems for different purposes. For that reason, we strongly
400/// encourage selecting a (ideally) unique prefix for the environment variables
401/// used by your application, to reduce the likelihood of collisions with
402/// environment variables used by other applications for different purposes.
403///
404/// For example, if someone were writing a trading application `tradesvc`, they
405/// might choose to use "TRADESVC_" as a common prefix for the environment
406/// variables.
407///
408/// ## Specifying Options {#balcl_commandline-specifying-options}
409///
410///
411/// A command line is described by an *option* *table* (supplied as an array of
412/// `balcl::OptionInfo`). Each entry (row) of the table describes an option
413/// (i.e., an option, flag, or non-option argument). Each entry has several
414/// fields, specified in the following order:
415/// @code
416/// Field name Main purpose (see below for more details)
417/// ============================ ===========================================
418/// tag field Specify tags (short and long) for options
419/// and flags. A non-option argument is
420/// indicated by an empty string.
421///
422/// name field Specify the name through which the option
423/// value can be accessed.
424///
425/// description field Used in printing usage.
426///
427/// type-and-constraint field (1) Specify the type of the option value(s).
428/// (2) Specify a variable to be linked to the
429/// option.
430/// (3) Specify other constraints on individual
431/// value(s).
432///
433/// occurrence information field (1) Specify a default value for an option.
434/// (2) Specify whether an option is required on
435/// the command line or is optional (by
436/// default, an option is optional).
437///
438/// environment variable name Specify an environment variable name that
439/// can be used to set the option.
440/// @endcode
441/// The first three fields *must* be specified. The type-and-constraint field
442/// can be omitted (meaning no constraint), and the occurrence information field
443/// likewise can be omitted (meaning that the option is not required on the
444/// command line).
445///
446/// The following sections provide a more detailed description of each field,
447/// including example values for each field.
448///
449/// ### balcl::OptionInfo versus balcl::Option {#balcl_commandline-balcl-optioninfo-versus-balcl-option}
450///
451///
452/// In some applications, command-line specifications *must* *be* defined using
453/// a statically-initialized array. For that reason, there are two classes that
454/// serve the same purpose: `balcl::OptionInfo` is a statically-initializable
455/// class but it does not conform to the `bslma` allocator protocol, while
456/// `balcl::Option` is convertible from `balcl::OptionInfo`, takes allocators,
457/// and is suitable for storing into containers.
458///
459/// ### Tag Field {#balcl_commandline-tag-field}
460///
461///
462/// The tag field specifies the (optional) short tag and long tag for the
463/// corresponding option or flag, except that non-option arguments are indicated
464/// by an empty string for a tag field. There can only be one multi-valued
465/// entry for non-option arguments, and it must be listed last among the
466/// non-options.
467///
468/// The general format is either:
469/// 1. "" (empty string) for non-option arguments;
470/// 2. "<s>|<long>" for options and flags, where `<s>` is the short tag, and
471/// `<long>` is the long tag; or
472/// 3. "<long>" for options and flags where a short tag is not specified.
473///
474/// Note that for short tags (`<s>`), `s` must be a single character (different
475/// from `-` and `|`); for long tags ("<long>"), `long` must have 2 or more
476/// characters (which may contain `-`, but not as the first character, and
477/// cannot contain `|`). Also note that either no tag (empty string), both
478/// short and long tags, or only a long tag, may be specified.
479///
480/// The tag field cannot be omitted, but it can be the empty string.
481///
482/// ### Name Field {#balcl_commandline-name-field}
483///
484///
485/// The name field specifies the name through which the option value can be
486/// accessed either through one of the *theType* methods.
487///
488/// The general format is any non-empty string. In most cases, the name will be
489/// used as-is. Note that any suffix starting at the first occurrence of `=`,
490/// if any, is removed from the name before storing in the `balcl::Option`.
491/// Thus, if a name having such a suffix is specified in a `balcl::OptionInfo`
492/// (e.g., "nameOption=someAttribute"), the correct name to use for querying
493/// this option by name does not include the suffix (e.g.,
494/// `cmdLine.numSpecified("nameOption=someAttribute")` will always return 0, but
495/// `cmdLine.numSpecified("nameOption")` will return the appropriate value).
496///
497/// This field cannot be omitted, and it cannot be an empty string.
498///
499/// ### Description Field {#balcl_commandline-description-field}
500///
501///
502/// The description field is used when printing the usage string.
503///
504/// The general format is any non-empty string.
505///
506/// This field cannot be omitted, and it cannot be an empty string.
507///
508/// ### Type-and-Constraint Field {#balcl_commandline-type-and-constraint-field}
509///
510///
511/// The type-and-constraint field specifies the type and constraints for the
512/// option values. Flags are identified by having the boolean type; note that
513/// flags cannot have constraints. Multiple values (for multi-valued options
514/// and multi-valued non-option arguments) can be specified by using array
515/// types. The list of the supported types is provided in the section
516/// @ref balcl_commandline-supported-types below.
517///
518/// Other constraints can be placed on individual value(s). When the type is an
519/// array type, then those constraints are placed on the individual value(s)
520/// held in the array and not on the entire array. A list of useful constraints
521/// is provided in the section @ref balcl_commandline-supported-constraint-values . Also see the
522/// section @ref balcl_commandline-building-new-constraints to see how new constraints can be built
523/// so that they can be used in the same manner as the available constraints.
524///
525/// Additionally, this field allows a specified variable to be linked to the
526/// option. In that case, after parsing, the variable is loaded with the option
527/// value specified on the command line (or its default value, if any, if the
528/// option is absent from the command line). @ref balcl_commandline-occurrence-information-field
529/// describes how to configure a default value.
530///
531/// The general format can be one of either:
532/// @code
533/// /// Link the option with the specified `variable`. Note that the option
534/// /// type is inferred from the type of `variable`. Optionally place the
535/// /// user-specified `constraint`, of a type defined in
536/// /// `balcl::Constraint`, on the value.
537/// balcl::TypeInfo(&variable)
538/// balcl::TypeInfo(&variable, constraint)
539///
540/// /// Specify the type of this option to be of the specified `type`.
541/// /// Optionally place the user-specified `constraint`, of a type defined
542/// /// in `balcl::Constraint`, on the value. Don't link this
543/// /// option with any variable. `type` must be one of the static
544/// /// variables (null pointers) listed in @ref balcl_optiontype-enumerators .
545/// balcl::TypeInfo(type)
546/// balcl::TypeInfo(type, constraint)
547/// @endcode
548/// This field can be omitted. If so, the type is assumed to be of string type
549/// with no constraints and no variable is linked to the option. No occurrence
550/// information field can then be specified; if such a field is desired, then
551/// the type-and-constraint field needs to be set explicitly.
552///
553/// #### Linked Variables {#balcl_commandline-linked-variables}
554///
555///
556/// Linked variables are updated by the `parse` method of `balcl::CommandLine`
557/// should that method determine a value for an option; otherwise, the linked
558/// variable is left unchanged. The value for an option is determined either
559/// from the command-line arguments passed to `parse` or obtained from a
560/// pre-configured default value, if any (see
561/// @ref balcl_commandline-occurrence-information-field .
562///
563/// Linked variables can be `bsl::optional` objects that wrap any of the
564/// non-array option types except for `bool` (see @ref balcl_commandline-supported-types . Also,
565/// a link to a `bsl::optional` object is disallowed if the option is "required"
566/// or has a default value (see @ref balcl_commandline-occurrence-information-field .
567///
568/// ### Occurrence Information Field {#balcl_commandline-occurrence-information-field}
569///
570///
571/// The occurrence information field is used to specify a default value for an
572/// option, and whether an option is required on the command line or is
573/// optional. An option may also be "hidden" (i.e., not displayed by
574/// `printUsage`).
575///
576/// The general format of this field is one of the following:
577/// @code
578/// balcl::OccurrenceInfo::e_HIDDEN
579/// balcl::OccurrenceInfo::e_OPTIONAL
580/// balcl::OccurrenceInfo::e_REQUIRED
581/// a default value
582/// @endcode
583/// If a default value is specified, the option is assumed to be optional; in
584/// addition, the default value must satisfy the type and constraint indicated
585/// by the specified type-and-constraint field.
586///
587/// This field can be omitted, and is always omitted if the type-and-constraint
588/// field is not specified. If omitted, the option is not required on the
589/// command line and has no default value; furthermore, if the option is not
590/// present on the command line, the linked variable, if any, is unaffected.
591///
592/// ### Environment Variable Name Field {#balcl_commandline-environment-variable-name-field}
593///
594///
595/// The environment variable name field is used to specify a string which is the
596/// name of an environment variable which, if set, allows the environment to be
597/// searched for a value of the option. If an option is specified on the
598/// command line, the environment is never searched for that option. If an
599/// option has a default value, and a value is specified in the environment, the
600/// value in the environment takes precedence over the default value.
601///
602/// ## Example Field Values {#balcl_commandline-example-field-values}
603///
604///
605/// The following tables give examples of field values.
606///
607/// ### Example: Tag Field {#balcl_commandline-example-tag-field}
608///
609///
610/// The tag field may be declared using the following forms:
611/// @code
612/// Usage Meaning
613/// ============== =======================================================
614/// "o|outputfile" The option being defined is either an option or a flag.
615/// The short tag is "o" and the long tag is "outputfile".
616///
617/// Note that "o" alone is invalid since a long tag must be
618/// specified.
619///
620/// "outputfile" The option being defined is either an option or a flag.
621/// There is no short tag and the long tag is "outputfile".
622///
623/// "" Specifies a non-option argument.
624/// @endcode
625///
626/// ### Example: Name Field {#balcl_commandline-example-name-field}
627///
628///
629/// The name field may be declared using the following form:
630/// @code
631/// Usage Meaning
632/// =============== =======================================================
633/// "xyz" The option value can be accessed by "xyz".
634/// @endcode
635///
636/// ### Example: Type-and-Constraint Field {#balcl_commandline-example-type-and-constraint-field}
637///
638///
639/// Suppose, for example, that our application has the following parameters:
640/// @code
641/// int portNum; // a variable to be linked to an
642/// // option
643///
644/// bool isVerbose; // a variable to be linked to a flag
645///
646/// bsl::vector<bsl::string> fileNames; // a variable to be linked to a
647/// // multi-valued option
648/// @endcode
649/// The type and constraint fields may be declared using the following values:
650/// @code
651/// Usage Meaning
652/// =============== =======================================================
653/// balcl::TypeInfo(&portNum)
654/// (1) Link the variable 'portNum' with this option value.
655/// That is, after successful parsing, this variable will
656/// contain the option value specified on the command line.
657/// (2) An integer value must be provided on the command
658/// line for this option (the type 'int' is inferred
659/// implicitly from the type of 'portNum').
660///
661/// balcl::TypeInfo(balcl::OptionType::k_INT)
662/// This option value must be an integer. Since there is no
663/// linked variable, the value of the option must be obtained
664/// using the field name passed to the 'the<TYPE>' accessor
665/// (in this case 'theInt').
666///
667/// balcl::TypeInfo(&isVerbose)
668/// Load the variable 'isVerbose' with this option value.
669///
670/// balcl::TypeInfo(balcl::OptionType::k_BOOL)
671/// This option is a flag.
672///
673/// balcl::TypeInfo(&fileNames)
674/// Load the variable 'fileNames' with the values specified
675/// for this multi-valued option (or multi-valued
676/// non-option argument). That is, after successful parsing,
677/// this variable will contain the sequence of values
678/// specified on the command line, in the same order.
679///
680/// balcl::TypeInfo(balcl::OptionType::k_STRING_ARRAY)
681/// This option value consists of a sequence of string
682/// values specified on the command line, in the same order.
683/// @endcode
684///
685/// ### Example: Occurrence Information Field {#balcl_commandline-example-occurrence-information-field}
686///
687///
688/// The following values may be used for this field:
689/// @code
690/// Usage Meaning
691/// =============== ========================================================
692/// balcl::OccurrenceInfo::e_REQUIRED
693/// The value(s) for this option *must* be provided on the
694/// command line. For options that are of an array type, at
695/// least one value must be provided. Omission manifests
696/// as a parse error.
697///
698/// balcl::OccurrenceInfo::e_OPTIONAL
699/// Value(s) for this option may be omitted on the command
700/// line.
701///
702/// balcl::OccurrenceInfo::e_HIDDEN
703/// Same as 'e_OPTIONAL'; in addition, this option will not
704/// be displayed by 'printUsage'.
705///
706/// 13 The default value for this option is 13 and the option
707/// is not required on the command line. If no value is
708/// provided, then 13 is used. If the type described by the
709/// type-and-constraint field is not integer, then it is an
710/// error.
711/// @endcode
712/// *Note*: If an option is optional *and* no value is provided on the command
713/// line or through an environment variable, `isSpecified` will will return
714/// `false and `numSpecified' will return 0. If no default value is provided
715/// and if the variable is a linked variable, it will be unmodified by the
716/// parsing. If the variable is accessed through
717/// `CommandLineOptionsHandle::value`, it will be in a null state (defined type
718/// but *no* defined value).
719///
720/// ### Example: Environment Variable Name Field {#balcl_commandline-example-environment-variable-name-field}
721///
722///
723/// The name field may be declared using the following form:
724/// @code
725/// Usage Meaning
726/// =============== =======================================================
727/// "MYPROG_XYZ" The option can be set by "export MYPROG_XYZ=<value>"
728/// @endcode
729///
730/// ## Supported Types {#balcl_commandline-supported-types}
731///
732///
733/// The following types are supported. The type is specified by an enumeration
734/// value (see @ref balcl_optiontype ) supplied as the first argument to:
735/// @code
736/// balcl::TypeInfo(type, constraint)
737/// @endcode
738/// which is used to create the type-and-constraint field value in the
739/// command-line specification. When the constraint need only specify the type
740/// of the option value (i.e., no linked variable or programmatic constraint),
741/// one can supply any of the public data members of `balcl::OptionType` shown
742/// below:
743/// @code
744/// Type Specifier
745/// ----------------------------- -------------------------
746/// bool OptionType::k_BOOL
747/// char OptionType::k_CHAR
748/// int OptionType::k_INT
749/// bsls::Types::Int64 OptionType::k_INT64
750/// double OptionType::k_DOUBLE
751/// bsl::string OptionType::k_STRING
752/// bdlt::Datetime OptionType::k_DATETIME
753/// bdlt::Date OptionType::k_DATE
754/// bdlt::Time OptionType::k_TIME
755/// bsl::vector<char> OptionType::k_CHAR_ARRAY
756/// bsl::vector<int> OptionType::k_INT_ARRAY
757/// bsl::vector<bsls::Types::Int64> OptionType::k_INT64_ARRAY
758/// bsl::vector<double> OptionType::k_DOUBLE_ARRAY
759/// bsl::vector<bsl::string> OptionType::k_STRING_ARRAY
760/// bsl::vector<bdlt::Datetime> OptionType::k_DATETIME_ARRAY
761/// bsl::vector<bdlt::Date> OptionType::k_DATE_ARRAY
762/// bsl::vector<bdlt::Time> OptionType::k_TIME_ARRAY
763/// @endcode
764/// The ASCII representation of these values (i.e., the actual format of the
765/// values on command lines) depends on the type:
766/// * Numeric Values: see @ref bdlb_numericparseutil .
767/// * Date/Time Values: see @ref bdlt_iso8601util .
768///
769/// ## Supported Constraint Values {#balcl_commandline-supported-constraint-values}
770///
771///
772/// This component supports constraint values for each supported type except
773/// `bool`. Specifically, the utility `struct` `balcl::Constraint` defines
774/// `TYPEConstraint` types (for instance, `StringConstraint`, `IntConstraint`)
775/// that can be used to define a constraint suitable for the `balcl::TypeInfo`
776/// class.
777///
778/// ## Building New Constraints {#balcl_commandline-building-new-constraints}
779///
780///
781/// A constraint is simply a function object that takes as its first argument
782/// the (address of the) data to be constrained and as its second argument the
783/// stream that should be written to with an appropriate error message when the
784/// data does not follow the constraint. The functor should return a `bool`
785/// value indicating whether or not the data abides by the constraint (with
786/// `true` indicating success). A constraint for a given option whose value has
787/// the given type must be convertible to one of the `TYPEConstraint` types
788/// defined in the utility `struct` `balcl::Constraint`. Note that when passing
789/// a function as a constraint, the *address* of the function must be passed.
790///
791/// ## Valid balcl::OptionInfo Specifications {#balcl_commandline-valid-balcl-optioninfo-specifications}
792///
793///
794/// The `balcl::CommandLine` class has a complex set of preconditions on the
795/// option specification table (array of `balcl::OptionInfo` objects) passed to
796/// each of its constructors. There are requirements on individual elements, on
797/// elements relative to each other, and on the entire set of elements. If
798/// these preconditions are not met, the behavior of the constructor is
799/// undefined.
800///
801/// The preconditions (some previously mentioned) are given in their entirety
802/// below. Moreover, an overloaded class method,
803/// `balcl::CommandLine::isValidOptionSpecification`, is provided to allow
804/// programmatic checking without risk of incurring undefined behavior.
805///
806/// ### TagNameDescription Fields {#balcl_commandline-tagnamedescription-fields}
807///
808///
809/// The tag, name, and description fields must pass the `isTagValid`,
810/// `isNameValid, and `isDescriptionValid' methods of `balcl::Option`,
811/// respectively.
812///
813/// * The tag field:
814/// - If empty (a non-option argument), the option must not be a flag.
815/// - If non-empty, see {Tag Field} above for details.
816/// * The name field must be non-empty.
817/// * The description field must be non-empty.
818///
819/// Collectively, each non-empty short tag, each long tag, and each name must be
820/// unique in the specification.
821///
822/// ### Default Values {#balcl_commandline-default-values}
823///
824///
825/// * Default values are disallowed for flags.
826/// * The type of a default value must match the type of its option.
827/// * The default value must satisfy the user-defined constraint on the option
828/// value, if any.
829///
830/// ### Non-Option Arguments {#balcl_commandline-non-option-arguments}
831///
832///
833/// * Cannot be a flag (see {Tag/Name/Description Fields}).
834/// * Cannot be a hidden option.
835/// * Only the last non-option argument can be multi-valued (i.e., an array
836/// type).
837/// * If a non-option argument has a default value, all subsequent non-option
838/// arguments must also have default values.
839///
840/// ### Boolean Options (Flags) {#balcl_commandline-boolean-options}
841///
842///
843/// Options having the `bool` type (also known as "flags") are distinguished
844/// from the other supported option types in several ways:
845///
846/// * The command-line syntax does not allow an explicit value for flag types
847/// (e.g., `-x=true` and `-xFlag false` are disallowed when setting booleans
848/// on the command line). The presence or absence of the tag name (either
849/// long or short form) on the command line determines the value of the
850/// option.
851/// * If providing a boolean option through an environment variable, an
852/// explicit value is required, and that value must be either "true", "1",
853/// "false", or "0" -- any other value, including the empty string, is
854/// invalid (see {Setting Boolean Options via Environment Variables}).
855/// * The boolean option type has no "array" form (i.e., there is no
856/// `BoolArray` option type).
857/// - Multiple instances of the tag for a boolean option are allowed on the
858/// command line (e.g., `-x -x -x`). For other option types, specifying
859/// multiple tags for a non-array option is an error.
860/// - Multiple instances of a boolean tag idempotently set the flag to
861/// `true`; however, one can determine the number of appearances by using
862/// the `position` accessor.
863/// * A boolean option type cannot be configured to:
864/// - have a default value, or
865/// - have a constraint, or
866/// - be linked to a `bsl::optional<bool>` variable.
867/// * A boolean option type *can* be configured to be a required parameter;
868/// however, that combination defeats the purpose of having a flag option so
869/// the requirement that the flag appear on the command line is *not*
870/// enforced.
871/// * The `theBool` method returns the same value (`true` or `false`) as the
872/// `isSpecified` method. In contrast, the `the*` accessor methods for the
873/// other option types have a precondition such that either `isSpecified()`
874/// must be `true` or the option must have a default value.
875///
876/// ## Usage {#balcl_commandline-usage}
877///
878///
879/// This section illustrates intended use of this component.
880///
881/// ### Example 1: Parsing Command Line Options Using Minimal Functionality {#balcl_commandline-example-1-parsing-command-line-options-using-minimal-functionality}
882///
883///
884/// Suppose we want to design a sorting utility named `mysort` that has the
885/// following syntax:
886/// @code
887/// Usage: mysort [-r|reverse] [-f|field-separator <fieldSeparator>]
888/// -o|outputfile <outputFile> [<fileList>]+
889/// // Sort the specified files (in 'fileList'), and
890/// // write the output to the specified output file.
891/// @endcode
892/// The `<fileList>` argument is a `non-option`, meaning that its value or
893/// values appear on the command line unannounced by tags. In this case, the
894/// `+` following the argument means that it is an array type of argument where
895/// at least one element is required, so its values are stored in a
896/// `bsl::vector`.
897/// @code
898/// int main(int argc, const char **argv)
899/// {
900/// using balcl::TypeInfo;
901/// using balcl::OccurrenceInfo;
902/// @endcode
903/// First, we define our variables to be initialized from the command line. All
904/// values must be initialized to their default state:
905/// @code
906/// bool reverse = false;
907/// bsl::string outputFile;
908/// char fieldSeparator = '|';
909/// bsl::vector<bsl::string> files;
910/// @endcode
911/// Then, we define our `OptionInfo` table of attributes to be set. The fields
912/// of the `OptionInfo` are:
913///
914/// * tag - the tag on the command line for supplying the option
915/// * name - a one word description of the value to provide for the option
916/// * description - a short body of text describing the purpose of the option
917/// etc.
918/// * TypeInfo - information about the type of the input expected (possibly the
919/// variable in which to load the value)
920/// * OccurenceInfo - (optional) whether the option is required, optional, or
921/// hidden (where hidden means hidden from the help text)
922/// * environment variable name - (optional) the name of an environment
923/// variable to use for the option if the option is not provided on the
924/// command line
925/// @code
926/// static const balcl::OptionInfo specTable[] = {
927/// {
928/// "r|reverse", // tag
929/// "isReverse", // name
930/// "sort in reverse order", // description
931/// TypeInfo(&reverse), // link
932/// OccurrenceInfo(), // occurrence
933/// "" // env var name
934/// },
935/// {
936/// "f|field-separator", // tag
937/// "fieldSeparator", // name
938/// "field separator character", // description
939/// TypeInfo(&fieldSeparator), // link
940/// OccurrenceInfo(), // occurrence
941/// "" // env var name
942/// },
943/// {
944/// "o|outputfile", // tag
945/// "outputFile", // name
946/// "output file", // description
947/// TypeInfo(&outputFile), // link
948/// OccurrenceInfo::e_REQUIRED, // occurrence info
949/// // (not optional)
950/// "" // env var name
951/// },
952/// {
953/// "", // non-option
954/// "fileList", // name
955/// "input files to be sorted", // description
956/// TypeInfo(&files), // link
957/// OccurrenceInfo::e_REQUIRED, // occurrence info
958/// // (at least one
959/// // file required)
960/// "" // env var name
961/// }
962/// };
963/// @endcode
964/// Now, we create a balcl command-line object, supplying it with the spec table
965/// that we have just defined:
966/// @code
967/// balcl::CommandLine cmdLine(specTable);
968/// @endcode
969/// Parse the options and if an error occurred, print a usage message describing
970/// the options:
971/// @code
972/// if (cmdLine.parse(argc, argv)) {
973/// cmdLine.printUsage();
974/// return -1; // RETURN
975/// }
976/// @endcode
977/// If there are no errors in the specification table and correct arguments are
978/// passed, `parse` will set any variables that were specified on the command
979/// line, return 0 and there will be no output.
980///
981/// Finally, we show what will happen if `mysort` is called with invalid
982/// arguments. We will call without specifying an input file to `fileList`,
983/// which will be an error. `parse` streams a message describing the error and
984/// then returns non-zero, so our program will call `cmdLine.printUsage`, which
985/// prints a detailed usage message.
986/// @code
987/// $ mysort -r -o sorted.txt
988/// Error: No value supplied for the non-option argument "fileList".
989///
990/// Usage: mysort [-r|reverse] [-f|field-separator <fieldSeparator>]
991/// -o|outputfile <outputFile> [<fileList>]+
992/// Where:
993/// -r | --reverse
994/// sort in reverse order
995/// -f | --field-separator <fieldSeparator>
996/// field separator character
997/// -o | --outputfile <outputFile>
998/// output file
999/// <fileList>
1000/// input files to be sorted
1001/// @endcode
1002///
1003/// ### Example 2: Accessing Option Values Through balcl::CommandLine Accessors {#balcl_commandline-example-2-accessing-option-values-through-balcl-commandline-accessors}
1004///
1005///
1006/// Imagine we defined the same `mysort` program with the same options. After a
1007/// successful `parse`, `balcl::Commandline` makes the state of every option
1008/// available through accessors (in addition to setting external variables as
1009/// shown in example 1).
1010///
1011/// For every type that is supported, there is a `the<TYPE>` accessor which
1012/// takes a single argument, the name of the argument. In the above program, if
1013/// parsing was successful, the following asserts will always pass:
1014/// @code
1015/// assert(cmdLine.theBool("isReverse") == reverse);
1016/// assert(cmdLine.theString("outputFile") == outputFile);
1017/// assert(cmdLine.theStringArray("fileList") == files);
1018/// @endcode
1019/// The next accessors we'll discuss are `isSpecified` and `numSpecified`.
1020/// Here, we use `isSpecified` to determine whether "fieldSeparator" was
1021/// specified on the command line, and we use `numSpecified` to determine the
1022/// number of times the "fieldSeparator" option appeared on the command line:
1023/// @code
1024/// if (cmdLine.isSpecified("fieldSeparator")) {
1025/// const unsigned char uc = cmdLine.theChar("fieldSeparator");
1026/// if (!::isprint(uc)) {
1027/// bsl::cerr << "'fieldSeparator' must be printable.\n";
1028///
1029/// return -1; // RETURN
1030/// }
1031/// }
1032///
1033/// if (1 < cmdLine.numSpecified("fieldSeparator")) {
1034/// bsl::cerr <<
1035/// "'fieldSeparator' may not be specified more than once.\n";
1036///
1037/// return -1; // RETURN
1038/// }
1039/// @endcode
1040///
1041/// ### Example 3: Default Values and Specifying Values Via The Environment {#balcl_commandline-example-3-default-values-and-specifying-values-via-the-environment}
1042///
1043///
1044/// Suppose we are implementing `mysort` (from examples 1 & 2) again, but here
1045/// we want to make use of default option values and the ability to supply
1046/// options via the environment.
1047///
1048/// In this example, we have decided not to link local variables, and instead
1049/// access the option values via the `balcl::CommandLine` object. Since we are
1050/// not linking local variables, we specify `OptionType::k_<TYPE>` in the
1051/// specification table below for each `TypeInfo` field.
1052///
1053/// To specify default values, we pass the default value to the `OccurrenceInfo`
1054/// field. Boolean options always have a default value of `false`.
1055///
1056/// We also choose to allow these options to be supplied through the
1057/// environment. To enable this, we specify an environment variable name as the
1058/// 5th (optional) element of the `OptionInfo` specification for the option. If
1059/// no name is supplied for the environment variable, the option cannot be set
1060/// via the environment.
1061///
1062/// First, in `main`, we define our spec table:
1063/// @code
1064/// using balcl::TypeInfo;
1065/// using balcl::OptionType;
1066/// using balcl::OccurrenceInfo;
1067///
1068/// // option specification table
1069/// static const balcl::OptionInfo specTable[] = {
1070/// {
1071/// "r|reverse", // tag
1072/// "isReverse", // name
1073/// "sort in reverse order", // description
1074/// TypeInfo(OptionType::k_BOOL), // type
1075/// OccurrenceInfo::e_OPTIONAL, // optional
1076/// "MYSORT_REVERSE" // env var name
1077/// },
1078/// {
1079/// "", // non-option
1080/// "fileList", // name
1081/// "input files to be sorted", // description
1082/// TypeInfo(OptionType::k_STRING_ARRAY), // type
1083/// OccurrenceInfo::e_REQUIRED, // at least one file required
1084/// "MYSORT_FILES" // env var name
1085/// }
1086/// };
1087///
1088/// int main(int argc, const char **argv)
1089/// {
1090/// @endcode
1091/// Then, we declare our `cmdLine` object. This time, we pass it a stream, and
1092/// messages will be written to that stream rather than `cerr` (the default).
1093/// @code
1094/// balcl::CommandLine cmdLine(specTable, bsl::cout);
1095/// @endcode
1096/// Next, we call `parse` (just like in Example 1):
1097/// @code
1098/// if (cmdLine.parse(argc, argv)) {
1099/// cmdLine.printUsage();
1100/// return -1; // RETURN
1101/// }
1102/// @endcode
1103///
1104/// `balcl::CommandLine` uses the following precedence to determine the value of
1105/// a command line option:
1106///
1107/// 1. Use the option value on the command-line (if one was supplied)
1108/// 2. Use the option value supplied by an environment variable (if one was
1109/// supplied)
1110/// 3. Use the default value (if one was supplied, or `false` for booleans)
1111///
1112/// Finally, if an option value is not supplied by either the command line or
1113/// environment, and there is no default value, any linked variable will be
1114/// unmodified, `cmdLine.hasValue` for the option will return `false`, and the
1115/// behavior is undefined if `cmdLine.the<TYPE>` for the option is called.
1116///
1117/// Note that `cmdLine.isSpecified` will be `true` only if an option was
1118/// supplied by the command line or the environment.
1119///
1120/// If an array options is set by an environment variable, the different
1121/// elements of the array are separated by spaces by default.
1122///
1123/// All these calling sequences are equivalent:
1124/// @code
1125/// $ mysort -r inputFile1 inputFile2 inputFile3
1126/// @endcode
1127/// or
1128/// @code
1129/// $ mysort inputFile1 --reverse inputFile2 inputFile3
1130/// @endcode
1131/// or
1132/// @code
1133/// $ mysort inputFile1 inputFile2 inputFile3 -r
1134/// @endcode
1135/// or the user can specify arguments through environment variables:
1136/// @code
1137/// $ export MYSORT_REVERSE=true
1138/// $ export MYSORT_FILES="inputFile1 inputFile2 inputFile3"
1139/// $ mysort
1140/// @endcode
1141/// or as a combination of command line arguments and environment variables:
1142/// @code
1143/// $ export MYSORT_FILES="inputFile1 inputFile2 inputFile3"
1144/// $ mysort -r
1145/// @endcode
1146/// The '\' character is used as an escape character for array values provided
1147/// via an environment variable. So, for example, if we needed to encode file
1148/// names that contain a space (` `), which is the element separator (by
1149/// default), we would use "\ ":
1150/// @code
1151/// $ export MYSORT_FILES='C:\\file\ name\ 1 C:\\file\ name\ 2'
1152/// @endcode
1153/// Notice we used a single tick to avoid requiring a double escape when
1154/// supplying the string to the shell (e.g., avoiding "C:\\\\file\\ name\\ 1").
1155///
1156/// ### Example 4: Option Constraints {#balcl_commandline-example-4-option-constraints}
1157///
1158///
1159/// Suppose, we are again implementing `mysort`, and we want to introduce some
1160/// constraints on the values supplied for the variables. In this example, we
1161/// will ensure that the supplied input files exist and are not directories, and
1162/// that `fieldSeparator` is appropriate.
1163///
1164/// First, we write a validation function for the file name. A validation
1165/// function supplied to `balcl::CommandLine` takes an argument of a const
1166/// pointer to the input option type (with the user provided value) and a stream
1167/// on which to write an error message, and the validation function returns a
1168/// `bool` that is `true` if the option is valid, and `false` otherwise.
1169///
1170/// Here, we implement a function to validate a file name, that returns `true`
1171/// if the file exists and is a regular file, and `false` otherwise (writing an
1172/// description of the error to the `stream`):
1173/// @code
1174/// bool isValidFileName(const bsl::string *fileName, bsl::ostream& stream)
1175/// {
1176/// if (!bdls::FilesystemUtil::isRegularFile(*fileName, true)) {
1177/// stream << "Invalid file: " << *fileName << bsl::endl;
1178///
1179/// return false; // RETURN
1180/// }
1181///
1182/// return true;
1183/// }
1184/// @endcode
1185/// Then, we also want to make sure that the specified `fieldSeparator` is
1186/// a non-whitespace printable ascii character, so we write a function for that:
1187/// @code
1188/// bool isValidFieldSeparator(const char *fieldSeparator,
1189/// bsl::ostream& stream)
1190/// {
1191/// const unsigned char uc = *fieldSeparator;
1192/// if (::isspace(uc) || !::isprint(uc)) {
1193/// stream << "Invalid field separator specified." << bsl::endl;
1194///
1195/// return false; // RETURN
1196/// }
1197///
1198/// return true;
1199/// }
1200/// @endcode
1201/// Next, we define `main` and declare the variables to be configured:
1202/// @code
1203/// int main(int argc, const char **argv)
1204/// {
1205/// using balcl::Constraint;
1206/// using balcl::OptionType;
1207/// using balcl::OccurrenceInfo;
1208/// using balcl::TypeInfo;
1209///
1210/// bool reverse = false;
1211/// char fieldSeparator;
1212/// bsl::vector<bsl::string> files;
1213/// @endcode
1214/// Notice that `fieldSeparator` are in automatic storage with no constructor or
1215/// initial value. We can safely use an uninitialized variable in the
1216/// `specTable` below because the `specTable` provides a default value for it,
1217/// which will be assigned to the variable if an option value is not provided on
1218/// the command line or through environment variables. `reverse` has to be
1219/// initialized because no default for it is provided in `specTable`.
1220///
1221/// Then, we declare our `specTable`, providing function pointers for our
1222/// constraint functions to the second argument of the `TypeInfo` constructor.
1223/// @code
1224/// // option specification table
1225///
1226/// static const balcl::OptionInfo specTable[] = {
1227/// {
1228/// "r|reverse", // tag
1229/// "isReverse", // name
1230/// "sort in reverse order", // description
1231/// TypeInfo(&reverse), // linked variable
1232/// OccurrenceInfo(), // default value
1233/// "" // env variable name
1234/// },
1235/// {
1236/// "f|field-separator", // tag
1237/// "fieldSeparator", // name
1238/// "field separator character", // description
1239/// TypeInfo(&fieldSeparator, // linked variable
1240/// &isValidFieldSeparator), // constraint
1241/// OccurrenceInfo('|'),
1242/// "" // env variable name
1243/// },
1244/// {
1245/// "", // non-option
1246/// "fileList", // name
1247/// "input files to be sorted", // description
1248/// TypeInfo(&files, &isValidFileName), // linked variable and
1249/// // constraint
1250/// OccurrenceInfo::e_REQUIRED, // at least one file
1251/// // required
1252/// "" // env variable name
1253/// }
1254/// };
1255///
1256/// balcl::CommandLine cmdLine(specTable);
1257/// if (cmdLine.parse(argc, argv)) {
1258/// cmdLine.printUsage();
1259/// return -1; // RETURN
1260/// }
1261/// @endcode
1262/// If the constraint functions return `false`, `cmdLine.parse` will return
1263/// non-zero, and the output will contain the message from the constraint
1264/// function followed by the usage message.
1265///
1266/// ### Example 5: Using bsl::optional for Optional Command Line Parameters {#balcl_commandline-example-5-using-bsl-optional-for-optional-command-line-parameters}
1267///
1268///
1269/// We can use a `bsl::optional` variables when providing optional command line
1270/// parameters. Suppose we want to write a command line that takes an optional
1271/// input file, and if the file is not supplied, take input from a
1272/// `bsl::stringstream`.
1273///
1274/// To represent the optional file name parameter, we link a variable of type
1275/// `bsl::optional<bsl::string>`. In general, when linking a variable to an
1276/// option, we can choose to use `bsl::optonal<TYPE>` in place of `TYPE`, for
1277/// any option type other than `bool`.
1278/// @code
1279/// int main(int argc, const char **argv)
1280/// {
1281/// bsl::optional<bsl::string> optionalFileName;
1282///
1283/// const balcl::OptionInfo specTable[] = {
1284/// {
1285/// "i|inputFile", // tag
1286/// "filename", // name
1287/// "name of input file", // description
1288/// balcl::TypeInfo(&optionalFileName), // linked optional variable
1289/// balcl::OccurrenceInfo(), // occurence info
1290/// "" // env variable name
1291/// }
1292/// };
1293///
1294/// balcl::CommandLine cmdLine(specTable);
1295/// if (cmdLine.parse(argc, argv)) {
1296/// cmdLine.printUsage();
1297/// return -1; // RETURN
1298/// }
1299/// @endcode
1300/// Finally, we test whether `optionalFileName` has been set, and if it has not
1301/// been set, take input from a prepared `stringstream`.
1302/// @code
1303/// bsl::stringstream ss;
1304/// bsl::istream *inStream = &ss;
1305///
1306/// bsl::ifstream fileStream;
1307/// if (optionalFileName.has_value()) {
1308/// fileStream.open(optionalFileName->c_str());
1309/// inStream = &fileStream;
1310/// }
1311/// else {
1312/// // Prepare the 'stringstream'.
1313///
1314/// ss << "The quick brown fox jumps over the lazy dog\n";
1315/// }
1316///
1317/// performTask(*inStream);
1318/// @endcode
1319/// @}
1320/** @} */
1321/** @} */
1322
1323/** @addtogroup bal
1324 * @{
1325 */
1326/** @addtogroup balcl
1327 * @{
1328 */
1329/** @addtogroup balcl_commandline
1330 * @{
1331 */
1332
1333#include <balscm_version.h>
1334
1335#include <balcl_option.h>
1336#include <balcl_optioninfo.h>
1337#include <balcl_optiontype.h>
1338#include <balcl_optionvalue.h>
1339
1340#include <bdlb_printmethods.h>
1341
1343
1344#include <bslma_allocator.h>
1346
1347#include <bsls_assert.h>
1348#include <bsls_types.h>
1349
1350#include <bsl_cstddef.h> // 'bsl::size_t'
1351#include <bsl_cstring.h> // 'bsl::strcmp'
1352#include <bsl_iosfwd.h>
1353#include <bsl_sstream.h> // 'bsl::ostringstream'
1354#include <bsl_string.h>
1355#include <bsl_string_view.h>
1356#include <bsl_vector.h>
1357
1358#include <bdlt_date.h>
1359#include <bdlt_datetime.h>
1360#include <bdlt_time.h>
1361
1362
1363
1364namespace balcl {
1365
1366 // =============================
1367 // struct CommandLine_SchemaData
1368 // =============================
1369
1370/// This `struct`, a pure value-semantic type, is used to manage option
1371/// value type and name information in support of public interfaces to
1372/// parsed options. See `CommandLineOptionsHandle`.
1374
1375 // PUBLIC DATA
1376 OptionType::Enum d_type; // option data type
1377 const char *d_name_p; // option name
1378};
1379
1380// FREE OPERATORS
1381
1382/// Return `true` if the specified `lhs` and `rhs` have the same value, and
1383/// `false` otherwise. Two `CommandLine_SchemaData` objects have the same
1384/// value if their `type` attributes are the same and if their `name`
1385/// attributes compare equal.
1386bool operator==(const CommandLine_SchemaData& lhs,
1387 const CommandLine_SchemaData& rhs);
1388
1389/// Return `true` if the specified `lhs` and `rhs` do note have the same
1390/// value, and `false` otherwise. Two `CommandLine_SchemaData` objects do
1391/// not have the same value if their `type` attributes are not the same or
1392/// if their `name` attributes do not compare equal.
1393bool operator!=(const CommandLine_SchemaData& lhs,
1394 const CommandLine_SchemaData& rhs);
1395
1396 // =================
1397 // class CommandLine
1398 // =================
1399
1401
1402/// This value-semantic `class` parses, validates, and provides access to
1403/// command-line arguments. The constructor takes the specification
1404/// describing the command-line arguments. Once created, `printUsage` can
1405/// be invoked to print the usage syntax. The `parse` method takes
1406/// command-line arguments and validates them against the specification
1407/// provided at creation, writing a suitable message to an
1408/// optionally-specified stream in case of a parsing error. Once parsed,
1409/// options and values can be accessed using various accessors. The class
1410/// has a set of `theType` methods (e.g., `theString`, `theInt`) that
1411/// provide access, by name, to the value of the indicated option. It is
1412/// also possible to link a variable with an option in the specification;
1413/// doing so will cause the variable to be loaded with the option value once
1414/// `parse` has been invoked. The `options` method returns a
1415/// `balcl::CommandLineOptionsHandle` object referring to the option names
1416/// and their values. A similar but different method, `specifiedOptions`,
1417/// is suitable for overwriting other configuration parameters (possibly
1418/// obtained from a configuration file).
1419///
1420/// See @ref balcl_commandline
1422
1423 // PRIVATE TYPES
1426
1427 enum State {
1428 e_INVALID = 0,
1429 e_PARSED = 1,
1430 e_NOT_PARSED = 2
1431 };
1432
1433 // DATA
1434 bsl::vector<Option> d_options; // command-line options
1435 // specified at
1436 // construction
1437
1438 bsl::vector<bsl::vector<int> > d_positions; // set of positions of
1439 // each command-line
1440 // option in the
1441 // arguments specified to
1442 // 'parse', indexed by
1443 // position of option in
1444 // 'd_options'
1445
1446 bsl::vector<int> d_nonOptionIndices;
1447 // set of positions of
1448 // each command-line
1449 // non-option in the
1450 // arguments specified to
1451 // 'parse', indexed by
1452 // non-option rank in
1453 // 'd_options'
1454
1455 State d_state; // indicates whether
1456 // 'parse' was invoked,
1457 // and with what result
1458
1459 bsl::vector<bsl::string> d_arguments; // command-line arguments
1460 // specified to 'parse'
1461
1462 CommandLine_Schema d_schema; // schema describing the
1463 // structure of the
1464 // option values in the
1465 // returned handle
1466
1467 OptionValueList d_data; // primary option values,
1468 // recorded one by one as
1469 // they are parsed by the
1470 // 'parse' manipulator
1471
1472 OptionValueList d_dataFinal; // final option values,
1473 // copied from 'd_data'
1474 // and from default
1475 // values by 'postParse'
1476
1477 mutable OptionValueList d_specifiedOptions;
1478 // specified data, i.e.
1479 // 'd_dataFinal' with
1480 // non-specified
1481 // arguments reset,
1482 // created by the
1483 // 'specifiedOptions'
1484 // manipulator
1485
1486 mutable bool d_isBindin2Valid;
1487 // records whether
1488 // 'd_specifiedOptions'
1489 // was initialized by
1490 // 'specifiedOptions'
1491
1492 bool d_envVarsPresent;
1493 // 'true' if any
1494 // environment variable
1495 // names are present in
1496 // 'd_options'
1497
1498 private:
1499 // PRIVATE MANIPULATORS
1500
1501 /// Reset this command-line object to an uninitialized state. Note that
1502 /// the state is set to `INVALID` and not `NOT_PARSED`.
1503 void clear();
1504
1505 /// Store the specified `argc` entries from the specified `argv` array
1506 /// of command-line arguments in this object.
1507 void initArgs(int argc, const char *const argv[]);
1508
1509 /// Parse the command-line arguments contained in `d_arguments`, and
1510 /// write a description of any errors that occur to the specified
1511 /// `errorStream`. Note that this operation will parse command line
1512 /// arguments implementing the documented behavior for `parse`, using
1513 /// `postParseImp` to perform verification of the parsed values.
1514 int parseImp(bsl::ostream& errorStream);
1515
1516 /// Verify that all required arguments have been given a value, and in
1517 /// that case load all the primary option values (if set) or default
1518 /// option values (if the primary option value is optional and set by no
1519 /// command-line argument) into the final option values and set the
1520 /// linked variables, if any. Return 0 on success, and a non-zero value
1521 /// if not all required arguments are provided with a value (and in this
1522 /// case, leave the final option values and linked variables unchanged).
1523 /// Upon encountering an error, output to the specified `errorStream` a
1524 /// descriptive error message and abort parsing subsequent arguments.
1525 int postParseImp(bsl::ostream& errorStream);
1526
1527 void validateAndInitialize();
1528 /// Validate the command-line options passed at construction with
1529 /// respect to the command-line documented invariants (e.g., valid tags,
1530 /// names, and descriptions, default values satisfying constraints,
1531 /// uniqueness of tags and names, and miscellaneous constraints), and
1532 /// initialize all internal state for parsing. Optionally specify an
1533 /// output `errorStream`. If `errorStream` is not specified,
1534 /// `bsl::cerr` is used. Upon encountering errors, output descriptive
1535 /// error messages and abort the execution of this program by invoking
1536 /// the currently installed assertion handler (unconditionally). Note
1537 /// that this method will attempt to report as many errors as possible
1538 /// before aborting, but that correcting all these errors will not
1539 /// guarantee that subsequent execution would result in successful
1540 /// validation.
1541 void validateAndInitialize(bsl::ostream& errorStream);
1542
1543 // PRIVATE ACCESSORS
1544
1545 /// Return the index (in the options table passed at construction) of an
1546 /// option whose name matches the specified `name` string, or -1 if no
1547 /// such `name` exists.
1548 int findName(const bsl::string_view& name) const;
1549
1550 /// Return the index (in the options table passed at construction) of a
1551 /// command-line option whose long tag matches the specified `longTag`
1552 /// string of the specified `tagLength`, or -1 if no such `longTag`
1553 /// exists.
1554 int findTag(const bsl::string_view& longTag) const;
1555
1556 /// Return the index (in the options table passed at construction) of an
1557 /// option whose short tag matches the specified `shortTag` character,
1558 /// or -1 if no such `shortTag` exists.
1559 int findTag(char shortTag) const;
1560
1561 /// Output to the specified `errorStream` a message describing the location
1562 /// in the argument at the specified `index` (in the list of command-line
1563 /// arguments) where an error was found. Optionally specify a `start`
1564 /// character position in that argument; if `start` is specified,
1565 /// optionally specify an `end` character position as well.
1566 void location(bsl::ostream& errorStream,
1567 int index,
1568 int start = -1,
1569 int end = -1) const;
1570
1571 /// Return the length of the longest name in all the possible non-flag
1572 /// options of this command line.
1573 int longestNonFlagNameSize() const;
1574
1575 /// Return the length of the longest long tag in all the possible options
1576 /// of this command line. Note that short tags are ignored.
1577 int longestTagSize() const;
1578
1579 /// Check that all required options have already been parsed. Optionally
1580 /// specify `checkAlsoNonOptions`. If `checkAlsoNonOptions` is `true` or
1581 /// not specified, required non-option arguments that have not been parsed
1582 /// will also be returned; if `false`, they will be ignored. Return the
1583 /// index of the first missing option, or -1 if none.
1584 int missing(bool checkAlsoNonOptions = true) const;
1585
1586 public:
1587 // TRAITS
1590
1591 // CLASS METHODS
1592
1593 /// Return `true` if the specified (statically-initialized) `specTable` of
1594 /// the specified `LENGTH` has a valid set of command-line option
1595 /// specifications, and `false` otherwise. Optionally specify
1596 /// `errorStream` to which error messages are written. If no `errorStream`
1597 /// is specified, this method produces no output. See {Valid
1598 /// `balcl::OptionInfo` Specifications} for a description of the validity
1599 /// requirements.
1600 template <int LENGTH>
1602 const OptionInfo (&specTable)[LENGTH]);
1603 template <int LENGTH>
1605 OptionInfo (&specTable)[LENGTH]);
1606 template <int LENGTH>
1608 const OptionInfo (&specTable)[LENGTH],
1609 bsl::ostream& errorStream);
1610 template <int LENGTH>
1612 OptionInfo (&specTable)[LENGTH],
1613 bsl::ostream& errorStream);
1614
1615 static bool isValidOptionSpecificationTable(const OptionInfo *specTable,
1616 int length);
1617 /// Return `true` if the specified `specTable` of the specified `length`
1618 /// has a valid set of command-line option specifications, and `false`
1619 /// otherwise. Optionally specify `errorStream` to which error messages
1620 /// are written. If no `errorStream` is specified, this method produces
1621 /// not output. See {Valid `balcl::OptionInfo` Specifications} for a
1622 /// description of the validity requirements. The behavior is undefined
1623 /// unless `0 <= length`. Note that `specTable` need not be statically
1624 /// initialized.
1625 static bool isValidOptionSpecificationTable(const OptionInfo *specTable,
1626 int length,
1627 bsl::ostream& errorStream);
1628
1629 // CREATORS
1630
1631 /// Create an object accepting the command-line options described by the
1632 /// specified (statically-initialized) `specTable`. Optionally specify a
1633 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
1634 /// currently installed default allocator is used. The behavior is
1635 /// undefined unless `specTable` satisfies the
1636 /// `isValidOptionSpecificationTable` function. Note that an appropriate
1637 /// error message is written to the specified `errorStream`.
1638 template <int LENGTH>
1639 CommandLine(const OptionInfo (&specTable)[LENGTH],
1640 bsl::ostream& errorStream,
1641 bslma::Allocator *basicAllocator = 0);
1642 template <int LENGTH>
1643 CommandLine(OptionInfo (&specTable)[LENGTH],
1644 bsl::ostream& errorStream,
1645 bslma::Allocator *basicAllocator = 0);
1646
1647 /// Create an object accepting the command-line options described by the
1648 /// specified (statically-initialized) `specTable`. Optionally specify a
1649 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
1650 /// currently installed default allocator is used. The behavior is
1651 /// undefined unless `specTable` satisfies the
1652 /// `isValidOptionSpecificationTable` function. Note that an appropriate
1653 /// error message is written to `bsl::cerr`.
1654 template <int LENGTH>
1655 explicit
1656 CommandLine(const OptionInfo (&specTable)[LENGTH],
1657 bslma::Allocator *basicAllocator = 0);
1658 template <int LENGTH>
1659 explicit
1660 CommandLine(OptionInfo (&specTable)[LENGTH],
1661 bslma::Allocator *basicAllocator = 0);
1662
1663 /// Create an object accepting the command-line options described by the
1664 /// specified `specTable` of the specified `length`. Optionally specify a
1665 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
1666 /// currently installed default allocator is used. The behavior is
1667 /// undefined unless `specTable` satisfies the
1668 /// `isValidOptionSpecificationTable` function. Note that an appropriate
1669 /// error message is written to `bsl::cerr`. Also note that `specTable`
1670 /// need not be statically initialized.
1671 CommandLine(const OptionInfo *specTable,
1672 int length,
1673 bslma::Allocator *basicAllocator = 0);
1674
1675 /// Create an object accepting the command-line options described by the
1676 /// specified `specTable` of the specified `length`. Optionally specify a
1677 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
1678 /// currently installed default allocator is used. The behavior is
1679 /// undefined unless `specTable` satisfies the
1680 /// `isValidOptionSpecificationTable` function. Note that an appropriate
1681 /// error message is written to the specified `errorStream`. Also note
1682 /// that `specTable` need not be statically initialized.
1683 CommandLine(const OptionInfo *specTable,
1684 int length,
1685 bsl::ostream& errorStream,
1686 bslma::Allocator *basicAllocator = 0);
1687
1688 /// Create a command-line object having the value of the specified
1689 /// `original` command line, if the `original` is parsed, and otherwise
1690 /// having a state such that parsing command-line arguments results in the
1691 /// same value as parsing the same command-line arguments with the
1692 /// `original`. Optionally specify a `basicAllocator` used to supply
1693 /// memory. If `basicAllocator` is 0, the currently installed default
1694 /// allocator is used. The behavior is undefined unless `original` is
1695 /// valid (i.e., `original.isValid()` returns `true`).
1696 CommandLine(const CommandLine& original,
1697 bslma::Allocator *basicAllocator = 0);
1698
1699 /// Destroy this command-line object.
1701
1702 // MANIPULATORS
1703
1704 /// Assign to this command-line object the value of the specified `rhs`
1705 /// command-line object and return a reference providing modifiable access
1706 /// to this object. The behavior is undefined unless both `rhs` and this
1707 /// object are valid (i.e., `isValid()` and `rhs.isValid()` both return
1708 /// `true`).
1710
1711 int parse(int argc, const char *const argv[]);
1712 /// Parse the command-line arguments contained in the array starting at the
1713 /// specified `argv` having the specified `argc` length. Optionally
1714 /// specify an `errorStream` to which an appropriate error message is
1715 /// written if parsing fails. If `errorStream` is not specified,
1716 /// `bsl::cerr` is used. Return 0 on success, and a non-zero value
1717 /// otherwise. If an argument is not specified on the command-line, then
1718 /// if the `Option` object configuration for this `CommandLine` defines an
1719 /// environment variable name and the runtime environment for this
1720 /// application has set that environment variable, then set the option to
1721 /// the value of the environment variable. Otherwise, if an option is not
1722 /// set by the command line, or the environment, set the option using the
1723 /// default value if one has been provided. If the option has not been set
1724 /// by the command line, environment, or by default, `hasValue` for the
1725 /// option will return `false`. After a successful call `isParsed()` and
1726 /// `isValid()` will both be `true`, and the information provided by `argv`
1727 /// can be viewed via the accessors. After an unsuccessful call
1728 /// `isParsed()` and `isValid()` will both be `false`. The behavior is
1729 /// undefined unless `isValid()` is `true` and `isParsed()` is `false`
1730 /// (i.e. the `CommandLine` was constructed in a valid state, and `parse`
1731 /// has not previously been called).
1732 int parse(int argc, const char *const argv[], bsl::ostream& errorStream);
1733
1734 // ACCESSORS
1735
1736 /// Return `true` if this command-line object is configured with an option
1737 /// having the specified `name`, and `false` otherwise.
1738 bool hasOption(const bsl::string_view& name) const;
1739
1740 /// Return `true` if this command-line object's option having the specified
1741 /// `name` has a defined value, and `false` otherwise. An option has a
1742 /// defined value if `isSpecified(name)` or if a default value was
1743 /// configured for the option (see {Occurrence Information Field}). The
1744 /// behavior is undefined unless this command-line object `isParsed()` and
1745 /// `hasOption(name)`.
1746 bool hasValue(const bsl::string_view& name) const;
1747
1748 /// Return `true` if this object was parsed successfully, and `false`
1749 /// otherwise. Note that if `parse` was invoked but failed, this method
1750 /// returns `false`.
1751 bool isParsed() const;
1752
1753 /// Return `true` if the option with the specified `name` has been entered
1754 /// on the command line and, if the optionally specified `count` is not 0,
1755 /// load into `count` the number of times the option `name` has been
1756 /// entered on the command line; otherwise, return `false` and leave
1757 /// `count` unaffected. Note that, in order to receive the valid value,
1758 /// the command line must be successfully parsed.
1759 bool isSpecified(const bsl::string_view& name) const;
1760 bool isSpecified(const bsl::string_view& name, int *count) const;
1761
1762 /// Return `true` if this object is in a valid state, and `false`
1763 /// otherwise. Objects are in a valid state after construction from a
1764 /// valid set of option specifications (see the function-level
1765 /// documentation of the `isValidOptionSpecificationTable` method) and
1766 /// after a successful invocation of the `parse` method. Conversely,
1767 /// construction from invalid option specifications or an unsuccessful
1768 /// invocation of the `parse` method leaves this object in an invalid
1769 /// state. Note that additional object state is available from the
1770 /// `isParsed` accessor method.
1771 bool isValid() const;
1772
1773 /// Return the number of times the option with the specified `name` has
1774 /// been entered on the command line, or 0 if `name` is not the name of a
1775 /// field in the command-line specification passed at construction to this
1776 /// object. Note that, in order to receive the valid number of
1777 /// occurrences, the command line must be successfully parsed.
1778 int numSpecified(const bsl::string_view& name) const;
1779
1780 /// Return the command-line options and their values. If an option was not
1781 /// entered on the command line *and* a default value was provided for that
1782 /// option, then that default value will be used (note the difference with
1783 /// the `specifiedOptions` method). If an option was not entered on the
1784 /// command line *and* no default value was provided for that option, then
1785 /// the corresponding option will be in a null state. The behavior is
1786 /// undefined unless `isParsed` returns `true`.
1788
1789 /// Return the position where the option with the specified `name` has been
1790 /// entered on the command line (i.e., the index in the `argv` argument to
1791 /// the `parse` method). If the option was specified multiple times on the
1792 /// command line, return the position of the first instance. If the option
1793 /// was specified as an environment variable but not on the command line,
1794 /// return -2. If the option was not specified, return -1. The behavior
1795 /// is undefined unless the option is of scalar type.
1796 int position(const bsl::string_view& name) const;
1797
1798 /// Return the positions where the option with the specified `name` has
1799 /// been entered on the command line (i.e., the offset in the `argv`
1800 /// argument to the `parse` method). If the option was not specified,
1801 /// return an empty vector. Note that, in order to receive the valid
1802 /// positions, the command line must be successfully parsed.
1804
1805 /// Print usage to the specified output `errorStream`, describing what the
1806 /// command line should look like. If `errorStream` is not specified,
1807 /// print usage to `stderr`. Optionally specify `programName` to use as
1808 /// the name of the program in the printed usage. If `programName` is not
1809 /// specified and if `parse` has been previously called successfully, use
1810 /// the first element of the `argv` argument; otherwise, use a default
1811 /// name. This method can be invoked at any time, even before `parse` has
1812 /// been invoked on this object.
1813 void printUsage() const;
1814 void printUsage(const bsl::string_view& programName) const;
1815 void printUsage(bsl::ostream& errorStream) const;
1816 void printUsage(bsl::ostream& errorStream,
1817 const bsl::string_view& programName) const;
1818
1819 /// Return the command-line options and their values. If an option was not
1820 /// entered on the command line or set through an environment variable,
1821 /// then the option will be in a null state (note the difference with the
1822 /// `options` method). This method is especially useful for overwriting
1823 /// some other configuration (potentially obtained from a configuration
1824 /// file). The behavior is undefined unless `isParsed` returns `true`.
1826
1827 /// Return the type of the option having the specified `name`. The
1828 /// behavior is undefined unless this command-line object
1829 /// `hasOption(name)`.
1831
1832 // 'the*' Accessors
1833
1834// BDE_VERIFY pragma: -FABC01 // not in alphabetic order
1835
1836 /// Return the value of the option having the specified `name`. The value
1837 /// returned matches that returned by `isSpecified(name)`. The behavior is
1838 /// undefined unless this command-line object `isParsed()`,
1839 /// `hasOption(name)`, and `OptionType::e_BOOL == type(name)`.
1840 bool theBool(const bsl::string_view& name) const;
1841
1842 /// Return the value of the option having the specified `name`. The
1843 /// behavior is undefined unless this command-line object `isParsed()`,
1844 /// `hasOption(name)`, `OptionType::e_CHAR == type(name)`, and
1845 /// `hasValue(name)`.
1846 char theChar(const bsl::string_view& name) const;
1847
1848 /// Return the value of the option having the specified `name`. The
1849 /// behavior is undefined unless this command-line object `isParsed()`,
1850 /// `hasOption(name)`, `OptionType::e_INT == type(name)`, and
1851 /// `hasValue(name)`.
1852 int theInt(const bsl::string_view& name) const;
1853
1854 /// Return the value of the option having the specified `name`. The
1855 /// behavior is undefined unless this command-line object `isParsed()`,
1856 /// `hasOption(name)`, `OptionType::e_INT64 == type(name)`, and
1857 /// `hasValue(name)`.
1859
1860 /// Return the value of the option having the specified `name`. The
1861 /// behavior is undefined unless this command-line object `isParsed()`,
1862 /// `hasOption(name)`, `OptionType::e_DOUBLE == type(name)`, and
1863 /// `hasValue(name)`.
1864 double theDouble(const bsl::string_view& name) const;
1865
1866 /// Return a `const` reference to the value of the option having the
1867 /// specified `name`. The behavior is undefined unless this
1868 /// command-line object `isParsed()`, `hasOption(name)`,
1869 /// `OptionType::e_STRING == type(name)`, and `hasValue(name)`.
1870 const bsl::string& theString(const bsl::string_view& name) const;
1871
1872 /// Return a `const` reference to the value of the option having the
1873 /// specified `name`. The behavior is undefined unless this
1874 /// command-line object `isParsed()`, `hasOption(name)`,
1875 /// `OptionType::e_DATETIME == type(name)`, and `hasValue(name)`.
1877
1878 /// Return a `const` reference to the value of the option having the
1879 /// specified `name`. The behavior is undefined unless this
1880 /// command-line object `isParsed()`, `hasOption(name)`,
1881 /// `OptionType::e_DATE == type(name)`, and `hasValue(name)`.
1882 const bdlt::Date& theDate(const bsl::string_view& name) const;
1883
1884 /// Return a `const` reference to the value of the option having the
1885 /// specified `name`. The behavior is undefined unless this
1886 /// command-line object `isParsed()`, `hasOption(name)`,
1887 /// `OptionType::e_TIME == type(name)`, and `hasValue(name)`.
1888 const bdlt::Time& theTime(const bsl::string_view& name) const;
1889
1890 /// Return a `const` reference to the value of the option having the
1891 /// specified `name`. The behavior is undefined unless this
1892 /// command-line object `isParsed()`, `hasOption(name)`,
1893 /// `OptionType::e_CHAR_ARRAY == type(name)`, and `hasValue(name)`.
1895
1896 /// Return a `const` reference to the value of the option having the
1897 /// specified `name`. The behavior is undefined unless this
1898 /// command-line object `isParsed()`, `hasOption(name)`,
1899 /// `OptionType::e_INT_ARRAY == type(name)`, and `hasValue(name)`.
1901
1902 /// Return a `const` reference to the value of the option having the
1903 /// specified `name`. The behavior is undefined unless this
1904 /// command-line object `isParsed()`, `hasOption(name)`,
1905 /// `OptionType::e_INT64_ARRAY == type(name)`, and `hasValue(name)`.
1907 const bsl::string_view& name) const;
1908
1909 /// Return a `const` reference to the value of the option having the
1910 /// specified `name`. The behavior is undefined unless this
1911 /// command-line object `isParsed()`, `hasOption(name)`,
1912 /// `OptionType::e_DOUBLE_ARRAY == type(name)`, and `hasValue(name)`.
1914 const bsl::string_view& name) const;
1915
1916 /// Return a `const` reference to the value of the option having the
1917 /// specified `name`. The behavior is undefined unless this
1918 /// command-line object `isParsed()`, `hasOption(name)`,
1919 /// `OptionType::e_STRING_ARRAY == type(name)`, and `hasValue(name)`.
1921 const bsl::string_view& name) const;
1922
1923 /// Return a `const` reference to the value of the option having the
1924 /// specified `name`. The behavior is undefined unless this
1925 /// command-line object `isParsed()`, `hasOption(name)`,
1926 /// `OptionType::e_DATETIME_ARRAY == type(name)`, and `hasValue(name)`.
1928 const bsl::string_view& name) const;
1929
1930 /// Return a `const` reference to the value of the option having the
1931 /// specified `name`. The behavior is undefined unless this
1932 /// command-line object `isParsed()`, `hasOption(name)`,
1933 /// `OptionType::e_DATE_ARRAY == type(name)`, and `hasValue(name)`.
1935 const bsl::string_view& name) const;
1936
1937 /// Return a `const` reference to the value of the option having the
1938 /// specified `name`. The behavior is undefined unless this
1939 /// command-line object `isParsed()`, `hasOption(name)`,
1940 /// `OptionType::e_TIME_ARRAY == type(name)`, and `hasValue(name)`.
1942 const bsl::string_view& name) const;
1943
1944// BDE_VERIFY pragma: +FABC01 // not in alphabetic order
1945
1946 // Aspects
1947
1948 /// Return the allocator used by this object to supply memory. Note
1949 /// that if no allocator was supplied at construction the currently
1950 /// installed default allocator at construction is used.
1952
1953 /// Format this command-line object to the specified output `stream` at
1954 /// the (absolute value of) the optionally specified indentation `level`
1955 /// and return a reference to `stream`. If `level` is specified,
1956 /// optionally specify `spacesPerLevel`, the number of spaces per
1957 /// indentation level for this object. If `level` is negative, suppress
1958 /// indentation of the first line. The behavior is undefined unless
1959 /// `0 <= spacesPerLevel`. If `stream` is not valid on entry, this
1960 /// operation has no effect.
1961 bsl::ostream& print(bsl::ostream& stream,
1962 int level = 0,
1963 int spacesPerLevel = 4) const;
1964};
1965
1966// FREE OPERATORS
1967
1968/// Return `true` if the specified `lhs` and `rhs` have the same value, and
1969/// `false` otherwise. Two command-line arguments have the same value if
1970/// and only if they are both parsed successfully and have the same
1971/// command-line specifications and the same values for flags, options, and
1972/// non-option arguments. Note that two identical copies built with the
1973/// same option table, but unparsed, are *not* equal.
1974bool operator==(const CommandLine& lhs, const CommandLine& rhs);
1975
1976/// Return `false` if the specified `lhs` and `rhs` have the same value, and
1977/// `true` otherwise. Two command-line arguments do not have the same value
1978/// if and only if they have different command-line specifications, or one
1979/// is parsed successfully but the other is not, or neither is, or else both
1980/// have the same specification and both are parsed successfully but they
1981/// have different values for at least one flag, option or non-option
1982/// argument. Note that two identical copies built with the same option
1983/// table, but unparsed, are *not* equal.
1984bool operator!=(const CommandLine& lhs, const CommandLine& rhs);
1985
1986/// Write the options and their values in the specified `rhs` to the
1987/// specified output `stream` in a (multi-line) human readable format and
1988/// return a reference to `errorStream`. Note that the last line is *not*
1989/// terminated by a newline character.
1990bsl::ostream& operator<<(bsl::ostream& stream, const CommandLine& rhs);
1991
1992 // ==============================
1993 // class CommandLineOptionsHandle
1994 // ==============================
1995
1996/// This class provides access to the parsed options (if any) of its
1997/// creating `CommandLine` object. The behavior is undefined if any of the
1998/// methods of this class (accessors all) are invoked after a subsequent
1999/// invocation of the `parse` method of the creating object or after the
2000/// destruction of the creating object.
2001///
2002/// See @ref balcl_commandline
2004
2005 // PRIVATE TYPES
2008
2009 // DATA
2010 const OptionValueList *d_data_p;
2011 const CommandLine_Schema *d_schema_p;
2012
2013 // FRIENDS
2014 friend class CommandLine;
2019
2020 // PRIVATE CREATORS
2021
2022 /// Create a `CommandLineOptionsHandle` object referring to the
2023 /// specified `dataPtr` and `schemaPtr`. The behavior is undefined
2024 /// unless `dataPtr->size() == schemaPtr->size()`.
2026 const CommandLine_Schema *schemaPtr);
2027
2028 public:
2029 // ACCESSORS
2030
2031 /// Return the position in this handle object of the option having the
2032 /// specified `name`, and -1 if the handle has no option of that name.
2033 /// Note that, on success, the return values are in the range
2034 /// `[0 .. numOptions() - 1]`.
2035 int index(const bsl::string_view& name) const;
2036
2037 /// Return the name of the option at the specified `index`. The
2038 /// behavior is undefined unless `index < numOptions()`.
2039 const char *name(bsl::size_t index) const;
2040
2041 /// Return the number of parsed options.
2042 bsl::size_t numOptions() const;
2043
2044 /// Return the type of the option at the specified `index` in this
2045 /// handle object. The behavior is undefined unless
2046 /// `index < numOptions()`.
2047 OptionType::Enum type(bsl::size_t index) const;
2048
2049 /// Return the type of the option having the specified `name`. The
2050 /// behavior is undefined unless this handle object has a `name` option
2051 /// (i.e., `0 <= index(name)`).
2053
2054 /// Return a `const` reference to the value (possibly in a null state)
2055 /// of the option at the specified `index` in this handle object. The
2056 /// behavior is undefined unless `index < numOptions()`.
2057 const OptionValue& value(bsl::size_t index) const;
2058
2059 /// Return a `const` reference to the value (possibly in a null state)
2060 /// of this handle object's option having the specified `name`. The
2061 /// behavior is undefined unless this handle object has a `name` option
2062 /// (i.e., `0 <= index(name)`).
2063 const OptionValue& value(const bsl::string_view& name) const;
2064
2065 // 'the*' Accessors
2066
2067// BDE_VERIFY pragma: -FABC01 // not in alphabetic order
2068
2069 /// Return a `const` reference to the value of the option at the
2070 /// specified `index`. Template parameter `TYPE` must be one of the
2071 /// supported types (see {Supported Types}). The behavior is undefined
2072 /// unless `index < numOptions()`, the option has the (template
2073 /// parameter) `TYPE` (i.e.,
2074 /// `OptionType::TypeToEnum<TYPE>::value == type(index)`), and the
2075 /// option has a value (i.e., `false == value(index).isNull()`).
2076 template <class TYPE>
2077 const TYPE& the(bsl::size_t index) const;
2078
2079 /// Return a `const` reference to the value of the option having the
2080 /// specified `name`. Template parameter `TYPE` must be one of the
2081 /// supported types (see {Supported Types}). The behavior is undefined
2082 /// unless this handle object has a `name` option (i.e.,
2083 /// `0 <= index(name)`), the option has (template parameter) `TYPE`
2084 /// (i.e., `OptionType::TypeToEnum<TYPE>::value == type(name)`), and the
2085 /// option has a value (i.e., `false == value(name).isNull()`).
2086 template <class TYPE>
2087 const TYPE& the(const bsl::string_view& name) const;
2088
2089 /// Return the value of the option having the specified `name`. The
2090 /// behavior is undefined unless this handle object has a `name` option
2091 /// (i.e., `0 <= index(name)`), the option has type `bool` (i.e.,
2092 /// `OptionType::e_BOOL == type(name)`), and the option has a value
2093 /// (i.e., `false == value(name).isNull()`).
2094 bool theBool(const bsl::string_view& name) const;
2095
2096 /// Return the value of the option having the specified `name`. The
2097 /// behavior is undefined unless this handle object has a `name` option
2098 /// (i.e., `0 <= index(name)`), the option has type `char` (i.e.,
2099 /// `OptionType::e_CHAR == type(name)`), and the option has a value
2100 /// (i.e., `false == value(name).isNull()`).
2101 char theChar(const bsl::string_view& name) const;
2102
2103 /// Return the value of the option having the specified `name`. The
2104 /// behavior is undefined unless this handle object has a `name` option
2105 /// (i.e., `0 <= index(name)`), the option has type `int` (i.e.,
2106 /// `OptionType::e_INT == type(name)`), and the option has a value
2107 /// (i.e., `false == value(name).isNull()`).
2108 int theInt(const bsl::string_view& name) const;
2109
2110 /// Return the value of the option having the specified `name`. The
2111 /// behavior is undefined unless this handle object has a `name` option
2112 /// (i.e., `0 <= index(name)`), the option has type `bsls::Types::Int64`
2113 /// (i.e., `OptionType::e_INT64 == type(name)`), and the option has a
2114 /// value (i.e., `false == value(name).isNull()`).
2116
2117 /// Return the value of the option having the specified `name`. The
2118 /// behavior is undefined unless this handle object has a `name` option
2119 /// (i.e., `0 <= index(name)`), the option has type `double` (i.e.,
2120 /// `OptionType::e_DOUBLE == type(name)`), and the option has a value
2121 /// (i.e., `false == value(name).isNull()`).
2122 double theDouble(const bsl::string_view& name) const;
2123
2124 /// Return a `const` reference to the value of the option having the
2125 /// specified `name`. The behavior is undefined unless this handle
2126 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2127 /// has type `bsl::string` (i.e., `OptionType::e_STRING == type(name)`),
2128 /// and the option has a value (i.e., `false == value(name).isNull()`).
2129 const bsl::string& theString(const bsl::string_view& name) const;
2130
2131 /// Return a `const` reference to the value of the option having the
2132 /// specified `name`. The behavior is undefined unless this handle
2133 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2134 /// has type `bdlt::Datetime` (i.e.,
2135 /// `OptionType::e_DATETIME == type(name)`), and the option has a value
2136 /// (i.e., `false == value(name).isNull()`).
2137 const bdlt::Datetime& theDatetime(const bsl::string_view& name) const;
2138
2139 /// Return a `const` reference to the value of the option having the
2140 /// specified `name`. The behavior is undefined unless this handle
2141 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2142 /// has type `bdlt::Date` (i.e., `OptionType::e_DATE == type(name)`),
2143 /// and the option has a value (i.e., `false == value(name).isNull()`).
2144 const bdlt::Date& theDate(const bsl::string_view& name) const;
2145
2146 /// Return a `const` reference to the value of the option having the
2147 /// specified `name`. The behavior is undefined unless this handle
2148 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2149 /// has type `bdlt::Time` (i.e., `OptionType::e_TIME == type(name)`),
2150 /// and the option has a value (i.e., `false == value(name).isNull()`).
2151 const bdlt::Time& theTime(const bsl::string_view& name) const;
2152
2153 /// Return a `const` reference to the value of the option having the
2154 /// specified `name`. The behavior is undefined unless this handle
2155 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2156 /// has type `bsl::vector<char>` (i.e.,
2157 /// `OptionType::e_CHAR_ARRAY == type(name)`), and the option has a
2158 /// value (i.e., `false == value(name).isNull()`).
2160
2161 /// Return a `const` reference to the value of the option having the
2162 /// specified `name`. The behavior is undefined unless this handle
2163 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2164 /// has type `bsl::vector<int>` (i.e.,
2165 /// `OptionType::e_INT_ARRAY == type(name)`), and the option has a value
2166 /// (i.e., `false == value(name).isNull()`).
2168
2169 /// Return a `const` reference to the value of the option having the
2170 /// specified `name`. The behavior is undefined unless this handle
2171 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2172 /// has type `bsl::vector<bsls::Types::Int64>` (i.e.,
2173 /// `OptionType::e_INT64_ARRAY == type(name)`), and the option has a
2174 /// value (i.e., `false == value(name).isNull()`).
2176 const bsl::string_view& name) const;
2177
2178 /// Return a `const` reference to the value of the option having the
2179 /// specified `name`. The behavior is undefined unless this handle
2180 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2181 /// has type `bsl::vector<double>` (i.e.,
2182 /// `OptionType::e_DOUBLE_ARRAY == type(name)`), and the option has a
2183 /// value (i.e., `false == value(name).isNull()`).
2185 const bsl::string_view& name) const;
2186
2187 /// Return a `const` reference to the value of the option having the
2188 /// specified `name`. The behavior is undefined unless this handle
2189 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2190 /// has type `bsl::vector<bsl::string>` (i.e.,
2191 /// `OptionType::e_STRING_ARRAY == type(name)`), and the option has a
2192 /// value (i.e., `false == value(name).isNull()`).
2194 const bsl::string_view& name) const;
2195
2196 /// Return a `const` reference to the value of the option having the
2197 /// specified `name`. The behavior is undefined unless this handle
2198 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2199 /// has type `bsl::vector<bdlt::Datetime>` (i.e.,
2200 /// `OptionType::e_DATETIME_ARRAY == type(name)`), and the option has a
2201 /// value (i.e., `false == value(name).isNull()`).
2203 const bsl::string_view& name) const;
2204
2205 /// Return a `const` reference to the value of the option having the
2206 /// specified `name`. The behavior is undefined unless this handle
2207 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2208 /// has type `bsl::vector<bdlt::Date>` (i.e.,
2209 /// `OptionType::e_DATE_ARRAY == type(name)`), and the option has a
2210 /// value (i.e., `false == value(name).isNull()`).
2212 const bsl::string_view& name) const;
2213
2214 /// Return a `const` reference to the value of the option having the
2215 /// specified `name`. The behavior is undefined unless this handle
2216 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2217 /// has type `bsl::vector<bdlt::TIME>` (i.e.,
2218 /// `OptionType::e_TIME_ARRAY == type(name)`), and the option has a
2219 /// value (i.e., `false == value(name).isNull()`).
2221 const bsl::string_view& name) const;
2222
2223// BDE_VERIFY pragma: +FABC01 // not in alphabetic order
2224};
2225
2226// FREE OPERATORS
2227
2228/// Return `true` if the specified `lhs` and `rhs` have the same value, and
2229/// `false` otherwise. Two `CommandLineOptionsHandle` objects have the same
2230/// value if they have the same `numOptions` and each of those options have
2231/// the same `name`, `type`, and `value` or are in the null state.
2232bool operator==(const CommandLineOptionsHandle& lhs,
2233 const CommandLineOptionsHandle& rhs);
2234
2235/// Return `true` if the specified `lhs` and `rhs` do not have the same
2236/// value, and `false` otherwise. Two `CommandLineOptionsHandle` objects do
2237/// not have the same value if they do not have the same `numOptions` or if
2238/// any of their options differ in `name`, `type`, or 'value (or null
2239/// state).
2240bool operator!=(const CommandLineOptionsHandle& lhs,
2241 const CommandLineOptionsHandle& rhs);
2242
2243// ============================================================================
2244// INLINE DEFINITIONS
2245// ============================================================================
2246
2247 // -----------------------------
2248 // struct CommandLine_SchemaData
2249 // -----------------------------
2250
2251} // close package namespace
2252
2253// FREE OPERATORS
2254inline
2255bool balcl::operator==(const CommandLine_SchemaData& lhs,
2256 const CommandLine_SchemaData& rhs)
2257{
2258 return lhs.d_type == rhs.d_type
2259 && 0 == bsl::strcmp(lhs.d_name_p, rhs.d_name_p);
2260}
2261
2262inline
2263bool balcl::operator!=(const CommandLine_SchemaData& lhs,
2264 const CommandLine_SchemaData& rhs)
2265{
2266 return lhs.d_type != rhs.d_type
2267 || 0 != bsl::strcmp(lhs.d_name_p, rhs.d_name_p);
2268}
2269
2270namespace balcl {
2271
2272 // -----------------
2273 // class CommandLine
2274 // -----------------
2275
2276// CLASS METHODS
2277template <int LENGTH>
2278inline
2280 const OptionInfo (&specTable)[LENGTH])
2281{
2282 return isValidOptionSpecificationTable(specTable, LENGTH);
2283}
2284
2285template <int LENGTH>
2286inline
2288 OptionInfo (&specTable)[LENGTH])
2289{
2290 return isValidOptionSpecificationTable(specTable, LENGTH);
2291}
2292
2293template <int LENGTH>
2294inline
2296 const OptionInfo (&specTable)[LENGTH],
2297 bsl::ostream& errorStream)
2298{
2299 return isValidOptionSpecificationTable(specTable, LENGTH, errorStream);
2300}
2301
2302template <int LENGTH>
2303inline
2305 OptionInfo (&specTable)[LENGTH],
2306 bsl::ostream& errorStream)
2307{
2308 return isValidOptionSpecificationTable(specTable, LENGTH, errorStream);
2309}
2310
2311inline
2313 int length)
2314{
2315 BSLS_ASSERT(specTable);
2316 BSLS_ASSERT(0 <= length);
2317
2319 return isValidOptionSpecificationTable(specTable, length, oss);
2320}
2321
2322// CREATORS
2323template <int LENGTH>
2324CommandLine::CommandLine(const OptionInfo (&specTable)[LENGTH],
2325 bsl::ostream& errorStream,
2326 bslma::Allocator *basicAllocator)
2327: d_options(basicAllocator)
2328, d_positions(basicAllocator)
2329, d_nonOptionIndices(basicAllocator)
2330, d_state(e_INVALID)
2331, d_arguments(basicAllocator)
2332, d_schema(basicAllocator)
2333, d_data(basicAllocator)
2334, d_dataFinal(basicAllocator)
2335, d_specifiedOptions(basicAllocator)
2336, d_isBindin2Valid(false)
2337, d_envVarsPresent(false)
2338{
2339 d_options.reserve(LENGTH);
2340 for (int ii = 0; ii < LENGTH; ++ii) {
2341 d_options.push_back(Option(specTable[ii], allocator()));
2342 }
2343 validateAndInitialize(errorStream);
2344 d_state = e_NOT_PARSED;
2345}
2346
2347template <int LENGTH>
2349 bsl::ostream& errorStream,
2350 bslma::Allocator *basicAllocator)
2351: d_options(basicAllocator)
2352, d_positions(basicAllocator)
2353, d_nonOptionIndices(basicAllocator)
2354, d_state(e_INVALID)
2355, d_arguments(basicAllocator)
2356, d_schema(basicAllocator)
2357, d_data(basicAllocator)
2358, d_dataFinal(basicAllocator)
2359, d_specifiedOptions(basicAllocator)
2360, d_isBindin2Valid(false)
2361, d_envVarsPresent(false)
2362{
2363 d_options.reserve(LENGTH);
2364 for (int i = 0; i < LENGTH; ++i) {
2365 d_options.push_back(Option(specTable[i], allocator()));
2366 }
2367 validateAndInitialize(errorStream);
2368 d_state = e_NOT_PARSED;
2369}
2370
2371template <int LENGTH>
2372CommandLine::CommandLine(const OptionInfo (&specTable)[LENGTH],
2373 bslma::Allocator *basicAllocator)
2374: d_options(basicAllocator)
2375, d_positions(basicAllocator)
2376, d_nonOptionIndices(basicAllocator)
2377, d_state(e_INVALID)
2378, d_arguments(basicAllocator)
2379, d_schema(basicAllocator)
2380, d_data(basicAllocator)
2381, d_dataFinal(basicAllocator)
2382, d_specifiedOptions(basicAllocator)
2383, d_isBindin2Valid(false)
2384, d_envVarsPresent(false)
2385{
2386 d_options.reserve(LENGTH);
2387 for (int ii = 0; ii < LENGTH; ++ii) {
2388 d_options.push_back(Option(specTable[ii], allocator()));
2389 }
2390 validateAndInitialize();
2391 d_state = e_NOT_PARSED;
2392}
2393
2394template <int LENGTH>
2396 bslma::Allocator *basicAllocator)
2397: d_options(basicAllocator)
2398, d_positions(basicAllocator)
2399, d_nonOptionIndices(basicAllocator)
2400, d_state(e_INVALID)
2401, d_arguments(basicAllocator)
2402, d_schema(basicAllocator)
2403, d_data(basicAllocator)
2404, d_dataFinal(basicAllocator)
2405, d_specifiedOptions(basicAllocator)
2406, d_isBindin2Valid(false)
2407, d_envVarsPresent(false)
2408{
2409 d_options.reserve(LENGTH);
2410 for (int ii = 0; ii < LENGTH; ++ii) {
2411 d_options.push_back(Option(specTable[ii], allocator()));
2412 }
2413 validateAndInitialize();
2414 d_state = e_NOT_PARSED;
2415}
2416
2417 // ------------------------------
2418 // class CommandLineOptionsHandle
2419 // ------------------------------
2420
2421// PRIVATE CREATORS
2422inline
2423CommandLineOptionsHandle::CommandLineOptionsHandle(
2424 const OptionValueList *dataPtr,
2425 const CommandLine_Schema *schemaPtr)
2426: d_data_p(dataPtr)
2427, d_schema_p(schemaPtr)
2428{
2429 BSLS_ASSERT(dataPtr);
2430 BSLS_ASSERT(schemaPtr);
2431 BSLS_ASSERT(dataPtr->size() == schemaPtr->size());
2432}
2433
2434// ACCESSORS
2435inline
2436const char *CommandLineOptionsHandle::name(bsl::size_t index) const
2437{
2439
2440 return (*d_schema_p)[index].d_name_p;
2441}
2442
2443inline
2445{
2446 return d_schema_p->size();
2447}
2448
2449inline
2451{
2453
2454 return (*d_schema_p)[index].d_type;
2455}
2456
2457inline
2459 const bsl::string_view& name) const
2460{
2461 int index = this->index(name);
2462
2463 BSLS_ASSERT(0 <= index);
2464 BSLS_ASSERT(static_cast<bsl::size_t>(index) < d_schema_p->size());
2465
2466 return (*d_schema_p)[index].d_type;
2467}
2468
2469inline
2470const OptionValue& CommandLineOptionsHandle::value(bsl::size_t index) const
2471{
2473
2474 return (*d_data_p)[index];
2475}
2476
2477inline
2479 const bsl::string_view& name) const
2480{
2481 int index = this->index(name);
2482
2483 BSLS_ASSERT(0 <= index);
2484 BSLS_ASSERT(static_cast<bsl::size_t>(index) < d_schema_p->size());
2485
2486 return (*d_data_p)[index];
2487}
2488
2489 // 'the*' Accessors
2490
2491// BDE_VERIFY pragma: -FABC01 // not in alphabetic order
2492
2493template <class TYPE>
2494const TYPE& CommandLineOptionsHandle::the(bsl::size_t index) const
2495{
2497 BSLS_ASSERT(!value(index).isNull());
2498
2499 return (*d_data_p)[index].the<TYPE>();
2500}
2501
2502template <class TYPE>
2504{
2505 int index = this->index(name);
2506
2507 BSLS_ASSERT(0 <= index);
2509 BSLS_ASSERT(!value(index).isNull());
2510
2511 return the<TYPE>(index);
2512}
2513
2514inline
2516{
2517 int index = this->index(name);
2518
2519 BSLS_ASSERT(0 <= index);
2521 BSLS_ASSERT(!value(index).isNull());
2522
2524}
2525
2526inline
2528{
2529 int index = this->index(name);
2530
2531 BSLS_ASSERT(0 <= index);
2533 BSLS_ASSERT(!value(index).isNull());
2534
2536}
2537
2538inline
2540{
2541 int index = this->index(name);
2542
2543 BSLS_ASSERT(0 <= index);
2545 BSLS_ASSERT(!value(index).isNull());
2546
2548}
2549
2550inline
2552 const bsl::string_view& name) const
2553{
2554 int index = this->index(name);
2555
2556 BSLS_ASSERT(0 <= index);
2558 BSLS_ASSERT(!value(index).isNull());
2559
2561}
2562
2563inline
2565{
2566 int index = this->index(name);
2567
2568 BSLS_ASSERT(0 <= index);
2570 BSLS_ASSERT(!value(index).isNull());
2571
2573}
2574
2575inline
2576const bsl::string&
2578{
2579 int index = this->index(name);
2580
2581 BSLS_ASSERT(0 <= index);
2583 BSLS_ASSERT(!value(index).isNull());
2584
2586}
2587
2588inline
2589const bdlt::Datetime&
2591{
2592 int index = this->index(name);
2593
2594 BSLS_ASSERT(0 <= index);
2596 BSLS_ASSERT(!value(index).isNull());
2597
2599}
2600
2601inline
2602const bdlt::Date&
2604{
2605 int index = this->index(name);
2606
2607 BSLS_ASSERT(0 <= index);
2609 BSLS_ASSERT(!value(index).isNull());
2610
2612}
2613
2614inline
2616 const bsl::string_view& name) const
2617{
2618 int index = this->index(name);
2619
2620 BSLS_ASSERT(0 <= index);
2622 BSLS_ASSERT(!value(index).isNull());
2623
2625}
2626
2627inline
2628const bsl::vector<char>&
2630{
2631 int index = this->index(name);
2632
2633 BSLS_ASSERT(0 <= index);
2635 BSLS_ASSERT(!value(index).isNull());
2636
2638}
2639
2640inline
2641const bsl::vector<int>&
2643{
2644 int index = this->index(name);
2645
2646 BSLS_ASSERT(0 <= index);
2648 BSLS_ASSERT(!value(index).isNull());
2649
2651}
2652
2653inline
2656{
2657 int index = this->index(name);
2658
2659 BSLS_ASSERT(0 <= index);
2661 BSLS_ASSERT(!value(index).isNull());
2662
2664}
2665
2666inline
2669{
2670 int index = this->index(name);
2671
2672 BSLS_ASSERT(0 <= index);
2674 BSLS_ASSERT(!value(index).isNull());
2675
2677}
2678
2679inline
2682{
2683 int index = this->index(name);
2684
2685 BSLS_ASSERT(0 <= index);
2687 BSLS_ASSERT(!value(index).isNull());
2688
2690}
2691
2692inline
2695{
2696 int index = this->index(name);
2697
2698 BSLS_ASSERT(0 <= index);
2700 BSLS_ASSERT(!value(index).isNull());
2701
2703}
2704
2705inline
2708{
2709 int index = this->index(name);
2710
2711 BSLS_ASSERT(0 <= index);
2713 BSLS_ASSERT(!value(index).isNull());
2714
2716}
2717
2718inline
2721{
2722 int index = this->index(name);
2723
2724 BSLS_ASSERT(0 <= index);
2726 BSLS_ASSERT(!value(index).isNull());
2727
2729}
2730
2731// BDE_VERIFY pragma: +FABC01 // not in alphabetic order
2732
2733} // close package namespace
2734
2735// FREE OPERATORS
2736inline
2739{
2740 BSLS_ASSERT(lhs.d_data_p); BSLS_ASSERT(lhs.d_schema_p);
2741 BSLS_ASSERT(rhs.d_data_p); BSLS_ASSERT(rhs.d_schema_p);
2742
2743 return *lhs.d_data_p == *rhs.d_data_p
2744 && *lhs.d_schema_p == *rhs.d_schema_p;
2745}
2746
2747inline
2750{
2751 BSLS_ASSERT(lhs.d_data_p); BSLS_ASSERT(lhs.d_schema_p);
2752 BSLS_ASSERT(rhs.d_data_p); BSLS_ASSERT(rhs.d_schema_p);
2753
2754 return *lhs.d_data_p != *rhs.d_data_p
2755 || *lhs.d_schema_p != *rhs.d_schema_p;
2756}
2757
2758
2759
2760#endif
2761
2762// ----------------------------------------------------------------------------
2763// Copyright 2020 Bloomberg Finance L.P.
2764//
2765// Licensed under the Apache License, Version 2.0 (the "License");
2766// you may not use this file except in compliance with the License.
2767// You may obtain a copy of the License at
2768//
2769// http://www.apache.org/licenses/LICENSE-2.0
2770//
2771// Unless required by applicable law or agreed to in writing, software
2772// distributed under the License is distributed on an "AS IS" BASIS,
2773// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2774// See the License for the specific language governing permissions and
2775// limitations under the License.
2776// ----------------------------- END-OF-FILE ----------------------------------
2777
2778/** @} */
2779/** @} */
2780/** @} */
Definition balcl_commandline.h:2003
const TYPE & the(bsl::size_t index) const
Definition balcl_commandline.h:2494
const bdlt::Time & theTime(const bsl::string_view &name) const
Definition balcl_commandline.h:2615
const bsl::string & theString(const bsl::string_view &name) const
Definition balcl_commandline.h:2577
char theChar(const bsl::string_view &name) const
Definition balcl_commandline.h:2527
const bsl::vector< bdlt::Time > & theTimeArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2720
bsls::Types::Int64 theInt64(const bsl::string_view &name) const
Definition balcl_commandline.h:2551
OptionType::Enum type(bsl::size_t index) const
Definition balcl_commandline.h:2450
const bsl::vector< bdlt::Datetime > & theDatetimeArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2694
const bdlt::Date & theDate(const bsl::string_view &name) const
Definition balcl_commandline.h:2603
bsl::size_t numOptions() const
Return the number of parsed options.
Definition balcl_commandline.h:2444
const bsl::vector< char > & theCharArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2629
bool theBool(const bsl::string_view &name) const
Definition balcl_commandline.h:2515
friend bool operator!=(const CommandLineOptionsHandle &, const CommandLineOptionsHandle &)
const OptionValue & value(bsl::size_t index) const
Definition balcl_commandline.h:2470
double theDouble(const bsl::string_view &name) const
Definition balcl_commandline.h:2564
const bsl::vector< bdlt::Date > & theDateArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2707
int index(const bsl::string_view &name) const
const bsl::vector< double > & theDoubleArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2668
const bsl::vector< int > & theIntArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2642
const char * name(bsl::size_t index) const
Definition balcl_commandline.h:2436
int theInt(const bsl::string_view &name) const
Definition balcl_commandline.h:2539
const bdlt::Datetime & theDatetime(const bsl::string_view &name) const
Definition balcl_commandline.h:2590
const bsl::vector< bsl::string > & theStringArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2681
friend bool operator==(const CommandLineOptionsHandle &, const CommandLineOptionsHandle &)
const bsl::vector< bsls::Types::Int64 > & theInt64Array(const bsl::string_view &name) const
Definition balcl_commandline.h:2655
Definition balcl_commandline.h:1421
CommandLine(const OptionInfo(&specTable)[LENGTH], bsl::ostream &errorStream, bslma::Allocator *basicAllocator=0)
Definition balcl_commandline.h:2324
bool hasOption(const bsl::string_view &name) const
OptionType::Enum type(const bsl::string_view &name) const
int theInt(const bsl::string_view &name) const
const bdlt::Date & theDate(const bsl::string_view &name) const
bool isParsed() const
BSLMF_NESTED_TRAIT_DECLARATION(CommandLine, bdlb::HasPrintMethod)
bool hasValue(const bsl::string_view &name) const
void printUsage() const
CommandLine(const OptionInfo *specTable, int length, bsl::ostream &errorStream, bslma::Allocator *basicAllocator=0)
static bool isValidOptionSpecificationTable(const OptionInfo *specTable, int length, bsl::ostream &errorStream)
bslma::Allocator * allocator() const
const bsl::vector< bdlt::Date > & theDateArray(const bsl::string_view &name) const
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
const bdlt::Time & theTime(const bsl::string_view &name) const
const bdlt::Datetime & theDatetime(const bsl::string_view &name) const
double theDouble(const bsl::string_view &name) const
~CommandLine()
Destroy this command-line object.
const bsl::vector< int > & positions(const bsl::string_view &name) const
CommandLineOptionsHandle specifiedOptions() const
const bsl::vector< bdlt::Time > & theTimeArray(const bsl::string_view &name) const
CommandLineOptionsHandle options() const
const bsl::vector< bdlt::Datetime > & theDatetimeArray(const bsl::string_view &name) const
BSLMF_NESTED_TRAIT_DECLARATION(CommandLine, bslma::UsesBslmaAllocator)
const bsl::vector< char > & theCharArray(const bsl::string_view &name) const
int numSpecified(const bsl::string_view &name) const
int parse(int argc, const char *const argv[], bsl::ostream &errorStream)
CommandLine & operator=(const CommandLine &rhs)
const bsl::vector< bsl::string > & theStringArray(const bsl::string_view &name) const
bool isSpecified(const bsl::string_view &name, int *count) const
static bool isValidOptionSpecificationTable(const OptionInfo(&specTable)[LENGTH])
Definition balcl_commandline.h:2279
void printUsage(const bsl::string_view &programName) const
bool theBool(const bsl::string_view &name) const
char theChar(const bsl::string_view &name) const
void printUsage(bsl::ostream &errorStream) const
bool isSpecified(const bsl::string_view &name) const
CommandLine(const OptionInfo *specTable, int length, bslma::Allocator *basicAllocator=0)
int position(const bsl::string_view &name) const
bsls::Types::Int64 theInt64(const bsl::string_view &name) const
const bsl::vector< double > & theDoubleArray(const bsl::string_view &name) const
CommandLine(const CommandLine &original, bslma::Allocator *basicAllocator=0)
bool isValid() const
const bsl::vector< bsls::Types::Int64 > & theInt64Array(const bsl::string_view &name) const
void printUsage(bsl::ostream &errorStream, const bsl::string_view &programName) const
const bsl::string & theString(const bsl::string_view &name) const
const bsl::vector< int > & theIntArray(const bsl::string_view &name) const
int parse(int argc, const char *const argv[])
Definition balcl_optionvalue.h:393
Definition balcl_option.h:132
Definition bdlt_date.h:294
Definition bdlt_datetime.h:331
Definition bdlt_time.h:196
Definition bslstl_ostringstream.h:175
Definition bslstl_stringview.h:441
Definition bslstl_string.h:1281
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:2664
Definition bslstl_vector.h:1025
void reserve(size_type newCapacity)
Definition bslstl_vector.h:3690
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:3760
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balcl_commandline.h:1364
bool operator==(const CommandLine_SchemaData &lhs, const CommandLine_SchemaData &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const CommandLine &rhs)
bool operator!=(const CommandLine_SchemaData &lhs, const CommandLine_SchemaData &rhs)
Definition balcl_commandline.h:1373
const char * d_name_p
Definition balcl_commandline.h:1377
OptionType::Enum d_type
Definition balcl_commandline.h:1376
Definition balcl_optioninfo.h:132
Definition balcl_optiontype.h:282
Enum
Definition balcl_optiontype.h:248
@ e_DOUBLE
Definition balcl_optiontype.h:255
@ e_CHAR_ARRAY
Definition balcl_optiontype.h:260
@ e_STRING
Definition balcl_optiontype.h:256
@ e_INT
Definition balcl_optiontype.h:253
@ e_INT64
Definition balcl_optiontype.h:254
@ e_CHAR
Definition balcl_optiontype.h:252
@ e_DATE_ARRAY
Definition balcl_optiontype.h:266
@ e_DATE
Definition balcl_optiontype.h:258
@ e_BOOL
Definition balcl_optiontype.h:251
@ e_INT64_ARRAY
Definition balcl_optiontype.h:262
@ e_INT_ARRAY
Definition balcl_optiontype.h:261
@ e_STRING_ARRAY
Definition balcl_optiontype.h:264
@ e_TIME
Definition balcl_optiontype.h:259
@ e_DATETIME
Definition balcl_optiontype.h:257
@ e_TIME_ARRAY
Definition balcl_optiontype.h:267
@ e_DATETIME_ARRAY
Definition balcl_optiontype.h:265
@ e_DOUBLE_ARRAY
Definition balcl_optiontype.h:263
Definition bdlb_printmethods.h:306
Definition bslma_usesbslmaallocator.h:343
long long Int64
Definition bsls_types.h:132